• Comments that describe all lines of code until a blank one are placed
into the lines immediately above
• Comments that describe an entire demarcated block are placed
immediately below the dash row at the top
• In any case, there should be a blank line after the top comment of
a demarcated block, to keep IntelliSense-style systems from applying
the block comment to the first actual line of code…
• …but there shouldn't be one before the dash row at the bottom, where
it'd be redundant.
Part of P0207, funded by GhostPhanom.
Brought to you by diagonal movement and the combined effect of 4 ZUN
bugs. Most commonly reported for Elis and Mima.
Part of P0197, funded by Yanga and Ember2528.
These could have been nicely separated into per-device translations
(one for GDC, one for EGC, one for regular VRAM accesses)… if their
original order followed that classification.
OK, so let's make it one full `graph_ex.cpp` translation unit… nope,
FUUIN.EXE needs graph_2xscale_byterect_1_to_0_slow() with different
compilation flags. 🤦
Whatever, fuck it, let's go for individual translation units, with
individual headers, so that we at least get predictably organized
source code out of this.
Part of P0196, funded by Yanga.
TDW and TCR modes share the same bit in the GRCG mode register and are
thus indistinguishable when looking at a disassembly, but only apply to
writing (TDW) or reading (TCR), respectively. TH01 only performs read
operations in this mode, so it's unambiguously TCR.
Part of P0176, funded by Ember2528.
TH01 doesn't use "back" and "front" pages in the way the later games
do, after all. Indicating that the source page of this parameter-less
function is the one that was previously set via graph_accesspage_func()
is going to make pretty much all its call sites way clearer, and stops
implying any further state.
Part of P0167, funded by Ember2528.
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.
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.
Wait, so if this is only used for the rotating white squares around
Mima, that must mean that the white star in the YuugenMagan fight got a
completely redundant reimplementation…
Part of P0121, funded by Yanga.
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.
I tried `brge` for the latter, but that had *the* most horrible
ergonomics, and I misspelled it as `bgre` 100% of the times I typed it
manually. Turns out that `dots` is also consistent with master.lib's
naming scheme, leaving `planar` to *actually* refer to types storing
multiple planes worth of pixels. These types are showing up more and
more, and deserve something better than their previous long-winded and
misleading name.
Part of P0081, funded by Ember2528.
Just like with the z_text_*() functions, master.lib doesn't already
have graph_init() and graph_exit() either, and once again, ZUN's code
here doesn't fully correspond to any master.lib function. Unlike the
z_text_*() functions though, those names aren't really the best
descriptions for these rather random combinations of BIOS calls and I/O
port writes…
Anyway, that's the entire segment!
Part of P0080, funded by Ember2528 and Splashman.
Page… 2? On a system with only page 0 and 1? Had to get out my real
PC-98 to double-check that I wasn't missing anything here, since
every emulator only looks at the bottom bit of the page number. But
real hardware seems to do the same, and there really is nothing special
to it semantically, being equivalent to page 0. 🤷
Part of P0080, funded by Ember2528 and Splashman.
In which our typedefs mercilessly reveal ZUN's original sloppiness, and
the unncessary sign extension taking place here. Also, ❎ unused…
Completes P0069, funded by [Anonymous] and Yanga.
TH01's (original) version also replicates the PC-98 text RAM's reverse
and underline attributes. Which was removed in later games,
interestingly and inconsistently enough.
Part of P0068, funded by Yanga.
Including the longest function present in more than one game among all
of PC-98 Touhou, and #23 on the list of longest functions overall,
which draws a 1-pixel line between two arbitrary pixels.
Completes P0067, funded by Splashman.
Semi-unused, that is, the one use of this function doesn't actually
move the rectangle to a different position. Ironically, the non-moving
back-to-front function immediately above *is* unused…
Also, too bad that stack order is the only reason we can't use structs
to combine all plane variables into a single object.
Part of P0067, funded by Splashman.