Commit Graph

181 Commits

Author SHA1 Message Date
nmlgc 34a5f4d183 [Decompilation] [th01] Boss entities: Unaligned 1-line blitting
"Oh wait, actually, I *do* want to blit 8 pixels at a time in some
cases" :zunpet:

First time in a long while that the VRAM access macros couldn't do the
job, because code generation wants *both* pointer arithmetic *and*
subscripts within the same expression.

But *come on*, just blit the 16 pixels for the byte-aligned case!

Part of P0107, funded by Yanga.
2020-08-12 17:51:42 +02:00
nmlgc 32c57c32e7 [Decompilation] [th01] Boss entities: Regular, byte-aligned blitting
That attempt at clipping the sprite at the left and right edges of
VRAM… is serviceable, I guess?

Part of P0107, funded by Yanga.
2020-08-12 17:51:42 +02:00
nmlgc 1f1829d2d8 [Decompilation] [th01] Boss entities: Copying .BOS metadata
So if the boss entity class stores all non-pixel metadata for its
associated .BOS file, how can YuugenMagan have 5 independent eye
sprites, or Kikuri have more than one soul and tear sprite?
By duplicating that data, of course!

Those structure copies to local variables seen in the load functions
of these bosses still remain pointless, though.

Completes P0106, funded by Yanga.
2020-08-12 17:51:40 +02:00
nmlgc 342e6450bc [Decompilation] [th01] Boss entities: .BOS load function
"Hm, I have this format that specifies sprite width in multiples of 8,
but *actually*, I'd like to blit 16 pixels at a time… well, time to
pepper the code with divisions and casts, I guess :zunpet:"

Which becomes even more hilarious once you realize that the `operator
new` function does require bytes after all. Which leads

	new dots16_t[image_size / 2];

to compile to

	operator new((image_size / 2) * 2);

:tannedcirno:

Part of P0106, funded by Yanga.
2020-08-12 17:49:35 +02:00
nmlgc 5f5eb8aa4e [Decompilation] [th01] .BOS: Unused and broken plane pointer reset function
Because that's not how you free dynamically allocated memory?

Part of P0106, funded by Yanga.
2020-08-12 17:49:34 +02:00
nmlgc 1a595cf60c [Reverse-engineering] [th01] Boss entity classes
What else to call something a boss can have multiple of, that may or
may not be part of a larger boss sprite, may or may not be animated,
and that may or may not have a orb hitbox?

Needed to be RE'd before the .BOS loading functions, because those are
actually methods of this class. And because renaming all these
variables in ASM land is tedious anyway, we might as well name each
individual entity of every boss.

Still, what's with the pointless local variable copies in the
YuugenMagan and Kikuri functions?

Part of P0106, funded by Yanga.
2020-08-12 17:49:34 +02:00
nmlgc 11b776b32e [Decompilation] [th01] 8×8 diamond, star, and snowflake sprite blitting
More hardcoded sprites! These are prominently seen in the Konngara,
Elis, and Sariel battles, respectively.

Completes P0105, funded by Yanga.
2020-08-12 16:24:04 +02:00
nmlgc 757f00e063 [Decompilation] [th01] Unaligned monochrome 8×8 sprite blitting
This is a perfectly fine generic sprite blitting function. Why doesn't
this game have more of these?

Part of P0105, funded by Yanga.
2020-08-12 16:21:28 +02:00
nmlgc 96e06fc746 [Decompilation] [th01] .GRC: Freeing images in a single slot
Part of P0105, funded by Yanga.
2020-08-12 16:20:54 +02:00
nmlgc 7ca525ba5c [Decompilation] [th01] .GRC: Byte-aligned blitting
And that's all? No unblitting or non-aligned functions? Oh well, at
least this one correctly clips the sprite at all 4 edges of VRAM, for
once.

Part of P0105, funded by Yanga.
2020-08-12 16:20:18 +02:00
nmlgc 72538610ba [Decompilation] [th01] .GRC: Load function
Still no idea what those 7 unknown bytes in the .GRC and .BOS headers
could be.

