Another function consisting almost entirely of inline ASM. Still worth
it though, if only to save us from duplicating any declarations in ASM
land.
Part of P0126, funded by [Anonymous] and Blue Bolt.
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.
With a type-safe wrapper template that removes the need for ID length
and structure-size-in-paragraphs macros. *And* <dos.h>!
Part of P0126, funded by [Anonymous] and Blue Bolt.
Rather than preferring either the Microsoft/Watcom `(in|out)pw?` style,
or the Borland `(in|out)portb?` style, master.lib had to introduce its
own `(OUT|IN)P[BW]` naming scheme… Insert obligatory xkcd standards
comic.
Part of P0126, funded by [Anonymous] and Blue Bolt.
Which gets rid of 13 redundant translation units. Definitely a good
start, before I figure out how to best handle the more complicated
cases.
(Maintenance mode commit)
Not really surprising why this works, and probably was how the original
code looked all along: The function is never called from anywhere, and
as long as the next function still lies on the same 16-byte paragraph,
it makes no difference whether the unused one is placed at the end of
the previous segment, or the beginning of the next.
Which means we can choose whatever leads to fewer translation units 👍
(Maintenance mode commit)
There's the better name, in ALLCAPS for improved grepping. TH01 is also
going to need a pseudo-binary to bundle translation units that appear
in more than one .EXE, and since "segment 2" would be wrong for that
game, it makes more sense to have one consistent name for these
pseudo-binaries in all games.
(Maintenance mode commit)
Yup, no trick there. If the selection moves to the other character, the
original background behind the raised top and left edges has to be
blitted back to VRAM, which means that it also has to be stored
somewhere. TH04 backs up exactly the two 256×8 and 8×244 strips behind
Reimu and Marisa, requiring 2 KB of heap memory, whereas TH05 simply
gave up, and backs up the entire 640×400 screen, totalling 128 KB.
Part of P0125, funded by [Anonymous].
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 change of pi_free() from a macro to a function in TH05 doesn't
require a complete redefinition.
Part of P0124, funded by [Anonymous] and Blue Bolt.
6149 LoC with the original master.h, vs. 2524 LoC *and* additional
semantic sugar with master.hpp. Nice!
(Yes, *semantic* sugar.)
Part of P0124, funded by [Anonymous] and Blue Bolt.
Since we can't even change whitespace inside a preprocessor macro
without getting a `redefinition is not identical` warning, these have
to be wrapped in `#if !defined(__MASTER_H)` blocks for now.
Part of P0124, funded by [Anonymous] and Blue Bolt.
And no longer force translation units that access the resident
structure into #including that mistake that was ReC98.h.
Part of P0124, funded by [Anonymous] and Blue Bolt.
The regular master.h is big, uncomfortable in C++ mode, and bloated
with all those portability `#define`s that effectively only cover a
small portion of the PC-98-specific code anyway. So, let's gradually
transition to a new smaller header that is more integrated into the
ReC98 codebase, by simply no longer #including `master.h` in new code.
Which also explains its weird place in the root directory. Even though
`libs/master.lib/` contains plenty of game-specific modifications, it
didn't feel right to have anything in this directory refer to types
from `pc98.h`.
Part of P0124, funded by [Anonymous] and Blue Bolt.
*Still* no need for the classic `if(ptr) { delete[] ptr; ptr = NULL }`
macro, because who cares about dangling pointers anyway, right?
:zunpet:
Part of P0123, funded by Yanga.
All this CPU time spent optimizing the unblitting mask, yet the code
still ends up glitching if the two sprites are more than 2 horizontal
bytes away. So, Reimu's slide speed can only be as high as 8 pixels per
frame, before this function fails to unblit the previous sprite and
leaves little Reimu parts in VRAM.
Part of P0123, funded by Yanga.
"Let's add a row to the offset, and then subtract it again" :zunpet:
This could only *possibly* have been intended as a DoS attack against a
future manual decompilation, right?
Part of P0123, funded by Yanga.
Two ZUN bugs in a single function call! These end up causing
effectively random sprite pixels to disappear during the transition to
the boss clear tally screen, if the boss was killed while any shootout
lasers were on screen. And once again, one of those bugs would have
been a non-issue with strong enough typing…
Oh well, that's all there is to this class.
Completes P0122, funded by Yanga.
Not to be confused with stationary lasers (as used by YuugenMagan, for
example), which are just regular lines with collision detection. 🥴
Also, 22 unused bytes out of 69, with another 11 that could have easily
been exchanged for better code…
Part of P0122, funded by Yanga.
First ZUN bug in sprite preshifting! One wrongly shifted pixel means
that we can't use the auto-preshift feature of our sprite converter -.-
Also, why did these even have to be hardcoded sprites to begin with.
These dot patterns could have been easily generated procedurally… but
even *that* wouldn't have been necessary, given that there's this nice
function called, uh, graph_r_line_patterned()? Which could have
rendered all of the lasers in the upcoming class and more?
Part of P0122, funded by Yanga.
Originally just a workaround to remove angles from the PI counter, but
having the sign indicate the Y direction also makes them a lot nicer to
read in C land.
(Maintenance mode commit)