Third longest function in all of PC-98 Touhou, and it's even more of a
copy-pasta than the patterns we've seen earlier. Certainly didn't feel
that long.
Part of P0156, funded by Ember2528.
The one where Konngara swings their sword and fires fast aimed pellets
towards the player.
The third time we've seen the exact same basic function layout…
Part of P0155, funded by Ember2528.
The one with lasers fired from the sword across the whole playfield,
either from left to right or from right to left, together with aimed
3-way spreads, every 10 frames.
Part of P0155, funded by Ember2528.
Similarly to cb6367a, you also can't tell from a function's ASM whether
a parameter that's assigned to an 8-bit destination is actually an 8-bit
parameter, or a narrowed 16-bit parameter. That can really only be
gleaned from looking at all call sites…
Part of P0155, funded by Ember2528.
The one where Konngara swings their sword and spawns triangle-shaped
subpatterns along the slash path.
At least no randomness in that one.
Part of P0155, funded by Ember2528.
The one where Konngara swings their sword and lets pellets rain along
the (surprisingly triangular) slash path.
Yeah… not worth expressing these coordinates in playfield space when
they clearly correspond to specific locations in the background image.
Completes P0154, funded by Ember2528.
The one where Konngara shoots rays in a semicircle motion from their
sword to the edge of the playfield, with pellets raining down from the
ray's end point.
Insert "if… else if… else if…" joke. And hey, I've finally had the idea
to use function-local enums in place of #define!
Part of P0154, funded by Ember2528.
The one where a gray diamond first flies from Konngara's left sleeve to
the top of the playfield, and then moves downwards in rows from left to
right and back, shooting aimed pellets along the way.
Completes P0153, funded by Ember2528.
The one with two homing snakes, and pellets fired in a semicircle
spread. And yes, Reimu really has a 30×30-pixel hitbox against the
snakes.
Much simpler than its instruction count might suggest. Recalculating
array element addresses over and over is certainly a way to add bloat…
And yes, we're going to see all of this exact same code again in the
four-snake pattern.
Part of P0153, funded by Ember2528.
At least I *hope* it's an improvement. `point` should be reserved for
actual structures with .x and .y members.
Part of P0149, funded by Blue Bolt, Ember2528, and -Tom-.
The one where Konngara fires 4 diamonds in a cross-shaped motion
towards the edges of the screen, with random pellets raining down for
200 frames afterwards.
Completes P0142, funded by Yanga.
Oh no, another place in which I'm going too far?! Just because I'm sick
of hardcoded number literals after 6 years? Hm…
Part of P0142, funded by Yanga.
We're going to need some name for the longer, boss-specific danmaku
animations. Turns out that these are exactly called "patterns" in
Sparen's glossary:
https://sparen.github.io/ph3tutorials/ddsg0.html#sub4
So what we called a "pattern" is actually called a "group". Whoops!
Part of P0142, funded by Yanga.
Amazing how both an `int` and an `unsigned char` parameter generate the
exact same ASM if they're only passed on to a single function that
widens them to a 16-bit type.
Part of P0142, funded by Yanga.
It's script-like code, what can you say. Maybe minimally sloppy in some
places, but ultimately harmless.
Oh, the Siddhaṃ seed syllables are supposed to show up immediately, with
no delay between them? Good to know – clocking your emulator too low
tends to roll them down from the top of the screen, and does add a
noticeable delay between the individual images.
… Wait, but this means that ZUN could have *intended* this "effect".
Why else would he not only put those syllables into four individual
images, but also show them on the foreground VRAM page?
Completes P0141, funded by [Anonymous] and rosenrose.
ASM land had a macro for this, which suggested a corresponding inlined
class method in C++ land. We couldn't use that macro for Konngara's
third boss entity though. So I probably wanted to wait with that inline
function until the decompilation of that Konngara load call, which
could verify the existence of said inline function. And it did!
Part of P0141, funded by [Anonymous] and rosenrose.
We've got to move all of Konngara's escape sequences to C land right
now, to get them out of the way of the filenames, so we might as well
look at all of them, in the entire binary.
But, uh… "graph mode"? That one is severely underdocumented, seemingly
even in Japanese. Turns out that it's a way to disable Shift-JIS
decoding, which makes it possible to access the half-width glyphs in
the PC-98 font ROM at the 0x81-0x9F and 0xE0-0xFF codepoints.
(In regular "kanji mode", these are interpreted as Shift-JIS lead
bytes.)
So, I did a deep dive into NEC's IO.SYS to hunt down all places where
this distinction has an effect, and then implemented it into DOSBox-X,
which was still missing everything related to it:
https://github.com/joncampbell123/dosbox-x/pull/2547
If P0140 looks a bit empty as a result, that's why – most of the
feature work went into DOSBox-X, not ReC98. That's the beauty of
"anything" pushes. :tannedcirno:
So, after switching to graph mode, TH01 does… one of the slowest
possible memset()s over all of text RAM (one printf(" ") call for every
single one of its 80×25 half-width cells), before switching back to
kanji mode. What a waste of RE time…? Oh well, at least we've now got
plenty of documentation to prove to future port authors that these
weird escape sequences *actually* do nothing.
Completes P0140, funded by [Anonymous].
At least that's what we can infer from its position in the code.
Putting it into player shots for the sole reason that it's easier to
find it there.
Part of P0140, funded by [Anonymous].
This gets rid of a couple of per-entity sprite bitplane types, makes
sprite declarations easier to read by putting width and height next to
each other… and points out a number of array dimension mistakes -.-
Even in places where we can't use it.
Part of P0138, funded by [Anonymous] and Blue Bolt.
DOS is not the same thing as the underlying CPU, after all. A separate
file not only indicates to future port authors which parts of the code
are x86-specific, but it also speeds up build times…
… in theory, because removing 677 lines from 49 files each doesn't seem
to speed up the build as much as I had hoped? But apparently my whole
system mysteriously got faster in the meantime, and I was getting 22-23
seconds for the entire repo even before this commit. Good enough.
Part of P0134, funded by [Anonymous].
Functions with 12 parameters are hard to describe, y'know. Looking
forward to decompiling these giant expressions for the actual
boss↔orb collision parameter passed to this function…
Oh well, at least we're now totally ready for some boss code next
year. 😌
Completes P0131, funded by Yanga.
Yes, no "generator", just a single number. Used to add some very
minimal randomness to certain things, by taking it modulo a small
number.
Part of P0131, funded by Yanga.