Part of P0105, funded by Yanga.
2020-08-12 16:19:39 +02:00
nmlgc b22bc80e98 [Reverse-engineering] [th01] .GRC: Slot structure
Part of P0105, funded by Yanga.
2020-08-12 16:17:58 +02:00
nmlgc bd1c2ee7de [Maintenance] #define the number of dots in a byte
One fewer magic number. And one more deliberate dependency on a
PC-98-specific hardware constant, to further drive home just how
unportable these games are, even once decompilation will be complete.

Part of P0105, funded by Yanga.
2020-08-12 16:16:58 +02:00
nmlgc 67d35115e6 [Maintenance] Use inline functions for all VRAM offset calculations
At least those can all be moved to a single place.

Part of P0105, funded by Yanga.
2020-08-12 16:16:18 +02:00
nmlgc a75e0f8f53 [Maintenance] Compile all VRAM-accessing translation units as C++
Leading to slight complications in TH02's Music Room and shot type
selection menus. Thought about leaving those in C for a while, but I
still think it's worth it for the consistency we get with the VRAM
offset functions. Also, we'll have similar code for the main menus of
later games, and I'll surely won't be using C++ when starting out with
these.

Part of P0105, funded by Yanga.
2020-08-12 16:16:09 +02:00
nmlgc 74b834fd7f [Maintenance] Use a distinct name for arc_file_get()'s sizeof() macro
We not only actually still need the (pointer, size) function to fill
heap-allocated memory, but we also need to differentiate between near
and far pointers, to move those pesky `PUSH DS` instructions to their
original places?!

Part of P0105, funded by Yanga.
2020-08-12 16:12:02 +02:00
nmlgc 3622eb6298 [Decompilation] [th01] HUD: Stage number rendering
Completes P0104, funded by Ember2528.
2020-07-27 17:23:06 +02:00
nmlgc 8367a41d46 [Maintenance] Decide on *_id for 0-based, and *_num for 1-based IDs
Which we've been already subconciously doing with the resident
`demo_num` variable.

Part of P0104, funded by Ember2528.
2020-07-27 17:22:28 +02:00
nmlgc afd74fb8aa [Decompilation] [th01] 16-bit integer to string conversion
"Hey, let's have separate functions for uint16_t and int16_t… and then
just *not* support negative numbers in the latter" :zunpet:

Part of P0104, funded by Ember2528.
2020-07-27 17:22:16 +02:00
nmlgc a0215ea85c [Decompilation] [th01] HUD: Life and bomb count rendering
If you've ever cheated more than 6 lives in TH01, you might have
noticed that those additional lives appear in additional rows in the
HUD. And well, that had to be coded somewhere…

Part of P0104, funded by Ember2528.
2020-07-27 17:20:29 +02:00
nmlgc e0bcdafb00 [Maintenance] [th01] Declare proper IDs for all .PTN sprites seen so far
Part of P0104, funded by Ember2528.
2020-07-27 17:19:48 +02:00
nmlgc f3093a802c [Decompilation] [th01] HUD: Inter-page row-sized rectangle blitting
Both inlined and non-inlined page switching within the same function,
together with an approach that doesn't correspond to our other planar
access macros? That code must have been written during a very
experimental phase very early in the development of this game.

Part of P0104, funded by Ember2528.
2020-07-27 17:19:12 +02:00
nmlgc edd9a14273 [Decompilation] [th01] HUD: Background (MASK.GRF) loading and rendering
Look, it's a memory leak!

Part of P0104, funded by Ember2528.
2020-07-27 17:17:59 +02:00
nmlgc 05c00287e9 [Decompilation] [th01] HUD: Initial score and card combo rendering
Hey look, this one *does* only render to a single page, and then blits
the area to the other one! Using an unnecessary new function that isn't
even EGC-accelerated…

