From d13bc1e54cc937d187eb0ddde4b2e8bad8065160 Mon Sep 17 00:00:00 2001 From: shoofle Date: Wed, 26 Feb 2025 21:26:41 -0500 Subject: [PATCH] readme --- ScreenCardBrowse.inc | 4 ++-- readme.md | 13 +++++++++++++ source.zip | Bin 303261 -> 303264 bytes 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 readme.md diff --git a/ScreenCardBrowse.inc b/ScreenCardBrowse.inc index a6da19b..b980fbe 100644 --- a/ScreenCardBrowse.inc +++ b/ScreenCardBrowse.inc @@ -27,7 +27,7 @@ CardBrowseSetup: call CopyTilesToMapUnsafe - call LoadCardData + call LoadCardTask ret CardBrowseUpdate: @@ -92,7 +92,7 @@ CardBrowseUpdate: ret nz ld hl, LoadCardTask - call Async_Spawn + call Async_Spawn_HL ret diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..06667fb --- /dev/null +++ b/readme.md @@ -0,0 +1,13 @@ +This is a tarot deck for the Nintendo Game Boy (1989). I hand-coded it in assembly using [gbdev.io's live rgbds interface](https://gbdev.io/rgbds-live/). I made the art in Aseprite, using a script I heavily modified to export the data in a gameboy-compatible format for inclusion in the assembly source. + +The entry point for this software is main.asm. I would love to have properly separated all the functionality into different asm files, but rgbds-live seems not to be able to link them together. So I used `INCLUDE` directives to split it up instead. Each file beginning wih `Screen` describes one screen of the app. Simple enough. I tend to organize apps into screens or scenes, with the main loop repeatedly calling the appropriate `update` and `draw` functions on a scene object, and a helper function to change what scene is loaded (and call `setup` and `teardown`, if applicable). It seemed natural enough. It doesn't lend itself to fancy scene-changing animations, but... I'm working with hand-coded assembly on the Game Boy (1989). Forgive me for not putting enough delight and pop! in the UI of my tarot project. + +What is there to say about this project? The hardest part by far has been the art. I get into flow states programming really easily - major thanks to my spouse for keeping me from burning out on this project by enforcing working hours. The art has been a struggle. I did not realize how many drawings 22 pieces of art is. It's twenty two! That's a lot! I vaguely dread the idea of doing a whole deck. I'm going to avoid it for now. + +The part of this project I'm most proud is the Async subsystem, which you can find defined, unsurprisingly, in `Async.inc`. It's a fully functioning multithreaded programming system, powered by the game boy's LYC interrupt - a "safe" time period is defined, as a subset of the vblank period, and whenever the LY counter reaches that region, the interrupt is used to switch to a second stack and resume execution of the second thread. The upshot of this is you can write totally normal-looking code, and if you call `Async_Spawn_HL` with the appropriate argument, it will then run that code only during the "safe" time period. This went through a lot of changes in development, initially without a second stack, so the second thread had to be written with weird compromises like disabling interrupts around function calls. But now it's proper, fully functional context switching! + +Let me rephrase: you can have two simultaneous threads of execution, with their own stacks, and it will jump between them so that the second thread only executes during a safe subset of vblank. So you can write totally normal code that copies data to vram, and you don't have to keep track of when it's safe to write. + +I'm really proud of some of the art. Especially the sun, the meteor, death, and strength. + +Ah, I mentioned The Meteor! I changed Judgement to The Meteor to make the final six cards form a neat sequence of astral bodies. The meteor is depicted streaking down towards Earth, bringing destruction, devastation, a total reset, a game over. It's more oblique than Judgement but honestly, I'm the artist and I get to make the decisions. Maybe I just wanted to draw a meteor. Maybe it's a little bit of a [Homestuck reference](https://mspaintadventures.fandom.com/wiki/Meteor). \ No newline at end of file diff --git a/source.zip b/source.zip index 901e789502aea1059cdfab880167ae7473db44ea..461693d2235e2efb936dc101bc45d2e92a493e11 100644 GIT binary patch delta 762 zcmY+CO=uHQ6ooVI-A1h)NT(`jthEG_q9Qd-Yjw0*F?Jz}ZY>Qes0)7(AtEBU5o(JB zbn_-NNoE9bSD|Dv+f*q?7wSp`yHV?3DV8d&D~mJdy;(S$`R=*r-23J+)hWZ9GW63Y zI5o$@=aMlzsdpE7@U9;zF0KP)?==j-@}rp!z>CS<5|-X(lTgwN-&z5Q)viq;_~r(! z8z%pHkCxd2%{r+W8$lBnwE4{-`>r;F8UAHU`z?JVb!~hry7OzdHBo=gjQ)=fk z{FB^q{3y@m_27%nu8ho@g|=9%;E#^-GfaG`@Pz+;jPoYZc);UgAWv)kl@f1l!LVkB ze{2K&e9n)JfqMJteHN6sLZuYwNr@igqD7xY`$9?Fu;>6_!lM0vACZzSE6=$y^`qrP z@UE=PhOOX~O(r}KZR!I|+jI!fZqTomW2fTyto&W#< delta 780 zcmY+CPe>F|9LMLq_bdCe1G<|*t!A>cYbYV>R%_Olq6vkNSH(a(7^oczp{VG%=wYKM z-t5fo%p4-SWGzAio%}_I&mL}7@6EQ!=!0;QSXdvj=DW-|zR$ycv5Tm|qC0 zw{9{xqIkzUd!V4UPBQmCcWrX#Fhcyz{qZ;`wd_!|&x(=t?D_e&!YMe)uW{Hy&7<0)Hq4cl($6@O|&{lS<9uHzqtfGJ-9