The TH04/TH05 BGM/SE mode setup is a good example for code where
different structure field offsets will vanish completely upon reverse-
engineering. If we continued to use the per-game ID string as the
variable name, we'd only have another game-specific "difference" there.
Part of P0065, funded by Touhou Patch Center.
WTF. Fine, let's have separate, micro-optimized ASM implementations for
decoding and encoding inr MAIN.EXE, but still, all those minute
difference between OP.EXE and MAINE.EXE…
This is as far as anyone should reasonably go before decompilation;
things will get really ugly with the loading functions once the file
name is involved as well…
Completes P0063, funded by -Tom-.
Funny how the actual scores are stored as little-endian gaiji strings
in the bold font, yet never actually used as such.
Part of P0063, funded by -Tom-.
Since a few annoying alignment bytes suggested more translation units
than previously expected, using many small headers has proved to be
better than one big shared TH04/TH05 header file. Or should we *really*
pepper the code with lots of `#pragma codestring`? 😛
And in case we have multiple translation units which all #include the
same set of headers, we'll just go with situational shared headers,
using a common prefix.
Part of P0062, funded by Touhou Patch Center.
At least wherever Turbo C++ and master.lib want us to use a
non-pointer, since both use uint16_t for segment values throughout
their APIs instead of the more sensible void __seg*. Maybe, integer
arithmetic on segment values was widely considered more important than
dereferencing?
*Finally*. We already used `(unsigned) int` in quite a few places where
we actually want a 16-bit value, which was bound to annoy future port
developers.
"bgimage" really was the best name I could come up with here, given
what it's used for. Everything else sounded way too ambiguous. Even
something like "mempage", in the meaning of "a third memory-backed
graphics page"… --Nmlgc
The pascal calling convention for TH03's input mode functions actually
sort of matters, since we have this nice function pointer type that
expects pascal.
Not applying this leak to TH03 since it would have more than one
`key_det` variable, resulting in names that are as much fanfiction as
the current ones…
Raw, uninteresting position independence work. Or maybe not, given that
this was one of the few things that also apply to TH01, and reveal just
how chaotically this game was coded. And so we've got three ways that
ZUN stored regular 2D points: Regularly (X first, Y second), Y first
and X second, and multiple points stored in a structure of arrays…
Completes P0059, funded by [Anonymous] and -Tom-.
In the end, the explosions remain the only constant in these phases,
everything else ("defeat"? "last phase"?) could have been
misunderstood. And yes, the algorithm really treated these 111
constants as potential memory references…
Completes P0058, funded by -Tom-.
> not using the Point structure, which is not only perfectly suitable
here, but would have also generated much better code
Part of P0058, funded by -Tom-.
Welcome to this new [brand] of reverse-engineering, where we only fix
things that might be mistaken for addresses, without looking deeper
into what the actual functions do… unless that directly leaps into
the eye.
Part of P0057, funded by [Anonymous] and -Tom-.
"Splashes"? That's what uth05win calls them. Oh well, "circle" is
already taken, and merely keeping the slices in the item/ directory
won't avoid the name collision when looking at game code.
These are hardly visible on top of regular enemy explosion animations;
you can most clearly see them at the end of the TH04 Extra Stage
midboss. Easy enough to *almost* completely cover right now, even
during a position independence push. Struct strITEM_SPLASH in uth05win.
Part of P0057, funded by [Anonymous] and -Tom-.
Yeah… such fun pretending that the original code wasn't copy-pasted.
And yes, Reimu will have to wait until the next one.
Completes P0037, funded by zorg.
That should make this convoluted copypasta a bit easier to read. And
sure, I could have done something about the loop as well, but
SHOT_FUNC_INIT already hides enough control flow behind a macro…
Part of P0037, funded by zorg.