Compare commits
12
Commits
res-2
...
c88f67559d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c88f67559d | ||
|
|
2344a2e874 | ||
|
|
54ba73c177 | ||
|
|
d5e9dde21d | ||
|
|
02e1e4c6b3 | ||
|
|
d413170098 | ||
|
|
2c37af8dd0 | ||
|
|
f96e2420ef | ||
|
|
17c6b07367 | ||
|
|
f0656aca40 | ||
|
|
b0758c6976 | ||
|
|
3992863664 |
@@ -22,7 +22,9 @@ PPM 8bits channels | In-game `RRRGGGBB` value | Name
|
|||||||
`0x00_00_00` | `000_000_00` | Black
|
`0x00_00_00` | `000_000_00` | Black
|
||||||
`0x00_00_FF` | `000_000_11` | Blue
|
`0x00_00_FF` | `000_000_11` | Blue
|
||||||
`0x00_FF_00` | `000_111_00` | Green
|
`0x00_FF_00` | `000_111_00` | Green
|
||||||
`0x77_77_77` | `010_011_10` | Gray
|
`0x99_50_00` | `010_001_00` | Brown
|
||||||
|
`0x77_77_77` | `011_011_10` | Dark gray
|
||||||
|
`0xB3_B3_B3` | `100_100_10` | Light gray
|
||||||
`0xFF_00_00` | `111_000_00` | Red
|
`0xFF_00_00` | `111_000_00` | Red
|
||||||
`0xFF_00_FF` | `111_000_11` | Pink
|
`0xFF_00_FF` | `111_000_11` | Pink
|
||||||
`0xFF_80_00` | `111_100_00` | Orange
|
`0xFF_80_00` | `111_100_00` | Orange
|
||||||
|
|||||||
Binary file not shown.
@@ -1,74 +1,145 @@
|
|||||||
#!/usr/bin/env -S deno run --allow-read
|
#!/usr/bin/env -S deno run --allow-read
|
||||||
|
|
||||||
if (Deno.args.length !== 0) {
|
|
||||||
console.error(
|
|
||||||
"This script takes no argument (The source file list is hardcoded) and output the result on stdout.",
|
|
||||||
);
|
|
||||||
Deno.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
import { TextLineStream } from "jsr:@std/streams@1.1.0";
|
import { TextLineStream } from "jsr:@std/streams@1.1.0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CONFIG
|
||||||
|
*/
|
||||||
|
|
||||||
|
const instructionLength = 4; // in bytes
|
||||||
|
const rawDataInstructionLengthPrefix = "U32";
|
||||||
|
|
||||||
const asmFilePaths = [
|
const asmFilePaths = [
|
||||||
"src/consts/colors.asm",
|
"src/consts/arch.asm",
|
||||||
"src/consts/game.asm",
|
"src/consts/game.asm",
|
||||||
"src/consts/keyboard.asm",
|
"src/consts/keyboard.asm",
|
||||||
"src/consts/map.asm",
|
"src/consts/map.asm",
|
||||||
"src/consts/offsets.asm",
|
|
||||||
"src/consts/scene.asm",
|
"src/consts/scene.asm",
|
||||||
"src/consts/screen.asm",
|
"src/consts/screen.asm",
|
||||||
"src/consts/sprites.asm",
|
"src/consts/sprites.asm",
|
||||||
|
|
||||||
|
"src/init.asm",
|
||||||
"src/main.asm",
|
"src/main.asm",
|
||||||
|
|
||||||
"src/lib/game.asm",
|
"src/lib/game.asm",
|
||||||
"src/lib/drawing.asm",
|
"src/lib/drawing.asm",
|
||||||
"src/lib/sprite_rotation.asm",
|
|
||||||
];
|
];
|
||||||
|
const initialScreenPath = "assets/screen.ppm";
|
||||||
|
const reservedSpacePath = "src/reserved_space.asm";
|
||||||
|
|
||||||
const mapWidth = 15;
|
const mapMatchingValues = {
|
||||||
const spriteWidth = 5;
|
0x00_00_00: 0, // Empty
|
||||||
|
0xFF_00_00: 1, // Wall
|
||||||
const mapMatchingStrings = {
|
0xFF_FF_00: 2, // Coin
|
||||||
0x00_00_00: 'U8 0', // Empty
|
|
||||||
0xFF_00_00: 'U8 1', // Wall
|
|
||||||
0xFF_FF_00: 'U8 2', // Coin
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const spritesMatchingStrings = {
|
const spritesMatchingValues = {
|
||||||
0x00_00_00: 'U8 0b000_000_00',
|
0x00_00_00: 0, // 0b000_000_00
|
||||||
0x00_00_FF: 'U8 0b000_000_11',
|
0x00_00_FF: 3, // 0b000_000_11
|
||||||
0x00_FF_00: 'U8 0b000_111_00',
|
0x00_FF_00: 28, // 0b000_111_00
|
||||||
0x77_77_77: 'U8 0b010_011_10',
|
0x99_50_00: 68, // 0b010_001_00
|
||||||
0xFF_00_00: 'U8 0b111_000_00',
|
0x77_77_77: 110, // 0b011_011_10
|
||||||
0xFF_00_FF: 'U8 0b111_000_11',
|
0xB3_B3_B3: 146, // 0b100_100_10
|
||||||
0xFF_80_00: 'U8 0b111_100_00',
|
0xFF_00_00: 224, // 0b111_000_00
|
||||||
0xFF_FF_00: 'U8 0b111_110_00',
|
0xFF_00_FF: 227, // 0b111_000_11
|
||||||
0xFF_FF_FF: 'U8 0b111_111_11',
|
0xFF_80_00: 240, // 0b111_100_00
|
||||||
|
0xFF_FF_00: 248, // 0b111_110_00
|
||||||
|
0xFF_FF_FF: 255, // 0b111_111_11
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapPath = 'assets/map.ppm';
|
const mapPath = "assets/map.ppm";
|
||||||
const spritesPath = {
|
const spritesPath = {
|
||||||
'sprite_empty': 'assets/sprites/empty.ppm',
|
"sprite_empty": "assets/sprites/empty.ppm",
|
||||||
'sprite_unimplemented': 'assets/sprites/placeholder.ppm',
|
"sprite_unimplemented": "assets/sprites/placeholder.ppm",
|
||||||
'sprite_wall_end': 'assets/sprites/wall_end.ppm',
|
"sprite_wall_end": "assets/sprites/wall_end.ppm",
|
||||||
'sprite_wall_straight': 'assets/sprites/wall_straight.ppm',
|
"sprite_wall_straight": "assets/sprites/wall_straight.ppm",
|
||||||
'sprite_wall_corner': 'assets/sprites/wall_corner.ppm',
|
"sprite_wall_corner": "assets/sprites/wall_corner.ppm",
|
||||||
'sprite_robot': 'assets/sprites/robot.ppm',
|
"sprite_robot": "assets/sprites/robot.ppm",
|
||||||
'sprite_ghost': 'assets/sprites/ghost.ppm',
|
"sprite_ghost": "assets/sprites/ghost.ppm",
|
||||||
'sprite_coin': 'assets/sprites/coin.ppm',
|
"sprite_coin": "assets/sprites/coin.ppm",
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* START OF BUILD
|
* END OF CONFIG
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (const path of asmFilePaths) {
|
class Minifier {
|
||||||
|
private buffer = "";
|
||||||
|
private lines: Array<string> = [];
|
||||||
|
stream;
|
||||||
|
|
||||||
|
constructor(writableStream: WritableStream) {
|
||||||
|
this.stream = new TransformStream<string>({
|
||||||
|
transform: (chunk, controller) => {
|
||||||
|
this.buffer += chunk;
|
||||||
|
controller.enqueue(this.processChunk());
|
||||||
|
},
|
||||||
|
|
||||||
|
flush: (controller) => {
|
||||||
|
this.buffer += "\n";
|
||||||
|
controller.enqueue(this.processChunk());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this.stream.readable.pipeTo(writableStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private processChunk(): string {
|
||||||
|
const newLines = this.buffer.split("\n");
|
||||||
|
this.buffer = newLines.pop() as string; // keep the last (potentially incomplete) line
|
||||||
|
|
||||||
|
const removeComment = (line: string) => line.replace(/\s*;.*/, "");
|
||||||
|
const removeLeadingWhitespaces = (line: string) => line.replace(/^\s+/, "");
|
||||||
|
const removeTrailingWhitespaces = (line: string) =>
|
||||||
|
line.replace(/\s+$/, "");
|
||||||
|
const removeDoubleSpaces = (line: string) => line.replaceAll(/ +/g, " ");
|
||||||
|
const isNotEmpty = (line: string) => line.length !== 0;
|
||||||
|
|
||||||
|
const newLinesStripped = newLines
|
||||||
|
.map(removeComment)
|
||||||
|
.map(removeLeadingWhitespaces)
|
||||||
|
.map(removeTrailingWhitespaces)
|
||||||
|
.map(removeDoubleSpaces)
|
||||||
|
.filter(isNotEmpty);
|
||||||
|
|
||||||
|
this.lines.push(...newLinesStripped);
|
||||||
|
|
||||||
|
return this.processLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
private processLines() {
|
||||||
|
const processedLines: Array<string> = [];
|
||||||
|
while (this.lines.length >= instructionLength) {
|
||||||
|
const mergeableLines = this.lines.slice(0, instructionLength);
|
||||||
|
if (!mergeableLines.every((line) => line.startsWith("U8"))) {
|
||||||
|
processedLines.push(this.lines.shift() as string);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytesToMerge = mergeableLines.map((line) =>
|
||||||
|
parseInt((line.match(/U8\s(\d+)/) as RegExpMatchArray)[1])
|
||||||
|
);
|
||||||
|
let mergedBytes = 0;
|
||||||
|
for (let i = 0; i < bytesToMerge.length; i++) {
|
||||||
|
mergedBytes += bytesToMerge[i] << (instructionLength - 1 - i) * 8;
|
||||||
|
}
|
||||||
|
processedLines.push(
|
||||||
|
`${rawDataInstructionLengthPrefix} ${mergedBytes >>> 0}`,
|
||||||
|
);
|
||||||
|
this.lines.splice(0, instructionLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
return processedLines.length === 0 ? "" : `${processedLines.join("\n")}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function build(output: WritableStreamDefaultWriter<string>) {
|
||||||
|
for (const path of asmFilePaths) {
|
||||||
const file = await Deno.open(path);
|
const file = await Deno.open(path);
|
||||||
const readable = file.readable.pipeThrough(new TextDecoderStream())
|
const readable = file.readable.pipeThrough(new TextDecoderStream())
|
||||||
.pipeThrough(new TextLineStream());
|
.pipeThrough(new TextLineStream());
|
||||||
|
|
||||||
console.log(`
|
output.write(`
|
||||||
;/*******************************
|
;/*******************************
|
||||||
;* ${path}
|
;* ${path}
|
||||||
;*******************************/
|
;*******************************/
|
||||||
@@ -76,56 +147,88 @@ for (const path of asmFilePaths) {
|
|||||||
|
|
||||||
for await (const line of readable) {
|
for await (const line of readable) {
|
||||||
if (!line.startsWith("include ")) {
|
if (!line.startsWith("include ")) {
|
||||||
console.log(line);
|
output.write(`${line}\n`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
const asmRawRepresentations = [];
|
||||||
|
|
||||||
const asmRawRepresentations = [];
|
const mapBytes = await getDataFromPPM(mapPath);
|
||||||
|
asmRawRepresentations.push(
|
||||||
|
bytesToAsmConstU8("map", mapBytes, mapMatchingValues),
|
||||||
|
);
|
||||||
|
|
||||||
const mapBytes = await getDataFromPPM(mapPath);
|
for (const [label, path] of Object.entries(spritesPath)) {
|
||||||
asmRawRepresentations.push(byteToAsmRawData('map', mapBytes, mapMatchingStrings, mapWidth));
|
|
||||||
|
|
||||||
for (const [label, path] of Object.entries(spritesPath)) {
|
|
||||||
const bytes = await getDataFromPPM(path);
|
const bytes = await getDataFromPPM(path);
|
||||||
asmRawRepresentations.push(byteToAsmRawData(label, bytes, spritesMatchingStrings, spriteWidth));
|
asmRawRepresentations.push(
|
||||||
}
|
bytesToAsmConstU8(label, bytes, spritesMatchingValues),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
console.log(asmRawRepresentations.join("\n\n"));
|
output.write(asmRawRepresentations.join("\n\n"));
|
||||||
|
|
||||||
|
output.write(`
|
||||||
|
;
|
||||||
|
; RESERVED RAM SPACE
|
||||||
|
;
|
||||||
|
`);
|
||||||
|
|
||||||
|
const screenBytes = await getDataFromPPM(initialScreenPath);
|
||||||
|
output.write(bytesToAsmConstU8("screen", screenBytes, spritesMatchingValues));
|
||||||
|
|
||||||
|
output.write(await Deno.readTextFile(reservedSpacePath));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an ASM representation of the given data
|
* Return an ASM constant (U8) representation of the given data
|
||||||
|
*
|
||||||
|
* If needed, the representation will be padded to ensure the following code stays aligned on the instruction's length
|
||||||
*
|
*
|
||||||
* @param label The label to write before the first raw data
|
* @param label The label to write before the first raw data
|
||||||
* @param data An array of bytes to interprete as 24 bits values
|
* @param data An array of bytes to interprete as 24 bits values
|
||||||
* @param matchingStrings An associative array with a string representation for each possible 24 bit data value
|
* @param matchingValues An associative array with a string representation for each possible 24 bit data value
|
||||||
* @param lineLength Optional: Provide a way to wrap the result in multiple lines
|
|
||||||
*
|
*
|
||||||
* @returns The ASM representation of that raw data, pre- and post-fixed by the given label
|
* @returns The ASM representation of that raw data, pre- and post-fixed by the given label
|
||||||
*/
|
*/
|
||||||
function byteToAsmRawData(label: string, data: Uint8Array, matchingStrings: Record<number, string>, lineLength = 0): string {
|
function bytesToAsmConstU8(
|
||||||
lineLength ??= Infinity;
|
label: string,
|
||||||
|
data: Uint8Array,
|
||||||
const stringValues = [];
|
matchingValues: Record<number, number>,
|
||||||
for (let i = 0; i < data.length - 2; i += 3) {
|
): string {
|
||||||
const pixelValue = (data[i] << 16) + (data[i+1] << 8) + (data[i+2])
|
if (data.length % 3 !== 0) {
|
||||||
|
console.error(
|
||||||
stringValues.push(matchingStrings[pixelValue]);
|
"Length of data passed to bytesToAsmConstU8 are not a multiple of 3 (it needs to, as each resulting byte need a Red, a Green and a Blue value)",
|
||||||
|
);
|
||||||
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const lines = [];
|
const lines = [`${label}:`];
|
||||||
if (lineLength === 0) {
|
for (let i = 0; i < data.length; i += 3) {
|
||||||
lines.push(stringValues.join("\t"));
|
const pixelValue = (data[i] << 16) + (data[i + 1] << 8) + (data[i + 2]);
|
||||||
} else {
|
if (!Object.hasOwn(matchingValues, pixelValue)) {
|
||||||
for (let i = 0; i < stringValues.length; i += lineLength) {
|
console.error(
|
||||||
lines.push(stringValues.slice(i, i+lineLength).join("\t"));
|
`No matching value defined for "${
|
||||||
}
|
pixelValue.toString(2)
|
||||||
|
}" (which is ${label}'s ${i} pixel)`,
|
||||||
|
);
|
||||||
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${label}:
|
lines.push(`U8 ${matchingValues[pixelValue]}`);
|
||||||
${lines.join("\n")}
|
}
|
||||||
${label}_end:`
|
lines.push(`${label}_end:`);
|
||||||
|
|
||||||
|
const bytesNb = data.length / 3;
|
||||||
|
const unalignedBytesNb = bytesNb % instructionLength;
|
||||||
|
|
||||||
|
for (let i = 0; i < instructionLength - unalignedBytesNb; i++) {
|
||||||
|
lines.push(
|
||||||
|
`U8 0 ; padding to preserve ${8 * instructionLength} bits alignment`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,7 +268,7 @@ async function getDataFromPPM(path: string): Promise<Uint8Array> {
|
|||||||
let offset = 0;
|
let offset = 0;
|
||||||
|
|
||||||
// magic number
|
// magic number
|
||||||
while(!whitespaces.includes(content[offset])) {
|
while (!whitespaces.includes(content[offset])) {
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +276,7 @@ async function getDataFromPPM(path: string): Promise<Uint8Array> {
|
|||||||
|
|
||||||
// potential comment
|
// potential comment
|
||||||
if (content[offset] === hashtag) {
|
if (content[offset] === hashtag) {
|
||||||
while(!endOfComment.includes(content[offset])) {
|
while (!endOfComment.includes(content[offset])) {
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,21 +284,21 @@ async function getDataFromPPM(path: string): Promise<Uint8Array> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// image width
|
// image width
|
||||||
while(numbers.includes(content[offset])) {
|
while (numbers.includes(content[offset])) {
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset++; // whitespace
|
offset++; // whitespace
|
||||||
|
|
||||||
// image height
|
// image height
|
||||||
while(numbers.includes(content[offset])) {
|
while (numbers.includes(content[offset])) {
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset++; // whitespace
|
offset++; // whitespace
|
||||||
|
|
||||||
// maximum color value
|
// maximum color value
|
||||||
while(numbers.includes(content[offset])) {
|
while (numbers.includes(content[offset])) {
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,3 +306,51 @@ async function getDataFromPPM(path: string): Promise<Uint8Array> {
|
|||||||
|
|
||||||
return content.slice(offset, content.length);
|
return content.slice(offset, content.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 --help
|
||||||
|
\t\tPrint this message`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SCRIPT
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (Deno.args.length > 1) {
|
||||||
|
printUsage(console.error);
|
||||||
|
Deno.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let minify = false;
|
||||||
|
if (Deno.args.length === 1) {
|
||||||
|
switch (Deno.args[0]) {
|
||||||
|
case "--help":
|
||||||
|
printUsage(console.log);
|
||||||
|
Deno.exit(0);
|
||||||
|
break;
|
||||||
|
case "--minify":
|
||||||
|
minify = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printUsage(console.error);
|
||||||
|
Deno.exit(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
const stdoutWritable = new WritableStream<string>({
|
||||||
|
async write(chunk) {
|
||||||
|
await Deno.stdout.write(encoder.encode(chunk));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (minify) {
|
||||||
|
const minifier = new Minifier(stdoutWritable);
|
||||||
|
await build(minifier.stream.writable.getWriter());
|
||||||
|
} else {
|
||||||
|
await build(stdoutWritable.getWriter());
|
||||||
|
}
|
||||||
@@ -9,7 +9,19 @@ It thus should be able to run on the architecture and ISA the players have built
|
|||||||
The `main` branch contains a minimal implementation of the game.
|
The `main` branch contains a minimal implementation of the game.
|
||||||
|
|
||||||
The following branches contains variations, allowing comparisons of performances, visuals, gameplay, ...
|
The following branches contains variations, allowing comparisons of performances, visuals, gameplay, ...
|
||||||
- `res-2`: 256x192 screen resolution, 17x17 tile
|
- `res-0-prerendered`:
|
||||||
|
- `80x60` screen resolution
|
||||||
|
- `5x5` tile resolution
|
||||||
|
- initial screen prerendered
|
||||||
|
- no sprite rotation
|
||||||
|
- `res-2`:
|
||||||
|
- `256x192` screen resolution
|
||||||
|
- `17x17` tile resolution
|
||||||
|
- `res-2-prerendered`:
|
||||||
|
- `256x192` screen resolution
|
||||||
|
- `17x17` tile resolution
|
||||||
|
- initial screen prerendered
|
||||||
|
- no sprite rotation
|
||||||
|
|
||||||
## Build script
|
## Build script
|
||||||
|
|
||||||
@@ -19,7 +31,7 @@ It also convert the PPM assets (map and sprites) into ASM raw values representat
|
|||||||
|
|
||||||
Usage example:
|
Usage example:
|
||||||
```sh
|
```sh
|
||||||
./build.ts > /path/to/the/game/schematics/architecture/Symfony/sandbox/main.asm
|
./build.ts --minify > /path/to/the/game/schematics/architecture/Symfony/sandbox/main.asm
|
||||||
```
|
```
|
||||||
|
|
||||||
The script is build over Deno's API, so you'll need to have a `deno` binary in your PATH to use it that way.
|
The script is build over Deno's API, so you'll need to have a `deno` binary in your PATH to use it that way.
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
pub const arch.instruction_size = 4
|
||||||
|
pub const arch.instruction_increment_shift = 2
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
pub const colors.black = 0b000_000_00
|
|
||||||
pub const colors.blue = 0b000_000_11
|
|
||||||
pub const colors.green = 0b000_111_00
|
|
||||||
pub const colors.gray = 0b010_011_10
|
|
||||||
pub const colors.red = 0b111_000_00
|
|
||||||
pub const colors.pink = 0b111_000_11
|
|
||||||
pub const colors.orange = 0b111_100_00
|
|
||||||
pub const colors.yellow = 0b111_110_00
|
|
||||||
pub const colors.white = 0b111_111_11
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
;const free_ram_start = 8000
|
|
||||||
|
|
||||||
pub const offsets.screen = 8000 ; screen size: 80x60 = 4800
|
|
||||||
|
|
||||||
pub const offsets.tick_duration_high = 12800
|
|
||||||
pub const offsets.tick_duration_low = 12804
|
|
||||||
pub const offsets.next_tick_high = 12808
|
|
||||||
pub const offsets.next_tick_low = 128012
|
|
||||||
|
|
||||||
|
|
||||||
; State:
|
|
||||||
; U8 x coord
|
|
||||||
; U8 y coord
|
|
||||||
; U8 direction
|
|
||||||
pub const offsets.state_robot = 12816
|
|
||||||
pub const offsets.state_ghost = 12819
|
|
||||||
+4
-12
@@ -2,17 +2,9 @@ pub const sprites.width = 5
|
|||||||
pub const sprites.height = 5 ; unused as sprite are all square
|
pub const sprites.height = 5 ; unused as sprite are all square
|
||||||
pub const sprites.size = 25 ; height x width
|
pub const sprites.size = 25 ; height x width
|
||||||
|
|
||||||
pub const sprites.rotation_0 = 0
|
|
||||||
pub const sprites.rotation_90 = 1
|
|
||||||
pub const sprites.rotation_180 = 2
|
|
||||||
pub const sprites.rotation_270 = 3
|
|
||||||
|
|
||||||
pub const sprites.empty = 0
|
pub const sprites.empty = 0
|
||||||
pub const sprites.unimplemented = 1
|
pub const sprites.unimplemented = 1
|
||||||
pub const sprites.wall_end = 2
|
pub const sprites.robot = 2
|
||||||
pub const sprites.wall_straight = 3
|
pub const sprites.ghost = 3
|
||||||
pub const sprites.wall_corner = 4
|
pub const sprites.coin = 4
|
||||||
pub const sprites.robot = 5
|
pub const sprites.max = 4 ; for lookup table
|
||||||
pub const sprites.ghost = 6
|
|
||||||
pub const sprites.coin = 7
|
|
||||||
pub const sprites.max = 7 ; for lookup table
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
;
|
||||||
|
; Jump table initialisation
|
||||||
|
;
|
||||||
|
; r1: sprite id
|
||||||
|
; r2: pointer address
|
||||||
|
; r3: pointer value
|
||||||
|
|
||||||
|
; sprite_empty
|
||||||
|
add r1, zr, sprites.empty
|
||||||
|
lsl r2, r1, arch.instruction_increment_shift
|
||||||
|
add r2, r2, ptr.textures_addresses
|
||||||
|
add r3, zr, sprite_empty
|
||||||
|
store_32 [r2], r3
|
||||||
|
; sprite_unimplemented
|
||||||
|
add r1, zr, sprites.unimplemented
|
||||||
|
lsl r2, r1, arch.instruction_increment_shift
|
||||||
|
add r2, r2, ptr.textures_addresses
|
||||||
|
add r3, zr, sprite_unimplemented
|
||||||
|
store_32 [r2], r3
|
||||||
|
; sprite_robot
|
||||||
|
add r1, zr, sprites.robot
|
||||||
|
lsl r2, r1, arch.instruction_increment_shift
|
||||||
|
add r2, r2, ptr.textures_addresses
|
||||||
|
add r3, zr, sprite_robot
|
||||||
|
store_32 [r2], r3
|
||||||
|
; sprite_ghost
|
||||||
|
add r1, zr, sprites.ghost
|
||||||
|
lsl r2, r1, arch.instruction_increment_shift
|
||||||
|
add r2, r2, ptr.textures_addresses
|
||||||
|
add r3, zr, sprite_ghost
|
||||||
|
store_32 [r2], r3
|
||||||
|
; sprite_coin
|
||||||
|
add r1, zr, sprites.coin
|
||||||
|
lsl r2, r1, arch.instruction_increment_shift
|
||||||
|
add r2, r2, ptr.textures_addresses
|
||||||
|
add r3, zr, sprite_coin
|
||||||
|
store_32 [r2], r3
|
||||||
|
|
||||||
|
;
|
||||||
|
; Screen initialization
|
||||||
|
;
|
||||||
|
|
||||||
|
; r1 = screen parameter value
|
||||||
|
mov r1, screen.mode_index
|
||||||
|
screen r1, screen.mode_value
|
||||||
|
|
||||||
|
mov r1, screen.offset_index
|
||||||
|
add r2, zr, screen
|
||||||
|
screen r1, r2
|
||||||
|
|
||||||
|
mov r1, screen.resolution_index
|
||||||
|
screen r1, screen.resolution_value
|
||||||
+27
-149
@@ -5,53 +5,6 @@ include ../consts/scene
|
|||||||
include ../consts/sprites
|
include ../consts/sprites
|
||||||
include sprite_rotation
|
include sprite_rotation
|
||||||
|
|
||||||
; /* Draw the whole (fill the screen memory with the values of the sprites based on the map)
|
|
||||||
|
|
||||||
; Inputs:
|
|
||||||
|
|
||||||
; Outputs:
|
|
||||||
|
|
||||||
; Locals:
|
|
||||||
; r1: x map coord
|
|
||||||
; r2: y map coord
|
|
||||||
; r3: sprite rotation
|
|
||||||
; r4: sprite id
|
|
||||||
; r12: rotation (returned by `sprite and rotation`)
|
|
||||||
; r13: sprite (returned by `get_sprite_id_and_rotation`)
|
|
||||||
; */
|
|
||||||
pub drawing.draw_whole_map:
|
|
||||||
push r1
|
|
||||||
push r2
|
|
||||||
push r3
|
|
||||||
push r4
|
|
||||||
push r12
|
|
||||||
push r13
|
|
||||||
|
|
||||||
mov r1, 0
|
|
||||||
mov r2, 0
|
|
||||||
|
|
||||||
draw_whole_map_loop:
|
|
||||||
call sprite_rotation.get_sprite_id_and_rotation
|
|
||||||
mov r3, r12
|
|
||||||
mov r4, r13
|
|
||||||
call drawing.draw_sprite_at_map_coord
|
|
||||||
add r1, r1, 1
|
|
||||||
cmp r1, map.width
|
|
||||||
jne draw_whole_map_loop
|
|
||||||
mov r1, 0
|
|
||||||
add r2, r2, 1
|
|
||||||
cmp r2, map.height
|
|
||||||
jne draw_whole_map_loop
|
|
||||||
|
|
||||||
pop r13
|
|
||||||
pop r12
|
|
||||||
pop r4
|
|
||||||
pop r3
|
|
||||||
pop r2
|
|
||||||
pop r1
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
; /* Return the top-left pixel address of the tile at the given map coordinates
|
; /* Return the top-left pixel address of the tile at the given map coordinates
|
||||||
|
|
||||||
; Inputs:
|
; Inputs:
|
||||||
@@ -77,7 +30,7 @@ get_tile_address:
|
|||||||
cmp r3, sprites.height
|
cmp r3, sprites.height
|
||||||
jne get_tile_address_offset_per_row_loop
|
jne get_tile_address_offset_per_row_loop
|
||||||
|
|
||||||
mov r13, offsets.screen
|
add r13, zr, screen
|
||||||
|
|
||||||
mov r3, 0
|
mov r3, 0
|
||||||
get_tile_address_margin_top_loop:
|
get_tile_address_margin_top_loop:
|
||||||
@@ -120,48 +73,21 @@ get_tile_address:
|
|||||||
; r13: address
|
; r13: address
|
||||||
|
|
||||||
; Locals:
|
; Locals:
|
||||||
; r2: jump address
|
; r2: pointer address
|
||||||
; */
|
; */
|
||||||
get_sprite_address:
|
get_sprite_address:
|
||||||
push r1
|
push r1
|
||||||
push r2
|
push r2
|
||||||
|
|
||||||
cmp r1, sprites.max
|
cmp r1, sprites.max
|
||||||
jbe get_sprite_address_jmp_table_init
|
jbe get_sprite_address_ptr
|
||||||
mov r1, sprites.unimplemented
|
mov r1, sprites.unimplemented
|
||||||
|
|
||||||
get_sprite_address_jmp_table_init:
|
get_sprite_address_ptr:
|
||||||
lsl r2, r1, 3 ; 2*instruction_size = *8 = <<3
|
lsl r2, r1, arch.instruction_increment_shift
|
||||||
add r2, r2, get_sprite_address_jmp_table_start
|
add r2, r2, ptr.textures_addresses
|
||||||
jmp r2
|
load_32 r13, [r2]
|
||||||
|
|
||||||
get_sprite_address_jmp_table_start:
|
|
||||||
; sprite_empty
|
|
||||||
add r13, zr, sprite_empty
|
|
||||||
jmp get_sprite_address_return
|
|
||||||
; sprite_unimplemented:
|
|
||||||
add r13, zr, sprite_unimplemented
|
|
||||||
jmp get_sprite_address_return
|
|
||||||
; sprite_wall_end
|
|
||||||
add r13, zr, sprite_wall_end
|
|
||||||
jmp get_sprite_address_return
|
|
||||||
; sprite_wall_straight
|
|
||||||
add r13, zr, sprite_wall_straight
|
|
||||||
jmp get_sprite_address_return
|
|
||||||
; sprite_wall_corner
|
|
||||||
add r13, zr, sprite_wall_corner
|
|
||||||
jmp get_sprite_address_return
|
|
||||||
; sprite_robot
|
|
||||||
add r13, zr, sprite_robot
|
|
||||||
jmp get_sprite_address_return
|
|
||||||
; sprite_ghost
|
|
||||||
add r13, zr, sprite_ghost
|
|
||||||
jmp get_sprite_address_return
|
|
||||||
; sprite_coin:
|
|
||||||
add r13, zr, sprite_coin
|
|
||||||
;jmp get_sprite_address_return
|
|
||||||
|
|
||||||
get_sprite_address_return:
|
|
||||||
pop r2
|
pop r2
|
||||||
pop r1
|
pop r1
|
||||||
ret
|
ret
|
||||||
@@ -171,8 +97,7 @@ get_sprite_address:
|
|||||||
; Inputs:
|
; Inputs:
|
||||||
; r1: map x coord
|
; r1: map x coord
|
||||||
; r2: map y coord
|
; r2: map y coord
|
||||||
; r3: sprite rotation
|
; r3: sprite id
|
||||||
; r4: sprite id
|
|
||||||
|
|
||||||
; Outputs:
|
; Outputs:
|
||||||
|
|
||||||
@@ -185,22 +110,20 @@ pub drawing.draw_sprite_at_map_coord:
|
|||||||
push r1
|
push r1
|
||||||
push r2
|
push r2
|
||||||
push r3
|
push r3
|
||||||
push r4
|
|
||||||
push r13
|
push r13
|
||||||
|
|
||||||
call get_tile_address
|
call get_tile_address
|
||||||
mov r1, r13
|
push r13
|
||||||
push r1
|
|
||||||
|
|
||||||
mov r1, r4
|
mov r1, r3
|
||||||
call get_sprite_address
|
call get_sprite_address
|
||||||
mov r2, r13
|
|
||||||
pop r1
|
|
||||||
|
|
||||||
|
mov r2, r13
|
||||||
|
pop r13
|
||||||
|
mov r1, r13
|
||||||
call draw_sprite
|
call draw_sprite
|
||||||
|
|
||||||
pop r13
|
pop r13
|
||||||
pop r4
|
|
||||||
pop r3
|
pop r3
|
||||||
pop r2
|
pop r2
|
||||||
pop r1
|
pop r1
|
||||||
@@ -211,18 +134,15 @@ pub drawing.draw_sprite_at_map_coord:
|
|||||||
; Inputs:
|
; Inputs:
|
||||||
; r1: screen address
|
; r1: screen address
|
||||||
; r2: sprite address
|
; r2: sprite address
|
||||||
; r3: rotation
|
|
||||||
|
|
||||||
; Outputs:
|
; Outputs:
|
||||||
|
|
||||||
; Locals:
|
; Locals:
|
||||||
; r1: current screen pixel address
|
; r1: current screen pixel address
|
||||||
; r4: x
|
; r2: current sprite pixel address
|
||||||
; r5: y
|
; r3: x
|
||||||
; r6: current sprite pixel address
|
; r4: color
|
||||||
; r7: color
|
; r5: sprite last pixel address + 1
|
||||||
; r8: x increment
|
|
||||||
; r9: y increment
|
|
||||||
; */
|
; */
|
||||||
draw_sprite:
|
draw_sprite:
|
||||||
push r1
|
push r1
|
||||||
@@ -230,67 +150,25 @@ draw_sprite:
|
|||||||
push r3
|
push r3
|
||||||
push r4
|
push r4
|
||||||
push r5
|
push r5
|
||||||
push r6
|
|
||||||
push r7
|
|
||||||
push r8
|
|
||||||
push r9
|
|
||||||
|
|
||||||
mov r6, r2
|
add r5, r2, sprites.size
|
||||||
|
|
||||||
; rotation
|
mov r3, 0
|
||||||
draw_sprite_cmp_rotation_0:
|
|
||||||
cmp r3, sprites.rotation_0
|
|
||||||
jne draw_sprite_cmp_rotation_90
|
|
||||||
mov r8, 1
|
|
||||||
mov r9, 0
|
|
||||||
jmp draw_sprite_loop_init
|
|
||||||
draw_sprite_cmp_rotation_90:
|
|
||||||
cmp r3, sprites.rotation_90
|
|
||||||
jne draw_sprite_cmp_rotation_180
|
|
||||||
add r6, r6, sprites.size
|
|
||||||
sub r6, r6, sprites.width
|
|
||||||
sub r8, zr, sprites.width
|
|
||||||
mov r9, sprites.size
|
|
||||||
add r9, r9, 1
|
|
||||||
jmp draw_sprite_loop_init
|
|
||||||
draw_sprite_cmp_rotation_180:
|
|
||||||
cmp r3, sprites.rotation_180
|
|
||||||
jne draw_sprite_cmp_rotation_270
|
|
||||||
add r6, r6, sprites.size
|
|
||||||
sub r6, r6, 1
|
|
||||||
sub r8, zr, 1
|
|
||||||
mov r9, 0
|
|
||||||
jmp draw_sprite_loop_init
|
|
||||||
draw_sprite_cmp_rotation_270:
|
|
||||||
add r6, r6, sprites.width
|
|
||||||
sub r6, r6, 1
|
|
||||||
mov r8, sprites.width
|
|
||||||
sub r9, zr, sprites.size
|
|
||||||
sub r9, r9, 1
|
|
||||||
|
|
||||||
draw_sprite_loop_init:
|
|
||||||
mov r4, 0
|
|
||||||
mov r5, 0
|
|
||||||
draw_sprite_loop:
|
draw_sprite_loop:
|
||||||
load_8 r7, [r6]
|
load_8 r4, [r2]
|
||||||
store_8 [r1], r7
|
store_8 [r1], r4
|
||||||
add r4, r4, 1
|
|
||||||
add r1, r1, 1
|
add r1, r1, 1
|
||||||
add r6, r6, r8
|
add r2, r2, 1
|
||||||
cmp r4, sprites.width
|
add r3, r3, 1
|
||||||
|
cmp r3, sprites.width
|
||||||
jne draw_sprite_loop
|
jne draw_sprite_loop
|
||||||
mov r4, 0
|
mov r3, 0
|
||||||
add r6, r6, r9
|
|
||||||
add r1, r1, screen.width
|
add r1, r1, screen.width
|
||||||
sub r1, r1, sprites.width
|
sub r1, r1, sprites.width
|
||||||
add r5, r5, 1
|
cmp r5, r2
|
||||||
cmp r5, sprites.width
|
|
||||||
jne draw_sprite_loop
|
jne draw_sprite_loop
|
||||||
|
|
||||||
pop r9
|
|
||||||
pop r8
|
|
||||||
pop r7
|
|
||||||
pop r6
|
|
||||||
pop r5
|
pop r5
|
||||||
pop r4
|
pop r4
|
||||||
pop r3
|
pop r3
|
||||||
|
|||||||
@@ -1,171 +0,0 @@
|
|||||||
include ../consts/offsets
|
|
||||||
include ../consts/map
|
|
||||||
include ../consts/sprites
|
|
||||||
|
|
||||||
; /* Return the sprite id and rotation for the given map coordinates
|
|
||||||
|
|
||||||
; Inputs:
|
|
||||||
; r1: x map coord
|
|
||||||
; r2: y map coord
|
|
||||||
|
|
||||||
; Outputs:
|
|
||||||
; r12: sprite rotation
|
|
||||||
; r13: sprite id
|
|
||||||
|
|
||||||
; Locals:
|
|
||||||
; r3: tile id
|
|
||||||
; r4: map offset
|
|
||||||
; r5: counter
|
|
||||||
; r6: left tile id
|
|
||||||
; r7: up tile id
|
|
||||||
; r8: right tile id
|
|
||||||
; r9: down tile id
|
|
||||||
; */
|
|
||||||
pub sprite_rotation.get_sprite_id_and_rotation:
|
|
||||||
push r1
|
|
||||||
push r2
|
|
||||||
push r3
|
|
||||||
push r4
|
|
||||||
push r5
|
|
||||||
push r6
|
|
||||||
push r7
|
|
||||||
push r8
|
|
||||||
push r9
|
|
||||||
|
|
||||||
add r4, r1, map
|
|
||||||
mov r5, 0
|
|
||||||
get_sprite_id_and_rotation_map_row_loop:
|
|
||||||
cmp r5, r2
|
|
||||||
je get_sprite_id_and_rotation_map_row_loop_end
|
|
||||||
add r4, r4, map.width
|
|
||||||
add r5, r5, 1
|
|
||||||
jmp get_sprite_id_and_rotation_map_row_loop
|
|
||||||
get_sprite_id_and_rotation_map_row_loop_end:
|
|
||||||
|
|
||||||
mov r12, sprites.rotation_0 ; default rotation
|
|
||||||
|
|
||||||
load_8 r3, [r4]
|
|
||||||
lsl r3, r3, 3 ; 2*instruction_size = *8 = <<3
|
|
||||||
add r3, r3, get_sprite_id_and_rotation_jump_table
|
|
||||||
jmp r3
|
|
||||||
|
|
||||||
get_sprite_id_and_rotation_jump_table:
|
|
||||||
; tile_empty
|
|
||||||
mov r13, sprites.empty
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
; tiles_wall
|
|
||||||
jmp get_sprite_id_and_rotation_wall
|
|
||||||
nop
|
|
||||||
; tile_coin
|
|
||||||
mov r13, sprites.coin
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
|
|
||||||
get_sprite_id_and_rotation_wall:
|
|
||||||
mov r6, 0
|
|
||||||
mov r7, 0
|
|
||||||
mov r8, 0
|
|
||||||
mov r9, 0
|
|
||||||
|
|
||||||
get_sprite_id_and_rotation_cmp_left:
|
|
||||||
cmp r1, 0
|
|
||||||
je get_sprite_id_and_rotation_cmp_up
|
|
||||||
sub r4, r4, 1
|
|
||||||
load_8 r6, [r4]
|
|
||||||
add r4, r4, 1
|
|
||||||
get_sprite_id_and_rotation_cmp_up:
|
|
||||||
cmp r2, 0
|
|
||||||
je get_sprite_id_and_rotation_cmp_right
|
|
||||||
sub r4, r4, map.width
|
|
||||||
load_8 r7, [r4]
|
|
||||||
add r4, r4, map.width
|
|
||||||
get_sprite_id_and_rotation_cmp_right:
|
|
||||||
cmp r1, map.max_x
|
|
||||||
je get_sprite_id_and_rotation_cmp_down
|
|
||||||
add r4, r4, 1
|
|
||||||
load_8 r8, [r4]
|
|
||||||
sub r4, r4, 1
|
|
||||||
get_sprite_id_and_rotation_cmp_down:
|
|
||||||
cmp r2, map.max_y
|
|
||||||
je get_sprite_id_and_rotation_check_connections
|
|
||||||
add r4, r4, map.width
|
|
||||||
load_8 r9, [r4]
|
|
||||||
sub r4, r4, map.width
|
|
||||||
|
|
||||||
get_sprite_id_and_rotation_check_connections:
|
|
||||||
get_sprite_id_and_rotation_straight_0:
|
|
||||||
cmp r7, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_straight_90
|
|
||||||
cmp r9, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_straight_90
|
|
||||||
mov r12, sprites.rotation_0
|
|
||||||
mov r13, sprites.wall_straight
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
get_sprite_id_and_rotation_straight_90:
|
|
||||||
cmp r6, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_corner_0
|
|
||||||
cmp r8, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_corner_0
|
|
||||||
mov r12, sprites.rotation_90
|
|
||||||
mov r13, sprites.wall_straight
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
|
|
||||||
get_sprite_id_and_rotation_corner_0:
|
|
||||||
cmp r6, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_corner_180
|
|
||||||
cmp r9, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_corner_90
|
|
||||||
mov r12,sprites.rotation_0
|
|
||||||
mov r13, sprites.wall_corner
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
get_sprite_id_and_rotation_corner_90:
|
|
||||||
cmp r7, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_end_90
|
|
||||||
mov r12,sprites.rotation_90
|
|
||||||
mov r13, sprites.wall_corner
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
get_sprite_id_and_rotation_corner_180:
|
|
||||||
cmp r8, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_end_0
|
|
||||||
cmp r7, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_corner_270
|
|
||||||
mov r12,sprites.rotation_180
|
|
||||||
mov r13, sprites.wall_corner
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
get_sprite_id_and_rotation_corner_270:
|
|
||||||
cmp r9, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_end_270
|
|
||||||
mov r12,sprites.rotation_270
|
|
||||||
mov r13, sprites.wall_corner
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
|
|
||||||
get_sprite_id_and_rotation_end_0:
|
|
||||||
cmp r9, map.tiles.wall
|
|
||||||
jne get_sprite_id_and_rotation_end_180
|
|
||||||
mov r12,sprites.rotation_0
|
|
||||||
mov r13, sprites.wall_end
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
get_sprite_id_and_rotation_end_90:
|
|
||||||
mov r12,sprites.rotation_90
|
|
||||||
mov r13, sprites.wall_end
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
get_sprite_id_and_rotation_end_180:
|
|
||||||
mov r12,sprites.rotation_180
|
|
||||||
mov r13, sprites.wall_end
|
|
||||||
jmp get_sprite_id_and_rotation_return
|
|
||||||
get_sprite_id_and_rotation_end_270:
|
|
||||||
mov r12,sprites.rotation_270
|
|
||||||
mov r13, sprites.wall_end
|
|
||||||
;jmp get_sprite_id_and_rotation_return
|
|
||||||
|
|
||||||
get_sprite_id_and_rotation_return:
|
|
||||||
pop r9
|
|
||||||
pop r8
|
|
||||||
pop r7
|
|
||||||
pop r6
|
|
||||||
pop r5
|
|
||||||
pop r4
|
|
||||||
pop r3
|
|
||||||
pop r2
|
|
||||||
pop r1
|
|
||||||
|
|
||||||
ret
|
|
||||||
+31
-63
@@ -1,20 +1,6 @@
|
|||||||
include consts/screen
|
include consts/screen
|
||||||
|
|
||||||
;
|
include init
|
||||||
; Screen initialization
|
|
||||||
;
|
|
||||||
|
|
||||||
; r1 = screen parameter value
|
|
||||||
mov r1, screen.mode_index
|
|
||||||
screen r1, screen.mode_value
|
|
||||||
|
|
||||||
mov r1, screen.offset_index
|
|
||||||
screen r1, offsets.screen
|
|
||||||
|
|
||||||
mov r1, screen.resolution_index
|
|
||||||
screen r1, screen.resolution_value
|
|
||||||
|
|
||||||
call drawing.draw_whole_map
|
|
||||||
|
|
||||||
;
|
;
|
||||||
; State initialization
|
; State initialization
|
||||||
@@ -27,15 +13,14 @@ const robot_initial_direction = game.direction_down
|
|||||||
mov r1, robot_initial_x
|
mov r1, robot_initial_x
|
||||||
mov r2, robot_initial_y
|
mov r2, robot_initial_y
|
||||||
mov r5, robot_initial_direction
|
mov r5, robot_initial_direction
|
||||||
mov r6, offsets.state_robot
|
add r6, zr, ptr.state_robot
|
||||||
store_8 [r6], r1
|
store_8 [r6], r1
|
||||||
add r6, r6, 1
|
add r6, r6, 1
|
||||||
store_8 [r6], r2
|
store_8 [r6], r2
|
||||||
add r6, r6, 1
|
add r6, r6, 1
|
||||||
store_8 [r6], r5
|
store_8 [r6], r5
|
||||||
|
|
||||||
mov r3, sprites.rotation_0
|
mov r3, sprites.robot
|
||||||
mov r4, sprites.robot
|
|
||||||
call drawing.draw_sprite_at_map_coord
|
call drawing.draw_sprite_at_map_coord
|
||||||
|
|
||||||
; Ghost
|
; Ghost
|
||||||
@@ -46,31 +31,23 @@ const ghost_initial_direction = game.direction_down
|
|||||||
mov r1, ghost_initial_x
|
mov r1, ghost_initial_x
|
||||||
mov r2, ghost_initial_y
|
mov r2, ghost_initial_y
|
||||||
mov r5, ghost_initial_direction
|
mov r5, ghost_initial_direction
|
||||||
mov r6, offsets.state_ghost
|
add r6, zr, ptr.state_ghost
|
||||||
store_8 [r6], r1
|
store_8 [r6], r1
|
||||||
add r6, r6, 1
|
add r6, r6, 1
|
||||||
store_8 [r6], r2
|
store_8 [r6], r2
|
||||||
add r6, r6, 1
|
add r6, r6, 1
|
||||||
store_8 [r6], r5
|
store_8 [r6], r5
|
||||||
|
|
||||||
mov r3, sprites.rotation_0
|
mov r3, sprites.ghost
|
||||||
mov r4, sprites.ghost
|
|
||||||
call drawing.draw_sprite_at_map_coord
|
call drawing.draw_sprite_at_map_coord
|
||||||
|
|
||||||
;
|
;
|
||||||
; Time initialization
|
; Time initialization
|
||||||
;
|
;
|
||||||
mov r2, game.tick_duration_1
|
add r1, zr, ptr.tick_duration_low
|
||||||
movt r2, r2
|
load_32 r2, [r1]
|
||||||
movb r2, game.tick_duration_0
|
add r1, zr, ptr.tick_duration_high
|
||||||
mov r1, offsets.tick_duration_low
|
load_32 r3, [r1]
|
||||||
store_32 [r1], r2
|
|
||||||
|
|
||||||
mov r3, game.tick_duration_3
|
|
||||||
movt r3, r3
|
|
||||||
movb r3, game.tick_duration_2
|
|
||||||
mov r1, offsets.tick_duration_high
|
|
||||||
store_32 [r1], r3
|
|
||||||
|
|
||||||
time_0 r4
|
time_0 r4
|
||||||
time_1 r5
|
time_1 r5
|
||||||
@@ -81,9 +58,9 @@ jae init_store_next_tick
|
|||||||
add r5, r5, 1 ; overflow
|
add r5, r5, 1 ; overflow
|
||||||
|
|
||||||
init_store_next_tick:
|
init_store_next_tick:
|
||||||
mov r1, offsets.next_tick_low
|
add r1, zr, ptr.next_tick_low
|
||||||
store_32 [r1], r4
|
store_32 [r1], r4
|
||||||
mov r1, offsets.next_tick_high
|
add r1, zr, ptr.next_tick_high
|
||||||
store_32 [r1], r5
|
store_32 [r1], r5
|
||||||
|
|
||||||
game_loop:
|
game_loop:
|
||||||
@@ -125,7 +102,7 @@ game_loop:
|
|||||||
; jmp game_loop_event_handling_end
|
; jmp game_loop_event_handling_end
|
||||||
|
|
||||||
game_loop_event_handling_store_direction:
|
game_loop_event_handling_store_direction:
|
||||||
add r2, zr, offsets.state_robot
|
add r2, zr, ptr.state_robot
|
||||||
add r2, r2, 2
|
add r2, r2, 2
|
||||||
store_8 [r2], r1
|
store_8 [r2], r1
|
||||||
|
|
||||||
@@ -143,9 +120,9 @@ game_loop:
|
|||||||
time_0 r2
|
time_0 r2
|
||||||
time_1 r3
|
time_1 r3
|
||||||
|
|
||||||
mov r1, offsets.next_tick_low
|
add r1, zr, ptr.next_tick_low
|
||||||
load_32 r4, [r1]
|
load_32 r4, [r1]
|
||||||
mov r1, offsets.next_tick_high
|
add r1, zr, ptr.next_tick_high
|
||||||
load_32 r5, [r1]
|
load_32 r5, [r1]
|
||||||
|
|
||||||
cmp r3, r5
|
cmp r3, r5
|
||||||
@@ -155,9 +132,9 @@ game_loop:
|
|||||||
jb game_loop
|
jb game_loop
|
||||||
|
|
||||||
update_next_tick:
|
update_next_tick:
|
||||||
mov r1, offsets.tick_duration_low
|
add r1, zr, ptr.tick_duration_low
|
||||||
load_32 r2, [r1]
|
load_32 r2, [r1]
|
||||||
mov r1, offsets.tick_duration_high
|
add r1, zr, ptr.tick_duration_high
|
||||||
load_32 r3, [r1]
|
load_32 r3, [r1]
|
||||||
add r4, r4, r2
|
add r4, r4, r2
|
||||||
add r5, r5, r3
|
add r5, r5, r3
|
||||||
@@ -166,9 +143,9 @@ game_loop:
|
|||||||
add r5, r5, 1
|
add r5, r5, 1
|
||||||
|
|
||||||
store_next_tick:
|
store_next_tick:
|
||||||
mov r1, offsets.next_tick_low
|
add r1, zr, ptr.next_tick_low
|
||||||
store_32 [r1], r4
|
store_32 [r1], r4
|
||||||
mov r1, offsets.next_tick_high
|
add r1, zr, ptr.next_tick_high
|
||||||
store_32 [r1], r5
|
store_32 [r1], r5
|
||||||
|
|
||||||
|
|
||||||
@@ -184,7 +161,7 @@ game_loop:
|
|||||||
; r7 = new position address
|
; r7 = new position address
|
||||||
; r8 = new position content
|
; r8 = new position content
|
||||||
; r9 = jump address
|
; r9 = jump address
|
||||||
mov r1, offsets.state_robot
|
add r1, zr, ptr.state_robot
|
||||||
load_8 r2, [r1]
|
load_8 r2, [r1]
|
||||||
add r1, r1, 1
|
add r1, r1, 1
|
||||||
load_8 r3, [r1]
|
load_8 r3, [r1]
|
||||||
@@ -229,7 +206,7 @@ game_loop:
|
|||||||
cmp r8, map.tiles.wall
|
cmp r8, map.tiles.wall
|
||||||
jne game_loop_robot_movement_some
|
jne game_loop_robot_movement_some
|
||||||
; hit wall
|
; hit wall
|
||||||
mov r1, offsets.state_robot
|
add r1, zr, ptr.state_robot
|
||||||
add r1, r1, 2
|
add r1, r1, 2
|
||||||
mov r4, game.direction_still
|
mov r4, game.direction_still
|
||||||
store_8 [r1], r4
|
store_8 [r1], r4
|
||||||
@@ -240,7 +217,7 @@ game_loop:
|
|||||||
mov r8, map.tiles.empty
|
mov r8, map.tiles.empty
|
||||||
store_8 [r7], r8
|
store_8 [r7], r8
|
||||||
|
|
||||||
mov r1, offsets.state_robot
|
add r1, zr, ptr.state_robot
|
||||||
store_8 [r1], r5
|
store_8 [r1], r5
|
||||||
add r1, r1, 1
|
add r1, r1, 1
|
||||||
store_8 [r1], r6
|
store_8 [r1], r6
|
||||||
@@ -248,15 +225,13 @@ game_loop:
|
|||||||
; clear old position
|
; clear old position
|
||||||
mov r1, r2
|
mov r1, r2
|
||||||
mov r2, r3
|
mov r2, r3
|
||||||
mov r3, sprites.rotation_0
|
mov r3, sprites.empty
|
||||||
mov r4, sprites.empty
|
|
||||||
call drawing.draw_sprite_at_map_coord
|
call drawing.draw_sprite_at_map_coord
|
||||||
|
|
||||||
; draw robot on new position
|
; draw robot on new position
|
||||||
mov r1, r5
|
mov r1, r5
|
||||||
mov r2, r6
|
mov r2, r6
|
||||||
mov r3, sprites.rotation_0
|
mov r3, sprites.robot
|
||||||
mov r4, sprites.robot
|
|
||||||
call drawing.draw_sprite_at_map_coord
|
call drawing.draw_sprite_at_map_coord
|
||||||
|
|
||||||
|
|
||||||
@@ -276,7 +251,7 @@ game_loop:
|
|||||||
; r9: new position address
|
; r9: new position address
|
||||||
; r10: new position content
|
; r10: new position content
|
||||||
; r11: jump address
|
; r11: jump address
|
||||||
mov r1, offsets.state_ghost
|
add r1, zr, ptr.state_ghost
|
||||||
load_8 r2, [r1]
|
load_8 r2, [r1]
|
||||||
add r1, r1, 1
|
add r1, r1, 1
|
||||||
load_8 r3, [r1]
|
load_8 r3, [r1]
|
||||||
@@ -308,40 +283,33 @@ game_loop:
|
|||||||
game_loop_ghost_movement_make_move:
|
game_loop_ghost_movement_make_move:
|
||||||
add r7, r2, r5
|
add r7, r2, r5
|
||||||
add r8, r3, r6
|
add r8, r3, r6
|
||||||
mov r1, offsets.state_ghost
|
add r1, zr, ptr.state_ghost
|
||||||
store_8 [r1], r7
|
store_8 [r1], r7
|
||||||
add r1, r1, 1
|
add r1, r1, 1
|
||||||
store_8 [r1], r8
|
store_8 [r1], r8
|
||||||
|
|
||||||
; get tile at previous position
|
; get tile at previous position
|
||||||
push r2
|
|
||||||
mov r1, r2
|
mov r1, r2
|
||||||
mov r2, r3
|
mov r2, r3
|
||||||
call game.get_tile_address_from_map_coord
|
call game.get_tile_address_from_map_coord
|
||||||
mov r9, r13
|
load_8 r13, [r13]
|
||||||
pop r2
|
|
||||||
|
|
||||||
; draw tile at previous position
|
; draw tile at previous position
|
||||||
load_8 r1, [r9]
|
cmp r13, map.tiles.coin
|
||||||
cmp r1, map.tiles.coin
|
|
||||||
je game_loop_ghost_movement_old_tile_coin
|
je game_loop_ghost_movement_old_tile_coin
|
||||||
; old tile empty
|
; old tile empty
|
||||||
mov r4, sprites.empty
|
mov r3, sprites.empty
|
||||||
jmp game_loop_ghost_movement_draw_old_tile
|
jmp game_loop_ghost_movement_draw_old_tile
|
||||||
game_loop_ghost_movement_old_tile_coin:
|
game_loop_ghost_movement_old_tile_coin:
|
||||||
mov r4, sprites.coin
|
mov r3, sprites.coin
|
||||||
|
|
||||||
game_loop_ghost_movement_draw_old_tile:
|
game_loop_ghost_movement_draw_old_tile:
|
||||||
mov r1, r2
|
|
||||||
mov r2, r3
|
|
||||||
mov r3, sprites.rotation_0
|
|
||||||
call drawing.draw_sprite_at_map_coord
|
call drawing.draw_sprite_at_map_coord
|
||||||
|
|
||||||
; draw ghost on new position
|
; draw ghost on new position
|
||||||
mov r1, r7
|
mov r1, r7
|
||||||
mov r2, r8
|
mov r2, r8
|
||||||
mov r3, sprites.rotation_0
|
mov r3, sprites.ghost
|
||||||
mov r4, sprites.ghost
|
|
||||||
call drawing.draw_sprite_at_map_coord
|
call drawing.draw_sprite_at_map_coord
|
||||||
|
|
||||||
;
|
;
|
||||||
@@ -355,7 +323,7 @@ game_loop:
|
|||||||
cmp r10, map.tiles.wall
|
cmp r10, map.tiles.wall
|
||||||
jne game_loop_ghost_movement_end
|
jne game_loop_ghost_movement_end
|
||||||
; increment direction
|
; increment direction
|
||||||
mov r1, offsets.state_ghost
|
add r1, zr, ptr.state_ghost
|
||||||
add r1, r1, 2
|
add r1, r1, 2
|
||||||
load_8 r4, [r1]
|
load_8 r4, [r1]
|
||||||
add r4, r4, 1
|
add r4, r4, 1
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
; Sprite addresses jump table
|
||||||
|
pub ptr.textures_addresses:
|
||||||
|
U32 0 ; empty
|
||||||
|
U32 0 ; placeholder
|
||||||
|
U32 0 ; robot
|
||||||
|
U32 0 ; ghost
|
||||||
|
U32 0 ; coin
|
||||||
|
|
||||||
|
; 0.5 second = 500_000_000 nano second = 0x0000_0000_1DCD_6500
|
||||||
|
pub ptr.tick_duration_high: U32 0x0000_0000
|
||||||
|
pub ptr.tick_duration_low: U32 0x1DCD_6500
|
||||||
|
|
||||||
|
; 1 second = 1_000_000_000 nano second = 0x0000_0000_3B9A_CA00
|
||||||
|
; pub ptr.tick_duration_high: U32 0x0000_0000
|
||||||
|
; pub ptr.tick_duration_low: U32 0x3B9A_CA00
|
||||||
|
|
||||||
|
pub ptr.next_tick_high: U32 0
|
||||||
|
pub ptr.next_tick_low: U32 0
|
||||||
|
|
||||||
|
pub ptr.state_robot:
|
||||||
|
U8 0 ; x coord
|
||||||
|
U8 0 ; y coord
|
||||||
|
U8 0 ; direction
|
||||||
|
U8 0 ; [padding]
|
||||||
|
|
||||||
|
pub ptr.state_ghost:
|
||||||
|
U8 0 ; x coord
|
||||||
|
U8 0 ; y coord
|
||||||
|
U8 0 ; direction
|
||||||
|
U8 0 ; [padding]
|
||||||
Reference in New Issue
Block a user