Completes P0103, funded by Ember2528.
2020-07-27 17:17:22 +02:00
nmlgc b9038be04d [Decompilation] [th01] HUD: Current score and card combo rendering
Part of P0103, funded by Ember2528.
2020-07-27 17:13:35 +02:00
nmlgc b73762ba12 [Decompilation] [th01] HUD: Maximum card combo rendering
Nice and consistent…

Part of P0103, funded by Ember2528.
2020-07-27 17:12:21 +02:00
nmlgc f92c2a637c [Decompilation] [th01] HUD: High score update/render function
The scores are rendered to *both* VRAM pages…? Which means that we
need a separate set of sprites to store the background behind the
numbers. This does not bode well for animated backgrounds…

Part of P0103, funded by Ember2528.
2020-07-27 17:11:43 +02:00
nmlgc 57a2294f7a [Maintenance] Add a Planar<> template for any type of 4-plane value
Part of P0103, funded by Ember2528.
2020-07-27 17:10:00 +02:00
nmlgc 91ff008140 [Maintenance] Define the number of score digits in a consistent place
Even if that place is a one-line header file…?

Part of P0103, funded by Ember2528.
2020-07-27 17:09:07 +02:00
nmlgc b60f38d42d [Decompilation] [th01] Pellets: Delay cloud unblit/update/render function
And with that, we're actually *done* with TH01 pellets, and never have
to look at them again! 🎉

Completes P0102, funded by Yanga.
2020-07-12 16:45:53 +02:00
nmlgc dbc8da99d5 [Decompilation] [th01] Pellets: Player collision
How optimized is TH01? Well, since the player Y is constant, checking
for Y ≥ 368 first would rule out a collision for the majority of
entities during gameplay after just 1 check.

TH01 still checks X first.

Part of P0102, funded by Yanga.
2020-07-12 16:35:31 +02:00
nmlgc 5735c1622e [Decompilation] [th01] Pellets: Reset and decay functions
Or, in more relevant news: That's the function that forced TH01's
pellet sprites to be defined in C land. First sprite to make that jump.

Part of P0102, funded by Yanga.
2020-07-12 16:34:16 +02:00
nmlgc 63dafdb9c7 [Decompilation] [th01] Pellets: Unblit/update/render function
… pellet unblitting uses a *doubly* sloppy 16×8 rectangle. 🤦
The resulting terrible flickering is probably why the Stage 15 and 20
battles enable this weird "interlace" mode that only renders and
hit-tests half of the pellets each frame… except that player shots
are still hit-tested every frame?
So yeah, your eyes aren't deceiving you, the game does effectively drop
its perceived frame rate in the Elis, Kikuri, Sariel, and Konngara
fights, and it does so deliberately.

And *then* you realize that those weird hit tests are actually a
futile attempt to mitigate the disastrous effects of a way too large
unblitting rectangle. Congratulations, you've found the most stupid
piece of code in this game.

Part of P0102, funded by Yanga.
2020-07-12 16:29:51 +02:00
nmlgc d840841a2b [Naming] Rename egc_copy_rect_1_to_0() to emphasize its 16-dot alignment
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.
2020-07-12 16:27:56 +02:00
nmlgc edb70162e0 [Decompilation] [th01] Pellets: Manager class constructor
Note how Turbo C++ auto-generates that call to `operator new`, which
you don't see in the decompilation anymore. So yeah, as soon as you add
a constructor, Turbo C++ enforces heap allocation for any instance of
that class, even function-local ones that would otherwise be
stack-allocated.

That's where the bad reputation of C++ comes from, I guess?

Part of P0102, funded by Yanga.
2020-07-12 16:23:12 +02:00
nmlgc c11a95666b [Decompilation] [th01] Pellets: Shot/Orb/deflecting player collision
First off: 👏 Just 👏 pass 👏 a 👏 reference 👏 to 👏 the 👏
currently 👏 iterated 👏 pellet 👏 if 👏 you 👏 need 👏 to 👏
modify 👏 it 👏
Second: Don't we hit-test pellets vs. shots already, in the CShots
class? So what is this garbage…?!

