[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.
This commit is contained in:
nmlgc 2020-07-30 20:46:00 +02:00
parent b22bc80e98
commit 72538610ba
8 changed files with 123 additions and 141 deletions

View File

@ -59,7 +59,7 @@ bin\th01\op.exe: bin\piloadc.obj bin\th01\op.obj th01\op_01.cpp th01\op_02.c th0
$**
|
bin\th01\reiiden.exe: bin\piloadc.obj bin\th01\reiiden.obj th01\main_01.cpp th01\main_01_.cpp th01\main_02.c th01\main_03.c th01\main_04.c th01\main_05.c th01\main_06.cpp th01\main_07.cpp th01\main_08.cpp th01\main_09.cpp th01\main_12.c th01\main_13.cpp th01\main_13_.cpp th01\main_14.cpp th01\main_16.c th01\main_19.cpp th01\main_25.cpp th01\main_27.cpp th01\main_30.cpp th01\main_38.cpp
bin\th01\reiiden.exe: bin\piloadc.obj bin\th01\reiiden.obj th01\main_01.cpp th01\main_01_.cpp th01\main_02.c th01\main_03.c th01\main_04.c th01\main_05.c th01\main_06.cpp th01\main_07.cpp th01\main_08.cpp th01\main_09.cpp th01\main_12.c th01\main_13.cpp th01\main_13_.cpp th01\main_14.cpp th01\main_16.c th01\main_19.cpp th01\main_23.cpp th01\main_25.cpp th01\main_27.cpp th01\main_30.cpp th01\main_38.cpp
$(CC) $(CFLAGS) -ml -3 -DGAME=1 -DBINARY='M' -nbin\th01\ -eREIIDEN.EXE @&&|
$**
|

View File

@ -110,6 +110,29 @@ as part of the same translation unit. Found nothing so far, though.
Borland C++ just pushes the entire word. Will cause IDA to mis-identify
certain local variables as `word`s when they aren't.
### Pushing pointers
When passing a `near` pointer to a function that takes a `far` one, the
segment argument is sometimes `PUSH`ed immediately, before evaluating the
offset:
```c++
#pragma option -ml
struct s100 {
char c[100];
};
extern s100 structs[5];
void __cdecl process(s100 *element);
void foo(int i) {
process((s100 near *)(&structs[i])); // PUSH DS; (AX = offset); PUSH AX;
process((s100 far *)(&structs[i])); // (AX = offset); PUSH DS; PUSH AX;
}
```
## Flags
### `-Z` (Suppress register reloads)

43
th01/formats/grc.cpp Normal file
View File

@ -0,0 +1,43 @@
#include <stddef.h>
#include "platform.h"
#include "pc98.h"
#include "planar.h"
#include "th01/formats/pf.hpp"
#include "th01/formats/grc.hpp"
int grc_load(int slot, const char fn[PF_FN_LEN])
{
union {
spriteformat_header_inner_t inner;
Palette4 pal;
int8_t space[50];
} header;
arc_file_load(fn);
arc_file_seek(offsetof(grc_header_t, vram_w));
arc_file_get_near(grc_images[slot].vram_w);
arc_file_get_near(grc_images[slot].h);
arc_file_get_far(header.inner);
grc_images[slot].image_count = header.inner.image_count;
// MODDERS:
/* if(
header.inner.image_count < 0 ||
header.inner.image_count > GRC_IMAGES_PER_SLOT
) {
return 1;
} */
size_t image_size = (grc_images[slot].vram_w * grc_images[slot].h);
arc_file_get_far(header.pal); // yeah, should have been a seek
for(int image = 0; grc_images[slot].image_count > image; image++) {
if(grc_images[slot].dots[image]) {
delete[] grc_images[slot].dots[image];
}
grc_images[slot].dots[image] = new dots8_t[image_size];
arc_file_get(grc_images[slot].dots[image], image_size);
}
arc_file_free();
return 0;
}

View File

@ -1,5 +1,17 @@
/// Uncompressed monochrome 8w×h sprite format
/// ------------------------------------------
#include "th01/formats/sprfmt_h.hpp"
#define GRC_MAGIC "GRCG"
// On-disk per-file header. Not the same as for .BOS!
struct grc_header_t {
char magic[sizeof(GRC_MAGIC) - 1];
int16_t vram_w;
int16_t h;
spriteformat_header_inner_t inner;
};
static const int GRC_SLOT_COUNT = 8;
static const int GRC_IMAGES_PER_SLOT = 8;
@ -12,4 +24,8 @@ struct grc_t {
};
extern grc_t grc_images[GRC_SLOT_COUNT];
// Loads all images from the .GRC file with the given [fn] inside the
// currently active packfile into the given .GRC [slot]. Always returns 0.
int grc_load(int slot, const char fn[PF_FN_LEN]);
/// ------------------------------------------

View File

@ -20,6 +20,9 @@ void pascal arc_file_load(const char fn[PF_FN_LEN]);
// into [buf], advancing the cursor in the process.
void pascal arc_file_get(char *buf, size_t size);
#define arc_file_get_near(var) \
arc_file_get(reinterpret_cast<char near *>(&var), sizeof(var))
#define arc_file_get_far(var) \
arc_file_get(reinterpret_cast<char far *>(&var), sizeof(var))

13
th01/formats/sprfmt_h.hpp Normal file
View File

@ -0,0 +1,13 @@
// Header structures for multi-sprite formats. Used for .BOS and .GRC.
#pragma pack(push, 1)
struct spriteformat_header_inner_t {
uint8_t image_count;
int8_t unknown[7];
};
// For reference, never actually used by the game itself (unfortunately).
template <class Outer> struct spriteformat_header_t {
Outer outer;
Palette4 pal;
};
#pragma pack(pop)

10
th01/main_23.cpp Normal file
View File

@ -0,0 +1,10 @@
/* ReC98
* -----
* Code segment #23 of TH01's REIIDEN.EXE
*/
#pragma option -3 -Z
extern "C" {
#include "th01/formats/grc.cpp"
}

View File

@ -73,6 +73,7 @@ BOMBS_MAX = 5
main_01 group main_01_TEXT, main_01__TEXT, main_01___TEXT
main_13 group main_13_TEXT, main_13__TEXT
main_19 group main_19_TEXT, main_19__TEXT
main_23 group main_23_TEXT, main_23__TEXT
main_25 group main_25_TEXT, main_25__TEXT
main_27 group main_27_TEXT, main_27__TEXT
main_30 group main_30_TEXT, main_30__TEXT
@ -912,14 +913,8 @@ sub_BCFE endp
sub_BEB1 proc far
push bp
mov bp, sp
push ds
push offset aKuzi1_grc ; "kuzi1.grc"
push 6
call sub_1744B
push ds
push offset aKuzi2_grc ; "kuzi2.grc"
push 7
call sub_1744B
call _grc_load stdcall, 6, offset aKuzi1_grc, ds
call _grc_load stdcall, 7, offset aKuzi2_grc, ds
add sp, 0Ch
pop bp
retf
@ -12018,120 +12013,14 @@ main_22_TEXT ends
; Segment type: Pure code
main_23_TEXT segment byte public 'CODE' use16
assume cs:main_23_TEXT
extern _grc_load:proc
main_23_TEXT ends
main_23__TEXT segment byte public 'CODE' use16
assume cs:main_23
;org 0Bh
assume es:nothing, ss:nothing, ds:_DATA, fs:nothing, gs:nothing
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_1744B proc far
var_36 = byte ptr -36h
var_4 = word ptr -4
var_2 = word ptr -2
arg_0 = word ptr 6
@@fn = dword ptr 8
enter 36h, 0
push si
push di
mov di, [bp+arg_0]
call arc_file_load pascal, large [bp+@@fn]
call arc_file_seek pascal, 4
push ds
mov ax, di
imul ax, size grc_t
add ax, offset _grc_images.GRC_vram_w
push ax
push 2
call arc_file_get
push ds
mov ax, di
imul ax, size grc_t
add ax, offset _grc_images.GRC_h
push ax
push 2
call arc_file_get
push ss
lea ax, [bp+var_36]
push ax
push 8
call arc_file_get
mov al, [bp+var_36]
mov ah, 0
mov bx, di
imul bx, size grc_t
mov _grc_images[bx].GRC_image_count, ax
mov bx, di
imul bx, size grc_t
mov ax, _grc_images[bx].GRC_vram_w
mov bx, di
imul bx, size grc_t
imul _grc_images[bx].GRC_h
mov [bp+var_2], ax
push ss
lea ax, [bp+var_36]
push ax
push size palette_t
call arc_file_get
mov [bp+var_4], 0
jmp short loc_17534
; ---------------------------------------------------------------------------
loc_174C8:
mov bx, di
imul bx, size grc_t
mov ax, [bp+var_4]
shl ax, 2
add bx, ax
mov ax, word ptr _grc_images.GRC_dots[bx]+0
or ax, word ptr _grc_images.GRC_dots[bx]+2
jz short loc_174F9
mov bx, di
imul bx, size grc_t
mov ax, [bp+var_4]
shl ax, 2
add bx, ax
pushd _grc_images.GRC_dots[bx] ; font
call @$bdla$qnv
add sp, 4
loc_174F9:
push [bp+var_2]
call @$bnwa$qui
pop cx
mov bx, di
imul bx, size grc_t
mov si, [bp+var_4]
shl si, 2
add bx, si
mov word ptr _grc_images.GRC_dots[bx]+2, dx
mov word ptr _grc_images.GRC_dots[bx]+0, ax
mov bx, di
imul bx, size grc_t
mov ax, [bp+var_4]
shl ax, 2
add bx, ax
call arc_file_get pascal, large _grc_images.GRC_dots[bx], [bp+var_2]
inc [bp+var_4]
loc_17534:
mov bx, di
imul bx, size grc_t
mov ax, _grc_images[bx].GRC_image_count
cmp ax, [bp+var_4]
jg short loc_174C8
call arc_file_free
xor ax, ax
pop di
pop si
leave
retf
sub_1744B endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
@ -13154,7 +13043,7 @@ loc_17CA3:
retf
sub_17C2F endp
main_23_TEXT ends
main_23__TEXT ends
; ===========================================================================
@ -34744,10 +34633,7 @@ sub_24F41 proc far
push offset point_3988E
call sub_1568F
mov word_398B8, 0
push ds
push offset aBoss5_gr_grc ; "boss5_gr.grc"
push 0
call sub_1744B
call _grc_load stdcall, 0, offset aBoss5_gr_grc, ds
call _ptn_new stdcall, (12 shl 16) or 2
call _ptn_load stdcall, 3, offset aBoss3_m_ptn_1, ds ; "boss3_m.ptn"
mov byte_3A1B2, 0C0h ; '?'
@ -40657,23 +40543,11 @@ sub_28754 proc far
push ds
push offset word_39A1E
call sub_16B56
push ds
push offset aBoss6gr1_grc ; "boss6gr1.grc"
push 0
call sub_1744B
push ds
push offset aBoss6gr2_grc ; "boss6gr2.grc"
push 1
call sub_1744B
push ds
push offset aBoss6gr3_grc ; "boss6gr3.grc"
push 2
call sub_1744B
call _grc_load stdcall, 0, offset aBoss6gr1_grc, ds
call _grc_load stdcall, 1, offset aBoss6gr2_grc, ds
call _grc_load stdcall, 2, offset aBoss6gr3_grc, ds
add sp, 30h
push ds
push offset aBoss6gr4_grc ; "boss6gr4.grc"
push 3
call sub_1744B
call _grc_load stdcall, 3, offset aBoss6gr4_grc, ds
call sub_232A4
nopcall sub_287D9
call _ptn_new stdcall, (16 shl 16) or 2