make the build script use 'include' statement instead of a hard-coded '.asm' file list
This commit is contained in:
130
build.ts
130
build.ts
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env -S deno run --allow-read --allow-run
|
||||
#!/usr/bin/env -S deno run --allow-read --allow-write --allow-run
|
||||
|
||||
import { TextLineStream } from "jsr:@std/streams@1.1.0";
|
||||
|
||||
@@ -9,25 +9,7 @@ import { TextLineStream } from "jsr:@std/streams@1.1.0";
|
||||
const instructionLength = 4; // in bytes
|
||||
const rawDataInstructionLengthPrefix = "U32";
|
||||
|
||||
const ppmToAsmScriptPath = './ppmToAsm.ts';
|
||||
|
||||
const asmFilePaths = [
|
||||
"src/consts/arch.asm",
|
||||
"src/consts/game.asm",
|
||||
"src/consts/keyboard.asm",
|
||||
"src/consts/map.asm",
|
||||
"src/consts/scene.asm",
|
||||
"src/consts/screen.asm",
|
||||
"src/consts/sprites.asm",
|
||||
|
||||
"src/init.asm",
|
||||
"src/main.asm",
|
||||
|
||||
"src/lib/game.asm",
|
||||
"src/lib/drawing.asm",
|
||||
"src/lib/sprite_rotation.asm",
|
||||
];
|
||||
const reservedSpacePath = "src/reserved_space.asm";
|
||||
const ppmToAsmScriptPath = "./ppmToAsm.ts";
|
||||
|
||||
const mapPath = "assets/map.ppm";
|
||||
const spritesPath = {
|
||||
@@ -117,7 +99,11 @@ class Minifier {
|
||||
}
|
||||
}
|
||||
|
||||
async function ppmToAsm(mode: "map" | "sprite", label: string, path: string): Promise<string> {
|
||||
async function ppmToAsm(
|
||||
mode: "map" | "sprite",
|
||||
label: string,
|
||||
path: string,
|
||||
): Promise<string> {
|
||||
const command = new Deno.Command(ppmToAsmScriptPath, {
|
||||
args: [
|
||||
instructionLength.toString(),
|
||||
@@ -140,62 +126,55 @@ async function ppmToAsm(mode: "map" | "sprite", label: string, path: string): Pr
|
||||
return decoder.decode(stdout);
|
||||
}
|
||||
|
||||
async function build(output: WritableStreamDefaultWriter<string>) {
|
||||
for (const path of asmFilePaths) {
|
||||
const file = await Deno.open(path);
|
||||
async function build(
|
||||
pwd: string,
|
||||
path: string,
|
||||
output: WritableStreamDefaultWriter<string>,
|
||||
) {
|
||||
const includeExpressionRegex = /^\s*include\s+([^\s;]+)/;
|
||||
|
||||
const file = await Deno.open(`${pwd}/${path}`);
|
||||
const readable = file.readable.pipeThrough(new TextDecoderStream())
|
||||
.pipeThrough(new TextLineStream());
|
||||
|
||||
await output.write(`
|
||||
;/*******************************
|
||||
;* ${path}
|
||||
;*******************************/
|
||||
`);
|
||||
|
||||
for await (const line of readable) {
|
||||
if (!line.startsWith("include ")) {
|
||||
const match = line.match(includeExpressionRegex);
|
||||
if (match === null) {
|
||||
await output.write(`${line}\n`);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const asmRawRepresentations = await Promise.all([
|
||||
ppmToAsm("map", "map", mapPath),
|
||||
...Object.entries(spritesPath).map(([label, path]) => ppmToAsm("sprite", label, path)),
|
||||
]);
|
||||
|
||||
await output.write(asmRawRepresentations.join("\n\n"));
|
||||
|
||||
await output.write(`
|
||||
;
|
||||
; RESERVED RAM SPACE
|
||||
;
|
||||
`);
|
||||
|
||||
await output.write(await Deno.readTextFile(reservedSpacePath));
|
||||
await output.close();
|
||||
await build(pwd, `${match[1]}.asm`, output);
|
||||
}
|
||||
}
|
||||
|
||||
function printUsage(into: (message: string) => void) {
|
||||
into(`Usage:
|
||||
\tbuild.ts [--minify]
|
||||
\t\tMerge the hardcoded files and output the result to stdout. The "--minify" option can be used to strip the result of all comments, leading/trailing double whitespaces, empty lines and use the more compact raw data representation.
|
||||
\tbuild.ts [options...] {file}
|
||||
\t\tRead the given file and recursively include other '.asm' files to produce a single output.
|
||||
\tbuild.ts --help
|
||||
\t\tPrint this message`);
|
||||
\t\tPrint this message
|
||||
|
||||
Options:
|
||||
\t--minify\tWhen used, the result will be stripped of all comments, leading/trailing double whitespaces, empty lines and use the more compact raw data representation.
|
||||
\t--ppm \tWhen used, the hardcoded ppm files will be translated to their matching Symfony assembly reprensentation into src/dist.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* SCRIPT
|
||||
*/
|
||||
|
||||
if (Deno.args.length > 1) {
|
||||
if (Deno.args.length < 1) {
|
||||
printUsage(console.error);
|
||||
Deno.exit(1);
|
||||
}
|
||||
|
||||
let minify = false;
|
||||
if (Deno.args.length === 1) {
|
||||
switch (Deno.args[0]) {
|
||||
let convertPPM = false;
|
||||
let path: string | undefined = undefined;
|
||||
|
||||
Deno.args.forEach((arg, index) => {
|
||||
switch (arg) {
|
||||
case "--help":
|
||||
printUsage(console.log);
|
||||
Deno.exit(0);
|
||||
@@ -203,11 +182,42 @@ if (Deno.args.length === 1) {
|
||||
case "--minify":
|
||||
minify = true;
|
||||
break;
|
||||
case "--ppm":
|
||||
convertPPM = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (index !== Deno.args.length - 1) {
|
||||
printUsage(console.error);
|
||||
Deno.exit(1);
|
||||
}
|
||||
path = arg;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (path === undefined) {
|
||||
printUsage(console.error);
|
||||
Deno.exit(1);
|
||||
}
|
||||
|
||||
if (convertPPM) {
|
||||
await Deno.mkdir(`${Deno.cwd()}/src/dist`, { recursive: true });
|
||||
const mapPromise = async () => {
|
||||
const assembly = await ppmToAsm("map", "map", mapPath);
|
||||
await Deno.writeTextFile(`${Deno.cwd()}/src/dist/map.asm`, assembly);
|
||||
};
|
||||
|
||||
const spritePromises = Object.entries(spritesPath).map(async ([label, path]) => {
|
||||
const assembly = await ppmToAsm("sprite", label, path);
|
||||
const filename = path.split("/").pop()?.split('.')[0];
|
||||
await Deno.writeTextFile(`${Deno.cwd()}/src/dist/${filename}.asm`, assembly);
|
||||
});
|
||||
|
||||
await Promise.all([
|
||||
mapPromise(),
|
||||
...spritePromises,
|
||||
]);
|
||||
}
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
@@ -217,9 +227,9 @@ const stdoutWritable = new WritableStream<string>({
|
||||
},
|
||||
});
|
||||
|
||||
if (minify) {
|
||||
const minifier = new Minifier(stdoutWritable);
|
||||
await build(minifier.stream.writable.getWriter());
|
||||
} else {
|
||||
await build(stdoutWritable.getWriter());
|
||||
}
|
||||
const writer = minify
|
||||
? (new Minifier(stdoutWritable)).stream.writable.getWriter()
|
||||
: stdoutWritable.getWriter();
|
||||
|
||||
await build(`${Deno.cwd()}/src`, path, writer);
|
||||
await writer.close();
|
||||
|
||||
@@ -43,7 +43,10 @@ Bundle all `.asm` and `.ppm` files and output the (optionaly minified) result.
|
||||
|
||||
Usage example:
|
||||
```sh
|
||||
./build.ts --minify > pacman.asm
|
||||
./build.ts --minify main.asm > pacman.asm
|
||||
|
||||
# To beforehand convert all ppm files
|
||||
./build.ts --ppm --minify main.asm > pacman.asm
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
include ../consts/offsets
|
||||
include ../consts/map
|
||||
include ../consts/screen
|
||||
include ../consts/scene
|
||||
include ../consts/sprites
|
||||
include sprite_rotation
|
||||
|
||||
; /* Draw the whole (fill the screen memory with the values of the sprites based on the map)
|
||||
; /* Draw the whole map (fill the screen memory with the values of the sprites based on the map)
|
||||
|
||||
; Inputs:
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
; /* Return the tile address from the given map coordinate
|
||||
|
||||
; Inputs:
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
include ../consts/offsets
|
||||
include ../consts/map
|
||||
include ../consts/sprites
|
||||
|
||||
; /* Return the sprite id and rotation for the given map coordinates
|
||||
|
||||
; Inputs:
|
||||
|
||||
21
src/main.asm
21
src/main.asm
@@ -1,4 +1,10 @@
|
||||
include consts/arch
|
||||
include consts/game
|
||||
include consts/keyboard
|
||||
include consts/map
|
||||
include consts/scene
|
||||
include consts/screen
|
||||
include consts/sprites
|
||||
|
||||
include init
|
||||
|
||||
@@ -347,4 +353,19 @@ game_loop:
|
||||
|
||||
jmp game_loop
|
||||
|
||||
include lib/game
|
||||
include lib/drawing
|
||||
include lib/sprite_rotation
|
||||
|
||||
include dist/empty
|
||||
include dist/placeholder
|
||||
include dist/wall_end
|
||||
include dist/wall_straight
|
||||
include dist/wall_corner
|
||||
include dist/robot
|
||||
include dist/ghost
|
||||
include dist/coin
|
||||
|
||||
include dist/map
|
||||
|
||||
include reserved_space
|
||||
|
||||
Reference in New Issue
Block a user