If the macro itself is local to a function, these can work in certain
scenarios, but never for global ones.
Part of P0186, funded by [Anonymous] and Blue Bolt.
We have finally run out of letters to remove from the first segment
name in TH05! 🎉 But we surely won't have to decompile any other
function from the middle of any of these 7 segments soon, right?
Right…?
Part of P0185, funded by [Anonymous], -Tom-, and Blue Bolt.
The algorithm for gradually rotating these clockwise or counterclockwise
towards the player could have been 5 lines long. ZUN blows it up to 26
lines.
Also, a 16×16 killbox for the head node, and a 12×12 one for trail
nodes.
Part of P0185, funded by [Anonymous], -Tom-, and Blue Bolt.
Too bad that alignment constraints do in fact force us to compile
th04/bullet_u.cpp and th04/bullet_a.cpp separately. 😕
Part of P0184, funded by -Tom-.
Not just the maximum bounce count. Unsurprisingly, I also did a rather
shallow job in this part of the bullet code back in 2020…
Part of P0184, funded by -Tom-.
Wow. After concluding that "normal" is a difficulty level in late July
2021 (see 05e4c4a), I then spent months looking at TH01 boss code,
without once noticing that this game was still using it!
Part of P0184, funded by -Tom-.
The single underscore version is actually slightly more supported among
the compilers I've seen so far. Also added the exact list now.
Part of P0183, funded by Yanga and [Anonymous].
Reason: Self-modifying. -.-
The main shape used for drawing into this bitmap. "Stripes" would have
been a better name, with only the top 2 (screen) / 1 (VRAM) out of
every 8 (screen) / 4 (VRAM) pixels inside these rectangles being
actually set as collidable inside this bitmap. If a player's hitbox
happens to be smaller than 8 (screen) / 4 (VRAM) pixels, this would
mean that a player could dodge right through two of these stripes. Same
for the CPU, which would make it obvious how it could cheat.
But are player hitboxes actually small enough for that to be possible?
Gotta add another push to find out…
(Also, wow, that's some ingenious bit twiddling right there… and it's
all completely correct. 🤯 Whether all that complexity and especially
all that register overloading would have been *necessary*, on the other
hand…)
Completes P0182, funded by Lmocinemod and [Anonymous].
Ironically only used for pellets, which are now confirmed to have a 2×2
(screen) / 2×1 (VRAM) hitbox. Might have been "decompilable", but it's
sandwiched between undecompilable functions.
Part of P0182, funded by Lmocinemod and [Anonymous].
Oh wow, it's exactly how I always naively imagined collision detection
to be implemented in a fixed-resolution 2D bullet hell game with small
hitboxes.
Part of P0182, funded by Lmocinemod and [Anonymous].
Makes sense for this game as well, even if it can only serve
documentary purpose due to it not knowing which playfield it's on.
Part of P0182, funded by Lmocinemod and [Anonymous].
Second PC-98 Touhou boss completely decompiled, 29 to go! But meh,
ZUN's original code did in fact force the three leaf pattern sprites
into separate 1-sprite sheets…
Completes P0181, funded by Ember2528.
The one where Sariel's second form shoots sparks towards the top of the
playfield, which then turn into leaf-like sprites that sway towards the
bottom, killing Reimu on contact.
And wow, what a finish! A weird "decimal subpixel" type, hardcoded
sprites, and effectively unused non-hardcoded sprites. Too bad that it
also ruins the nice `dot_rect_t(w, h)` parameter abstraction for
grcg_put_8x8_mono()…
Completes P0180, funded by Yanga.
The one where evenly spaced, randomly aimed pellets rain down from an
imaginary horizontal line at the seal's center Y coordinate. Featuring
an equally broken symmetric spawn ray variant.
Part of P0180, funded by Yanga.
The one where decelerating pellets form a curve shape, by being fired
from the center and aimed along the bottom left and right edges of the
playfield.
First pattern of Sariel's second form… which is where ZUN apparently
learned to pass the frame count as a parameter. Would have been even
nicer if the return value indicated when the pattern is done instead of
mutating a reference to the frame count.
Completes P0179, funded by Ember2528.
The one where Sariel fires vertical 3-stacks with two spawners moving
from between the two bottom edges of the playfield, followed by
randomly raining bullets from two spawners moving between the two top
edges of the playfield. Final pattern of Sariel's first form, and
surprisingly fair by never spawning pellets on top of Reimu.
Also, about time I found a way of bypassing the -Z -3 function
parameter optimization in order to keep using nice structures like
these.
Part of P0179, funded by Ember2528.
The one where Sariel fires four semicircle spreads from their shield,
10 frames apart.
So nice and simple that it warrants trying out a more compact coding
style for these `for` loops with two loop variables. The more I look at
it, the more I like it? I do think it's good.
Completes P0178, funded by Ember2528.
The one where symmetric birds spawn from the bottom of the playfield,
then fly to the top while shooting bullets at random angles.
Part of P0178, funded by Ember2528.
The one with a single spawn ray spinning from Sariel's shield across
the seal, followed by radial pellet stacks and lasers being fired from
the same position.
Completes P0177, funded by Yanga.