diff --git a/book.toml b/book.toml index 7f28386c..352546f3 100644 --- a/book.toml +++ b/book.toml @@ -35,5 +35,5 @@ edit-url-template = "https://github.com/ISSOtm/gb-asm-tutorial/edit/master/{path site-url = "/gb-asm-tutorial/" [output.linkcheck] -traverse-parent-directories = false +traverse-parent-directories = true # We intentionally read some files outside of `src/` optional = true diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 50ee7a08..0c670973 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -23,6 +23,7 @@ # Part Ⅱ — Our first game +- [Getting started](part2/getting-started.md) - [Work in progress](part2/wip.md) # Part Ⅲ — Our second game diff --git a/src/assets/part2/img/duck.png b/src/assets/part2/img/duck.png new file mode 100644 index 00000000..d2e3c8da Binary files /dev/null and b/src/assets/part2/img/duck.png differ diff --git a/src/assets/part2/img/rgbds.png b/src/assets/part2/img/rgbds.png new file mode 100644 index 00000000..349d362e Binary files /dev/null and b/src/assets/part2/img/rgbds.png differ diff --git a/src/assets/part2/img/screenshot.png b/src/assets/part2/img/screenshot.png new file mode 100644 index 00000000..8f347e05 Binary files /dev/null and b/src/assets/part2/img/screenshot.png differ diff --git a/src/assets/part2/img/tail.png b/src/assets/part2/img/tail.png new file mode 100644 index 00000000..fc36eaba Binary files /dev/null and b/src/assets/part2/img/tail.png differ diff --git a/src/assets/part2/img/tilemap.png b/src/assets/part2/img/tilemap.png new file mode 100644 index 00000000..6295c1ec Binary files /dev/null and b/src/assets/part2/img/tilemap.png differ diff --git a/src/part2/getting-started.md b/src/part2/getting-started.md new file mode 100644 index 00000000..c59a7f94 --- /dev/null +++ b/src/part2/getting-started.md @@ -0,0 +1,158 @@ +# Getting started + +In this lesson, we will start a new project from scratch. +We will make a [Breakout](https://en.wikipedia.org/wiki/Breakout_%28video_game%29) / [Arkanoid](https://en.wikipedia.org/wiki/Arkanoid) clone, which we'll call "Unbricked"! +(Though you are free to give it any other name you like, as it will be *your* project.) + +Open a terminal and make a new directory (`mkdir unbricked`), and then enter it (`cd unbricked`), just like you did for ["Hello, world!"](../part1/hello_world.md). + +Start by creating a file called `main.asm`, and include `hardware.inc` in your code. + +```rgbasm,linenos,start={{#line_no_of "" ../../unbricked/getting-started/main.asm:includes}} +{{#include ../../unbricked/getting-started/main.asm:includes}} +``` +You may be wondering what purpose `hardware.inc` serves. +Well, the code we write only really affects the CPU, but does not do anything with the rest of the console (not directly, anyway). +To interact with other components (like the graphics system, say), [Memory-Mapped I/O](https://en.wikipedia.org/wiki/Memory-mapped_I/O) (MMIO) is used: basically, [memory](../part1/memory.md) in a certain range (addresses $FF00–FF7F) does special things when accessed. + +These bytes of memory being interfaces to the hardware, they are called *hardware registers* (not to be mistaken with [the CPU registers](../part1/registers.md)). +For example, the "PPU status" register is located at address $FF41. +Reading from that address reports various bits of info regarding the graphics system, and writing to it allows changing some parameters. +But, having to remember all the numbers ([non-exhaustive list](https://gbdev.io/pandocs/Power_Up_Sequence.html#hardware-registers)) would be very tedious—and this is where `hardware.inc` comes into play! +`hardware.inc` defines one constant for each of these registers (for example, `rSTAT` for the aforementioned "PPU status" register), plus some additional constants for values read from or written to these registers. + +::: tip + +Don't worry if this flew over your head, we'll see an example below with `rLCDC` and `LCDCF_ON`. + +By the way, the `r` stands for "register", and the `F` in `LCDCF` stands for "flag". + +::: + +Next, make room for the header. +[Remember from Part Ⅰ](../part1/header.md) that the header is where some information that the Game Boy relies on is stored, so you don't want to accidentally leave it out. + +```rgbasm,linenos,start={{#line_no_of "" ../../unbricked/getting-started/main.asm:header}} +{{#include ../../unbricked/getting-started/main.asm:header}} +``` + +The header jumps to `EntryPoint`, so let's write that now: + +```rgbasm,linenos,start={{#line_no_of "" ../../unbricked/getting-started/main.asm:entry}} +{{#include ../../unbricked/getting-started/main.asm:entry}} +``` + +The next few lines wait until "VBlank", which is the only time you can safely turn off the screen (doing so at the wrong time could damage a real Game Boy, so this is very crucial). +We'll explain what VBlank is and talk about it more later in the tutorial. + +Turning off the screen is important because loading new tiles while the screen is on is tricky—we'll touch on how to do that in Part 3. + +Speaking of tiles, we're going to load some into VRAM next, using the following code: + +```rgbasm,linenos,start={{#line_no_of "" ../../unbricked/getting-started/main.asm:copy_tiles}} +{{#include ../../unbricked/getting-started/main.asm:copy_tiles}} +``` + +This loop might be [reminiscent of part Ⅰ](../part1/jumps.md#conditional-jumps). +It copies starting at `Tiles` to `$9000` onwards, which is the part of VRAM where our [tiles](../part1/tiles.md) are going to be stored. +Recall that `$9000` is where the data of background tile $00 lies, and the data of subsequent tiles follows right after. +To get the number of bytes to copy, we will do just like in Part Ⅰ: using another label at the end, called `TilesEnd`, the difference between it (= the address after the last byte of tile data) and `Tiles` (= the address of the first byte) will be exactly that length. + +That said, we haven't written `Tiles` nor any of the related data yet. +We'll get to that later! + +Almost done now—next, write another loop, this time for copying [the tilemap](../part1/tilemap.md). + +```rgbasm,linenos,start={{#line_no_of "" ../../unbricked/getting-started/main.asm:copy_map}} +{{#include ../../unbricked/getting-started/main.asm:copy_map}} +``` + +Note that while this loop's body is exactly the same as `CopyTiles`'s, the 3 values loaded into `de`, `hl`, and `bc` are different. +These determine the source, destination, and size of the copy, respectively. + +::: tip "[DRY](https://en.wikipedia.org/wiki/Don't_Repeat_Yourself)" + +If you think that this is super redundant, you are not wrong, and we will see later how to write actual, reusable *functions*. +But there is more to them than meets the eye, so we will start tackling them much later. + +::: + +Finally, let's turn the screen back on, and set a [background palette](../part1/palettes.md). +Rather than writing the non-descript number `%10000001` (or $81 or 129, to taste), we make use of two constants graciously provided by `hardware.inc`: `LCDCF_ON` and `LCDCF_BGON`. +When written to [`rLCDC`](https://gbdev.io/pandocs/LCDC), the former causes the PPU and screen to turn back on, and the latter enables the background to be drawn. +(There are other elements that could be drawn, but we are not enabling them yet.) +Combining these constants must be done using `|`, the *binary "or"* operator; we'll see why later. + +```rgbasm,linenos,start={{#line_no_of "" ../../unbricked/getting-started/main.asm:end}} +{{#include ../../unbricked/getting-started/main.asm:end}} +``` + +There's one last thing we need before we can build the ROM, and that's the graphics. +We will draw the following screen: + +![Layout of unbricked](../assets/part2/img/tilemap.png) + +In `hello-world.asm`, tile data had been written out by hand in hexadecimal; this was to let you see how the sausage is made at the lowest level, but *boy* is it impractical to write! +This time, we will employ a more friendly way, which will let us write each row of pixels more easily. +For each row of pixels, instead of writing [the bitplanes](../part1/tiles.md#encoding) directly, we will use a backtick (`` ` ``) followed by 8 characters. +Each character defines a single pixel, intuitively from left to right; it must be one of 0, 1, 2, and 3, representing the corresponding color index in [the palette](../part1/palettes.md). + +::: tip + +If the character selection isn't to your liking, you can use [RGBASM's `-g` option](https://rgbds.gbdev.io/docs/v0.5.2/rgbasm.1#g) or [`OPT g`](https://rgbds.gbdev.io/docs/v0.5.2/rgbasm.5/#Changing_options_while_assembling) to pick others. +For example, `rgbasm -g '.xXO' (...)` or `OPT g.xXO` would swap the four characters to `.`, `x`, `X`, and `O` respectively. + +::: + +For example: + +```rgbasm + dw `01230123 ; This is equivalent to `db $55,$33` +``` + +You may have noticed that we are using `dw` instead of `db`; the difference between these two will be explained later. +We already have tiles made for this project, so you can copy [this premade file](../../unbricked/getting-started/tileset.asm), and paste it at the end of your code. + +Then copy the tilemap from [this file](../../unbricked/getting-started/tilemap.asm), and paste it after the `TilesEnd` label. + +You can build the ROM now, by running the following commands in your terminal: + +```console +$ rgbasm -L -o main.o main.asm +$ rgblink -o unbricked.gb main.o +$ rgbfix -v -p 0xFF unbricked.gb +``` + +If you run this in your emulator, you should see the following: + +![Screenshot of our game](../assets/part2/img/screenshot.png) + +That white square seems to be missing! +You may have noticed this comment earlier, somewhere in the tile data: + +```rgbasm,linenos,start={{#line_no_of "" ../../unbricked/getting-started/main.asm:custom_logo}} +{{#include ../../unbricked/getting-started/main.asm:custom_logo}} +``` + +The logo tiles were left intentionally blank so that you can choose your own. +You can use one of the following pre-made logos, or try coming up with your own! + +- **RGBDS Logo** + + ![The RGBDS Logo](../assets/part2/img/rgbds.png) + + [Source](../../unbricked/getting-started/rgbds.asm) + +- **Duck** + + ![A pixel-art duck](../assets/part2/img/duck.png) + + [Source](../../unbricked/getting-started/duck.asm) + +- **Tail** + + ![A silhouette of a tail](../assets/part2/img/tail.png) + + [Source](../../unbricked/getting-started/tail.asm) + +Replace the blank tiles with the new graphics, build the game again, and you should see your logo of choice in the bottom-right! diff --git a/unbricked/2bpp2asm.c b/unbricked/2bpp2asm.c new file mode 100644 index 00000000..bbf9fb10 --- /dev/null +++ b/unbricked/2bpp2asm.c @@ -0,0 +1,39 @@ +#include +#include +#include + +int main(int argc, char ** argv) { + if (argc != 4) { + fprintf(stderr, "Expected 4 arguments\nUsage: %s ", argv[0]); + exit(1); + } + + FILE * infile = fopen(argv[2], "rb"); + FILE * outfile = fopen(argv[3], "w"); + + if (!infile) { + perror("infile"); + exit(1); + } + + if (!outfile) { + perror("outfile"); + exit(1); + } + + char * pixels = argv[1]; + + while (1) { + uint8_t light_row = fgetc(infile); + uint8_t dark_row = fgetc(infile); + if (feof(infile)) break; + fputs("\tdw `", outfile); + for (int i = 0; i < 8; i++) { + uint8_t shade = (light_row & 0x80) >> 7 | (dark_row & 0x80) >> 6; + fputc(pixels[shade], outfile); + light_row <<= 1; + dark_row <<= 1; + } + fputc('\n', outfile); + } +} \ No newline at end of file diff --git a/unbricked/getting-started/duck.asm b/unbricked/getting-started/duck.asm new file mode 100644 index 00000000..b34d1c30 --- /dev/null +++ b/unbricked/getting-started/duck.asm @@ -0,0 +1,128 @@ + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222211 + dw `22222211 + dw `22222211 + dw `22222222 + dw `22222222 + dw `22222222 + dw `11111111 + dw `11111111 + dw `11221111 + dw `11221111 + dw `11000011 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `11222222 + dw `11222222 + dw `11222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222211 + dw `22222200 + dw `22222200 + dw `22000000 + dw `22000000 + dw `22222222 + dw `22222222 + dw `22222222 + dw `11000011 + dw `11111111 + dw `11111111 + dw `11111111 + dw `11111111 + dw `11111111 + dw `11111111 + dw `11000022 + dw `11222222 + dw `11222222 + dw `11222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222200 + dw `22222200 + dw `22222211 + dw `22222211 + dw `22221111 + dw `22221111 + dw `22221111 + dw `11000022 + dw `00112222 + dw `00112222 + dw `11112200 + dw `11112200 + dw `11220000 + dw `11220000 + dw `11220000 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22000000 + dw `22000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `22222222 + dw `11110022 + dw `11110022 + dw `11110022 + dw `22221111 + dw `22221111 + dw `22221111 + dw `22221111 + dw `22221111 + dw `22222211 + dw `22222211 + dw `22222222 + dw `11220000 + dw `11110000 + dw `11110000 + dw `11111111 + dw `11111111 + dw `11111111 + dw `11111111 + dw `22222222 + dw `00000000 + dw `00111111 + dw `00111111 + dw `11111111 + dw `11111111 + dw `11111111 + dw `11111111 + dw `22222222 + dw `11110022 + dw `11000022 + dw `11000022 + dw `00002222 + dw `00002222 + dw `00222222 + dw `00222222 + dw `22222222 diff --git a/unbricked/getting-started/main.asm b/unbricked/getting-started/main.asm new file mode 100644 index 00000000..70b26d97 --- /dev/null +++ b/unbricked/getting-started/main.asm @@ -0,0 +1,177 @@ +; ANCHOR: dummy Lines beginning with `ANCHOR` and `ANCHOR_END` are used by mdBook +; ANCHOR_END: dummy Note that lines matching /^; ANCHOR/ are stripped from the online version +; ANCHOR: includes +INCLUDE "hardware.inc" +; ANCHOR_END: includes + +; ANCHOR: header +SECTION "Header", ROM0[$100] + + jp EntryPoint + + ds $150 - @, 0 ; Make room for the header +; ANCHOR_END: header + +; ANCHOR: entry +EntryPoint: + ; Do not turn the LCD off outside of VBlank +WaitVBlank: + ld a, [rLY] + cp 144 + jr c, WaitVBlank + + ; Turn the LCD off + ld a, 0 + ld [rLCDC], a +; ANCHOR_END: entry + +; ANCHOR: copy_tiles + ; Copy the tile data + ld de, Tiles + ld hl, $9000 + ld bc, TilesEnd - Tiles +CopyTiles: + ld a, [de] + ld [hli], a + inc de + dec bc + ld a, b + or a, c + jr nz, CopyTiles +; ANCHOR_END: copy_tiles + +; ANCHOR: copy_map + ; Copy the tilemap + ld de, Tilemap + ld hl, $9800 + ld bc, TilemapEnd - Tilemap +CopyTilemap: + ld a, [de] + ld [hli], a + inc de + dec bc + ld a, b + or a, c + jr nz, CopyTilemap +; ANCHOR_END: copy_map + +; ANCHOR: end + ; Turn the LCD on + ld a, LCDCF_ON | LCDCF_BGON + ld [rLCDC], a + + ; During the first (blank) frame, initialize display registers + ld a, %11100100 + ld [rBGP], a + +Done: + jr Done +; ANCHOR_END: end + +Tiles: + dw `33333333 + dw `33333333 + dw `33333333 + dw `33322222 + dw `33322222 + dw `33322222 + dw `33322211 + dw `33322211 + dw `33333333 + dw `33333333 + dw `33333333 + dw `22222222 + dw `22222222 + dw `22222222 + dw `11111111 + dw `11111111 + dw `33333333 + dw `33333333 + dw `33333333 + dw `22222333 + dw `22222333 + dw `22222333 + dw `11222333 + dw `11222333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33322211 + dw `33322211 + dw `33322211 + dw `33322211 + dw `33322211 + dw `33322211 + dw `33322211 + dw `33322211 + dw `22222222 + dw `20000000 + dw `20111111 + dw `20111111 + dw `20111111 + dw `20111111 + dw `22222222 + dw `33333333 + dw `22222223 + dw `00000023 + dw `11111123 + dw `11111123 + dw `11111123 + dw `11111123 + dw `22222223 + dw `33333333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `11001100 + dw `11111111 + dw `11111111 + dw `21212121 + dw `22222222 +; ANCHOR: custom_logo + dw `22322232 + dw `23232323 + dw `33333333 + ; Paste your logo here: + +TilesEnd: +; ANCHOR_END: custom_logo + +Tilemap: + db $00, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $02, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $0A, $0B, $0C, $0D, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $0E, $0F, $10, $11, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $12, $13, $14, $15, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $16, $17, $18, $19, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $09, $09, $09, $09, $09, $09, $09, $09, $09, $09, $09, $09, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 +TilemapEnd: diff --git a/unbricked/getting-started/rgbds.asm b/unbricked/getting-started/rgbds.asm new file mode 100644 index 00000000..4039921f --- /dev/null +++ b/unbricked/getting-started/rgbds.asm @@ -0,0 +1,128 @@ + dw `33000000 + dw `33000000 + dw `33000000 + dw `33000000 + dw `33111100 + dw `33111100 + dw `33111111 + dw `33111111 + dw `33331111 + dw `00331111 + dw `00331111 + dw `00331111 + dw `00331111 + dw `00331111 + dw `11331111 + dw `11331111 + dw `11333300 + dw `11113300 + dw `11113300 + dw `11113300 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `00003333 + dw `00000033 + dw `00000033 + dw `00000033 + dw `11000033 + dw `11000033 + dw `11111133 + dw `11111133 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11113311 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `33111111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11331111 + dw `11330000 + dw `11330000 + dw `11330000 + dw `33330000 + dw `11113311 + dw `11113311 + dw `00003311 + dw `00003311 + dw `00003311 + dw `00003311 + dw `00003311 + dw `00333311 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11111133 + dw `11113333 diff --git a/unbricked/getting-started/tail.asm b/unbricked/getting-started/tail.asm new file mode 100644 index 00000000..286fc332 --- /dev/null +++ b/unbricked/getting-started/tail.asm @@ -0,0 +1,128 @@ + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33302333 + dw `33333133 + dw `33300313 + dw `33300303 + dw `33013330 + dw `30333333 + dw `03333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `03333333 + dw `30333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333330 + dw `33333320 + dw `33333013 + dw `33330333 + dw `33100333 + dw `31001333 + dw `20001333 + dw `00000333 + dw `00000033 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33330333 + dw `33300333 + dw `33333333 + dw `33033333 + dw `33133333 + dw `33303333 + dw `33303333 + dw `33303333 + dw `33332333 + dw `33332333 + dw `33333330 + dw `33333300 + dw `33333300 + dw `33333100 + dw `33333000 + dw `33333000 + dw `33333100 + dw `33333300 + dw `00000001 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `10000333 + dw `00000033 + dw `00000003 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `33332333 + dw `33302333 + dw `32003333 + dw `00003333 + dw `00003333 + dw `00013333 + dw `00033333 + dw `00033333 + dw `33333300 + dw `33333310 + dw `33333330 + dw `33333332 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `30000000 + dw `33000000 + dw `33333000 + dw `33333333 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000003 + dw `00000033 + dw `00003333 + dw `02333333 + dw `33333333 + dw `00333333 + dw `03333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 diff --git a/unbricked/getting-started/tilemap.asm b/unbricked/getting-started/tilemap.asm new file mode 100644 index 00000000..42afef99 --- /dev/null +++ b/unbricked/getting-started/tilemap.asm @@ -0,0 +1,20 @@ +Tilemap: + db $00, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $02, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $05, $06, $05, $06, $05, $06, $05, $06, $05, $06, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $0A, $0B, $0C, $0D, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $0E, $0F, $10, $11, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $12, $13, $14, $15, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $07, $03, $16, $17, $18, $19, $03, 0,0,0,0,0,0,0,0,0,0,0,0 + db $04, $09, $09, $09, $09, $09, $09, $09, $09, $09, $09, $09, $09, $07, $03, $03, $03, $03, $03, $03, 0,0,0,0,0,0,0,0,0,0,0,0 +TilemapEnd: diff --git a/unbricked/getting-started/tileset.asm b/unbricked/getting-started/tileset.asm new file mode 100644 index 00000000..98d7ee9d --- /dev/null +++ b/unbricked/getting-started/tileset.asm @@ -0,0 +1,84 @@ +Tiles: + dw `33333333 + dw `33333333 + dw `33333333 + dw `33322222 + dw `33322222 + dw `33322222 + dw `33322211 + dw `33322211 + dw `33333333 + dw `33333333 + dw `33333333 + dw `22222222 + dw `22222222 + dw `22222222 + dw `11111111 + dw `11111111 + dw `33333333 + dw `33333333 + dw `33333333 + dw `22222333 + dw `22222333 + dw `22222333 + dw `11222333 + dw `11222333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33333333 + dw `33322211 + dw `33322211 + dw `33322211 + dw `33322211 + dw `33322211 + dw `33322211 + dw `33322211 + dw `33322211 + dw `22222222 + dw `20000000 + dw `20111111 + dw `20111111 + dw `20111111 + dw `20111111 + dw `22222222 + dw `33333333 + dw `22222223 + dw `00000023 + dw `11111123 + dw `11111123 + dw `11111123 + dw `11111123 + dw `22222223 + dw `33333333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `11222333 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `00000000 + dw `11001100 + dw `11111111 + dw `11111111 + dw `21212121 + dw `22222222 + dw `22322232 + dw `23232323 + dw `33333333 + ; Paste your logo here: + +TilesEnd: diff --git a/unbricked/map2asm.c b/unbricked/map2asm.c new file mode 100644 index 00000000..b887180f --- /dev/null +++ b/unbricked/map2asm.c @@ -0,0 +1,35 @@ +#include +#include +#include + +int main(int argc, char ** argv) { + if (argc != 4) { + fprintf(stderr, "Expected 4 arguments\nUsage: %s ", argv[0]); + exit(1); + } + + FILE * infile = fopen(argv[1], "rb"); + FILE * outfile = fopen(argv[2], "w"); + + if (!infile) { + perror("infile"); + exit(1); + } + + if (!outfile) { + perror("outfile"); + exit(1); + } + + char * pixels = argv[1]; + + while (1) { + fputs("\tdb ", outfile); + for (int i = 0; i < 20; i++) { + int byte = fgetc(infile); + if (byte == EOF) exit(0); + fprintf(outfile, "$%X, ", byte); + } + fputs("0,0,0,0,0,0,0,0,0,0,0,0\n", outfile); + } +}