Completes P0101, funded by Yanga and Ember2528.
2020-07-12 16:21:17 +02:00
nmlgc 8328905f46 [Decompilation] [th01] Pellets: Multi-pellet patterns
Actually quite cute with their hardcoded limitations, since the created
patterns do follow a clear logic.
But yeah, no 6-way spreads for you, we only support 2-, 3-, 4-, and
5-way ones here :zunpet:

Part of P0101, funded by Yanga and Ember2528.
2020-07-12 16:15:24 +02:00
nmlgc ceb81db49c [Decompilation] [th01] Pellets: Spawn functions
Completes P0100, funded by Yanga.
2020-07-12 16:14:01 +02:00
nmlgc 8f33b9717c [Decompilation] [th01] Pellets: Motion types
Look, an unused pellet motion type! Which doesn't work as intended
thanks to no fewer than 3 ZUN bugs in one single if() expression.

Part of P0100, funded by Yanga.
2020-07-12 16:13:33 +02:00
nmlgc 2fdaa35535 [Reverse-engineering] [th01] Pellets: Manager class
A 4227-byte structure, with 100 pellet_t instances followed by a few
other data members. A textbook example of why you can't just quickly
get full position independence by parsing individual lines of ASM.

Part of P0100, funded by Yanga.
2020-07-12 16:06:36 +02:00
nmlgc 1b25830786 [Reverse-engineering] [th01] Pellets: Single pellet structure
Completes P0099, funded by Ember2528.
2020-07-12 16:03:19 +02:00
nmlgc 2d0b4a5b06 [Maintenance] Add generic overlap test macros for collision detection
Part of P0099, funded by Ember2528.
2020-07-12 16:02:04 +02:00
nmlgc a207d6a494 [Decompilation] Add screen-space assignment overloads for Subpixels
Also great news for those people who want to remove any and all C++ in
their mods, because this forces us to spell out subpixel literals as
actual floats, every time. And with that, you're back to being able to
simply search-replace for all the instances you'll have to change.

Part of P0099, funded by Ember2528.
2020-07-12 16:00:59 +02:00
nmlgc f0baf27c04 [Reverse-engineering] [th01] REIIDEN.CFG variables in REIIDEN.EXE
Part of P0099, funded by Ember2528.
2020-07-12 16:00:09 +02:00
nmlgc e3a78bd19b [Maintenance] Fix vector creation function declarations and calls
Part of P0099, funded by Ember2528.
2020-07-12 15:22:50 +02:00
nmlgc 8f8940801d [Maintenance] Move the Subpixel class to TH01
At least pellets are moved at a decent precision in this game.

Part of P0099, funded by Ember2528.
2020-07-12 15:16:03 +02:00
nmlgc 3e3129567c [Decompilation] [th01] Pellet delay cloud blitting and unblitting
And immediately, we discover another two hardcoded sprites, with, of
course, another set of functions for blitting and unblitting them…

Part of P0099, funded by Ember2528.
2020-07-12 15:15:05 +02:00
nmlgc f612c40dce [Maintenance] Move generic VRAM macros from REIIDEN.EXE's PTN code to planar.h
C++ templates would be *so nice* here, but code generation… 😢

Part of P0099, funded by Ember2528.
2020-07-12 15:08:38 +02:00
nmlgc 1799d67782 [Build] Convert all known hardcoded sprites during the 32-bit build part
You can now mod them by simply editing .BMP files!
2020-07-09 22:28:15 +02:00
nmlgc f03f43db3a [Regression] Fix conditional branches in CShots::hittest_pellet()
1 wrong byte of ASM that slipped through due to a off-by-one error in
an experimental mzdiff branch. Having MOV rather than LES here was
ultimately a harmless mistake though. In context, it's even covered by
the "identical instruction encoding" exception 🙂
2020-06-25 17:37:39 +02:00