Skip to content

Commit

Permalink
[Decompilation] [th03] .MRS: Slot freeing function
Browse files Browse the repository at this point in the history
How can you mess up *a freeing function* that badly?! In your third
game?!

Part of P0127, funded by [Anonymous].
  • Loading branch information
nmlgc committed Nov 16, 2020
1 parent 00e65f4 commit 1fe9863
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 36 deletions.
29 changes: 27 additions & 2 deletions th03/formats/mrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,15 @@ extern mrs_t far *mrs_images[MRS_SLOT_COUNT];
// Decompilation workarounds
// -------------------------

#define mrs_slot_offset_to(var, slot) { \
var = slot; \
var <<= 2; \
}

// Points [reg_sgm]:[reg_off] to the alpha plane of the .MRS image in the
// given [slot].
#define mrs_slot_assign(reg_sgm, reg_off, slot) { \
_BX = slot; \
_BX <<= 2; \
mrs_slot_offset_to(_BX, slot); \
__asm { l##reg_sgm reg_off, mrs_images[bx]; } \
}

Expand Down Expand Up @@ -86,6 +90,27 @@ struct mrs_at_B_t : public mrs_plane_t {
};
// -------------------------

void pascal mrs_free(int slot)
{
#define mrs_image_pointer_word(slot_offset, off_or_sgm) \
*(reinterpret_cast<uint16_t near *>( \
reinterpret_cast<uint16_t>(mrs_images) + slot_offset \
) + off_or_sgm)
mrs_slot_offset_to(_BX, slot);
_AX = mrs_image_pointer_word(_BX, 1);
// Yes, |=, not =, to an uninitialized register. The entire reason why we
// can't decompile this into one sane expression...
_DX |= mrs_image_pointer_word(_BX, 0);
_DX |= _AX;
if(!FLAGS_ZERO) {
hmem_free(_AX);
mrs_image_pointer_word(_BX, 0) = mrs_image_pointer_word(_BX, 1) = NULL;
}
#undef mrs_image_pointer_word
}

#pragma codestring "\x90"

inline uint16_t to_bottom_left_8(const screen_x_t &left) {
return ((left >> 3) + ((MRS_H - 1) * ROW_SIZE));
}
Expand Down
3 changes: 3 additions & 0 deletions th03/formats/mrs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ static const int MRS_SLOT_COUNT = 8;
static const pixel_t MRS_W = 288;
static const pixel_t MRS_H = 184;

// Frees the .MRS image in the given [slot].
void pascal mrs_free(int slot);

// Displays the .MRS image in the given [slot] at (⌊left/8⌋*8, top).
void pascal mrs_put_8(screen_x_t left, uscreen_y_t top, int slot);

Expand Down
37 changes: 3 additions & 34 deletions th03_main.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2399,10 +2399,8 @@ _arg0 = dword ptr 6
call graph_hide
call text_clear
call gaiji_restore
push 0
call sub_EF1C
push 1
call sub_EF1C
call @mrs_free$qi pascal, 0
call @mrs_free$qi pascal, 1
call _game_exit
pushd 0
pushd [bp+_arg0] ; arg0
Expand Down Expand Up @@ -8933,36 +8931,7 @@ arg_4 = word ptr 0Ah
retf 6
sub_EEE2 endp


; =============== S U B R O U T I N E =======================================

; Attributes: bp-based frame

sub_EF1C proc far

arg_0 = word ptr 6

push bp
mov bp, sp
mov bx, [bp+arg_0]
shl bx, 2
mov ax, word ptr (_mrs_images[bx] + 2)
or dx, word ptr (_mrs_images[bx] + 0)
or dx, ax
jz short loc_EF41
push ax
call hmem_free
xor ax, ax
mov word ptr (_mrs_images[bx] + 2), ax
mov word ptr (_mrs_images[bx] + 0), ax

loc_EF41:
pop bp
retf 2
sub_EF1C endp

; ---------------------------------------------------------------------------
nop
extern @MRS_FREE$QI:proc
extern @MRS_PUT_8$QIUII:proc
extern @MRS_PUT_NOALPHA_8$QIUIIC:proc
extern @MRS_HFLIP$QI:proc
Expand Down

0 comments on commit 1fe9863

Please sign in to comment.