Once we decompile whatever can be decompiled of those, we're going to
use the same coordinate constants for both these and the backdrop
image. Ideally, we can even macro (or inline-function) away the entire
implementation, so that the redundancy between TH04's and TH05's Stage
4 bosses won't matter as much.
Part of P0189, funded by Arandui and Lmocinemod.
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].
Sure, we can't use them everywhere, but it's really nice to get rid of
that casting madness – and any explicit references to x86 memory
segmentation – wherever we can.
Part of P0138, funded by [Anonymous] and Blue Bolt.
Might look uglier, but has the advantage of not generating an empty
segment with the default name… *and* the default padding, which will
really come in handy with the following breakthrough.
Part of P0137, funded by [Anonymous].
Whoops, turns out that the build has been broken on TASM32 version 5.3
(the one in the DevKit) ever since 7897bf1. In contrast to version 5.0
(which I use for my development), 5.3 actually defines 32-bit segments
if you specify a .386 CPU before using .MODEL.
That might have been the reason for the .286 workaround all along?
Turns out there's the USE16 modifier, which makes this much more
explicit than switching CPUs.
Eh, REP MOVSD is used too inconsistently across the games to justify
replacing these macros with an `inline` function. Still can use a
custom one here to make the register usage a bit more explicit, though.
Part of P0136, funded by [Anonymous].
eeb4e7e changed the final C translation unit that used this header to
C++, and we got some more helpful inline functions upcoming.
Part of P0136, funded by [Anonymous].
Not that it really fits there either, but I've been trying to keep the
th0?/ directories free from any actual code. They should only contain
the distinct translation units within the original three .EXE binaries,
`#include`ing files from subdirectories, along with maybe game-specific
`#pragma`s, but contain no code on their own. Port authors would simply
ignore those, and link everything from the subdirectories into one
binary. That approach has seemed to make the most sense for all of this
so far.
Part of P0135, funded by [Anonymous].
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].
Turns out the inlining behavior of `const` variables at global scope
that we've been relying on lately is actually exclusive to C++ mode…
once again!
Part of P0133, funded by [Anonymous].
Reason: Manual "tail call optimization" of input_reset_sense(), with
execution falling through to input_sense() immediately below.
Part of P0133, funded by [Anonymous].
Actually fairly average, as far as unreasonable decompilations are
concerned. No `goto`, at least! Another place that would benefit from
EGC raster op documentation, though.
Also, got one more padding byte in TH05's MAINE.EXE correct. 🙂
Part of P0126, funded by [Anonymous] and Blue Bolt.
And get rid of the constraining FX() macro, with its spacing parameter
that we haven't even seen used so far.
Part of P0124, funded by [Anonymous] and Blue Bolt.
The TH04 one might have the same function structure, but the only thing
that's actually identical in both games is the picture darkening loop.
Part of P0119, funded by [Anonymous] and -Tom-.
Whew, time to look at every `int` variable we ever declared! The best
moment to do this would have been a year ago, but well, better late
than never. No need to communicate that in comments anymore.
These shouldn't be used for widths, heights, or sprite-space
coordinates. Maybe we'll cover that another time, this commit is
already large enough.
Part of P0111, funded by [Anonymous] and Blue Bolt.
ZUN might have gotten the impression that the EGC can *only* work with
multiples of 16 pixels per load or store? Which might explain why…
Part of P0102, funded by Yanga.
Which *looks* like a master.lib function, but only because ZUN adapted
his own micro-optimized super_roll_put_tiny() for 32×32. Good thing we
covered that one first!
Part of P0073, funded by [Anonymous] and -Tom-.
Which finally allows us to use the PLANE_SIZE macro in ASM land. Yeah,
(ROW_SIZE * RES_Y) has finally got old.
Part of P0073, funded by [Anonymous] and -Tom-.
Yes, when clipping the start and end points to the screen area, ZUN
uses an integer division to calculate the line slopes, rather than a
floating-point one. Doesn't seem like it actually causes any incorrect
lines to be drawn, though; that case is only hit in the Mima boss
fight, which draws a few lines with a bottom coordinate of 400 rather
than 399. It *might* also restore the wrong pixels at parts of the
YuugenMagan fight, causing weird flickering, but seriously, that's an
issue everywhere you look in this game.
Part of P0069, funded by [Anonymous] and Yanga.
I did consider not doing this, because "well, can't anyone who's
*actually* interested just diff the TH01 and TH02 implementations to
figure out the differences themselves", but that duplication ended up
feeling too filthy after all.
And hey, it's a nice excuse to update TH02's version to current naming
standards! 😛
Part of P0068, funded by Yanga.
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…
So yes, we *can* technically decompile from anywhere, by splitting the
segment after the function we want, then .SEQuentially GROUPing the two
segments back together into one virtual segment matching the original
one. This gives us one more point where we can slot in new compilation
units that emit their code into the same segment, in the order given on
the link command line.
*But* since all ASM in ReC98 heavily relies on being assembled in MASM
mode, we then start to suffer from MASM's group addressing quirk,
described in the "Accessing data in a segment belonging to a group"
section in the Turbo Assembler Version 5 User's Guide.
Which then forces us to manually prefix every single function call
• from inside the group
• to anywhere else within the newly created segment
with the group name. It's stupidly boring busywork, because of all the
function calls you *mustn't* prefix. Special tooling might make this
easier, but I don't have it, and I'm not getting crowdfunded for it.
And while this is faster than porting the entire codebase to Ideal
mode, I'll only do this on rare occasions.
Like the upcoming, particularly awful piece of reverse-engineering.
Completes P0031, funded by zorg.
These are used from quite a few places, so it seems best to just name
them after the rect on the playfield they leave out, which is then
typically where the background picture goes.
…*except* that in doing this, we quickly run up against the symbol
length limit of 32 characters. TASM can expand it via the /mv option,
but TCC only lets you *reduce* it to even less. (Why?)
So, my initial idea of `playfield_fill_around_(x)_(y)_(w)_(h)` wouldn't
have worked. But those coordinates are kinda important, I'd say…
Well then, let's just go with `fillm` instead of `fill_around` then.
"Fill with mask at the given coordinates"… yeah, that would work.
Part of P0029, funded by zorg.
With TH05 definitely being the Galaxy Brain version of this function.
You'll see once I get to push the C decompilation for that one…
Anyway, that covers all shared input functions of TH02-TH05!
Funded by zorg.
And renaming them all to the short filenames they will be decompiled to for
consistency. These functions aren't really immediately hardware-related, as
we've established earlier in the decompilation.