mirror of https://github.com/nmlgc/ReC98.git
[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.
This commit is contained in:
parent
c11a95666b
commit
edb70162e0
|
@ -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_38.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_25.cpp th01\main_27.cpp th01\main_38.cpp
|
||||||
$(CC) $(CFLAGS) -ml -3 -DGAME=1 -DBINARY='M' -nbin\th01\ -eREIIDEN.EXE @&&|
|
$(CC) $(CFLAGS) -ml -3 -DGAME=1 -DBINARY='M' -nbin\th01\ -eREIIDEN.EXE @&&|
|
||||||
$**
|
$**
|
||||||
|
|
|
|
||||||
|
|
|
@ -269,6 +269,50 @@ Examples:
|
||||||
**Certainty**: Maybe Borland (not Turbo) C++ has an optimization option
|
**Certainty**: Maybe Borland (not Turbo) C++ has an optimization option
|
||||||
against it?
|
against it?
|
||||||
|
|
||||||
|
### Boilerplate for constructors defined outside the class declaration
|
||||||
|
|
||||||
|
```c++
|
||||||
|
struct MyClass {
|
||||||
|
// Members…
|
||||||
|
|
||||||
|
MyClass();
|
||||||
|
};
|
||||||
|
|
||||||
|
MyClass::MyClass() {
|
||||||
|
// Initialization…
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Resulting ASM:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
; MyClass::MyClass(MyClass* this)
|
||||||
|
; Exact instructions differ depending on the memory model. Model-independent
|
||||||
|
; ASM instructions are in UPPERCASE.
|
||||||
|
@MyClass@$bctr$qv proc
|
||||||
|
PUSH BP
|
||||||
|
MOV BP, SP
|
||||||
|
; (saving SI and DI, if used in constructor code)
|
||||||
|
; (if this, 0)
|
||||||
|
JNZ @@ctor_code
|
||||||
|
PUSH sizeof(MyClass)
|
||||||
|
CALL @$bnew$qui ; operator new(uint)
|
||||||
|
POP CX
|
||||||
|
; (this = value_returned_from_new)
|
||||||
|
; (if this)
|
||||||
|
JZ @@ret
|
||||||
|
|
||||||
|
@@ctor_code:
|
||||||
|
; Initialization…
|
||||||
|
|
||||||
|
@@ret:
|
||||||
|
; (retval = this)
|
||||||
|
; (restoring DI and SI, if used in constructor code)
|
||||||
|
POP BP
|
||||||
|
RET
|
||||||
|
@MyClass@$bctr$qv endp
|
||||||
|
```
|
||||||
|
|
||||||
## Limits of decompilability
|
## Limits of decompilability
|
||||||
|
|
||||||
### `MOV BX, SP`-style functions, or others with no standard stack frame
|
### `MOV BX, SP`-style functions, or others with no standard stack frame
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
#include "th01/math/subpixel.hpp"
|
|
||||||
#include "th01/math/vector.hpp"
|
|
||||||
#include "th01/main/vars.hpp"
|
|
||||||
#include "th01/main/bullet/pellet.hpp"
|
|
||||||
#include "th01/main/playfld.hpp"
|
|
||||||
#include "th01/main/player/orb.hpp"
|
|
||||||
#include "th01/main/player/player.hpp"
|
|
||||||
#include "th01/main/player/shots.hpp"
|
|
||||||
|
|
||||||
/// Constants
|
/// Constants
|
||||||
/// ---------
|
/// ---------
|
||||||
// Can't declare these as `static const` variables, because that would break
|
// Can't declare these as `static const` variables, because that would break
|
||||||
|
@ -25,6 +16,24 @@ static const unsigned int PELLET_DESTROY_SCORE = 10;
|
||||||
pellet_t near *pellet_cur;
|
pellet_t near *pellet_cur;
|
||||||
/// -------
|
/// -------
|
||||||
|
|
||||||
|
CPellets::CPellets(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#define p pellet_cur
|
||||||
|
p = iteration_start();
|
||||||
|
for(i = 0; i < PELLET_COUNT; i++, p++) {
|
||||||
|
p->moving = false;
|
||||||
|
p->not_rendered = false;
|
||||||
|
}
|
||||||
|
#undef p
|
||||||
|
|
||||||
|
alive_count = 0;
|
||||||
|
for(i = 0; i < sizeof(unknown_zero) / sizeof(unknown_zero[0]); i++) {
|
||||||
|
unknown_zero[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void vector2_to_player_from(
|
void vector2_to_player_from(
|
||||||
int x, int y, int &ret_x, int &ret_y, int length, unsigned char plus_angle
|
int x, int y, int &ret_x, int &ret_y, int length, unsigned char plus_angle
|
||||||
)
|
)
|
||||||
|
|
|
@ -168,6 +168,8 @@ protected:
|
||||||
bool16 visible_after_hittests_for_cur(int pellet_left, int pellet_top);
|
bool16 visible_after_hittests_for_cur(int pellet_left, int pellet_top);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
CPellets(void);
|
||||||
|
|
||||||
// Spawns a number of bullets according to the given [pattern], with their
|
// Spawns a number of bullets according to the given [pattern], with their
|
||||||
// corresponding velocities, at (left, top). [speed_base] is tuned
|
// corresponding velocities, at (left, top). [speed_base] is tuned
|
||||||
// according to the currently played difficulty and the resident
|
// according to the currently played difficulty and the resident
|
||||||
|
|
|
@ -1,11 +1,3 @@
|
||||||
#include "th01/snd/mdrv2.h"
|
|
||||||
#include "th01/formats/ptn.hpp"
|
|
||||||
#include "th01/hardware/egc.h"
|
|
||||||
#include "th01/main/playfld.hpp"
|
|
||||||
#include "th01/main/player/player.hpp"
|
|
||||||
#include "th01/main/player/orb.hpp"
|
|
||||||
#include "th01/main/player/shots.hpp"
|
|
||||||
|
|
||||||
static const int SHOT_SPRITE_MARGIN = 2;
|
static const int SHOT_SPRITE_MARGIN = 2;
|
||||||
static const int SHOT_DECAY_FRAMES = 7;
|
static const int SHOT_DECAY_FRAMES = 7;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,26 @@
|
||||||
/* ReC98
|
/* ReC98
|
||||||
* -----
|
* -----
|
||||||
* 1st part of code segment #38 of TH01's REIIDEN.EXE
|
* Code segment #38 of TH01's REIIDEN.EXE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma option -Z
|
#pragma option -Z
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "platform.h"
|
#include "th01/th01.h"
|
||||||
#include "pc98.h"
|
#include "th01/ranks.h"
|
||||||
#include "planar.h"
|
#include "th01/snd/mdrv2.h"
|
||||||
|
#include "th01/formats/ptn.hpp"
|
||||||
|
#include "th01/hardware/egc.h"
|
||||||
#include "th01/math/subpixel.hpp"
|
#include "th01/math/subpixel.hpp"
|
||||||
|
#include "th01/math/vector.hpp"
|
||||||
|
#include "th01/main/vars.hpp"
|
||||||
|
#include "th01/main/playfld.hpp"
|
||||||
|
#include "th01/main/player/player.hpp"
|
||||||
|
#include "th01/main/player/orb.hpp"
|
||||||
|
#include "th01/main/bullet/pellet.hpp"
|
||||||
|
#include "th01/main/player/shots.hpp"
|
||||||
|
|
||||||
#include "th01/main/player/shots.cpp"
|
#include "th01/main/player/shots.cpp"
|
||||||
|
#include "th01/main/bullet/pellet.cpp"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/* ReC98
|
|
||||||
* -----
|
|
||||||
* 2nd part of code segment #38 of TH01's REIIDEN.EXE
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma codeseg main_38__TEXT main_38
|
|
||||||
#pragma option -Z
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "th01/th01.h"
|
|
||||||
#include "th01/ranks.h"
|
|
||||||
|
|
||||||
#include "th01/main/bullet/pellet.cpp"
|
|
||||||
|
|
||||||
}
|
|
|
@ -73,7 +73,7 @@ main_13 group main_13_TEXT, main_13__TEXT
|
||||||
main_19 group main_19_TEXT, main_19__TEXT
|
main_19 group main_19_TEXT, main_19__TEXT
|
||||||
main_25 group main_25_TEXT, main_25__TEXT
|
main_25 group main_25_TEXT, main_25__TEXT
|
||||||
main_27 group main_27_TEXT, main_27__TEXT
|
main_27 group main_27_TEXT, main_27__TEXT
|
||||||
main_38 group main_38_TEXT, main_38__TEXT, main_38___TEXT
|
main_38 group main_38_TEXT, main_38__TEXT
|
||||||
|
|
||||||
; ===========================================================================
|
; ===========================================================================
|
||||||
|
|
||||||
|
@ -4483,7 +4483,7 @@ word_E309 dw 4, 9, 0Eh, 13h
|
||||||
sub_E319 proc far
|
sub_E319 proc far
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
call sub_30047 c, offset _Pellets, ds
|
call @CPellets@$bctr$qv c, offset _Pellets, ds
|
||||||
mov _Shots.SHOT_unknown[0 * word], 50h
|
mov _Shots.SHOT_unknown[0 * word], 50h
|
||||||
mov _Shots.SHOT_unknown[1 * word], 60h
|
mov _Shots.SHOT_unknown[1 * word], 60h
|
||||||
mov _Shots.SHOT_unknown[2 * word], 70h
|
mov _Shots.SHOT_unknown[2 * word], 70h
|
||||||
|
@ -53930,90 +53930,22 @@ main_37_TEXT ends
|
||||||
|
|
||||||
; Segment type: Pure code
|
; Segment type: Pure code
|
||||||
main_38_TEXT segment byte public 'CODE' use16
|
main_38_TEXT segment byte public 'CODE' use16
|
||||||
main_38_TEXT ends
|
|
||||||
|
|
||||||
main_38__TEXT segment byte public 'CODE' use16
|
|
||||||
assume cs:main_38
|
|
||||||
;org 4
|
|
||||||
assume es:nothing, ss:nothing, ds:_DATA, fs:nothing, gs:nothing
|
|
||||||
|
|
||||||
extern @CShots@add$qii:proc
|
extern @CShots@add$qii:proc
|
||||||
extern @CShots@unput_and_reset_all$qv:proc
|
extern @CShots@unput_and_reset_all$qv:proc
|
||||||
extern @CShots@unput_update_render$qv:proc
|
extern @CShots@unput_update_render$qv:proc
|
||||||
extern @CShots@hittest_pellet$qii:proc
|
extern @CShots@hittest_pellet$qii:proc
|
||||||
extern @CShots@hittest_boss$qiiii:proc
|
extern @CShots@hittest_boss$qiiii:proc
|
||||||
|
extern @CPellets@$bctr$qv:proc
|
||||||
; =============== S U B R O U T I N E =======================================
|
|
||||||
|
|
||||||
; Attributes: bp-based frame
|
|
||||||
|
|
||||||
sub_30047 proc far
|
|
||||||
|
|
||||||
@@CPellets = dword ptr 6
|
|
||||||
|
|
||||||
push bp
|
|
||||||
mov bp, sp
|
|
||||||
push si
|
|
||||||
cmp [bp+@@CPellets], 0
|
|
||||||
jnz short loc_30065
|
|
||||||
push size CPellets
|
|
||||||
call @$bnew$qui ; operator new(uint)
|
|
||||||
pop cx
|
|
||||||
mov word ptr [bp+@@CPellets+2], dx
|
|
||||||
mov word ptr [bp+@@CPellets], ax
|
|
||||||
or ax, dx
|
|
||||||
jz short loc_300AA
|
|
||||||
|
|
||||||
loc_30065:
|
|
||||||
mov ax, word ptr [bp+@@CPellets]
|
|
||||||
mov _pellet_cur, ax
|
|
||||||
xor si, si
|
|
||||||
jmp short loc_30081
|
|
||||||
; ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
loc_3006F:
|
|
||||||
mov bx, _pellet_cur
|
|
||||||
mov byte ptr [bx], 0
|
|
||||||
mov word ptr [bx+18h], 0
|
|
||||||
inc si
|
|
||||||
add _pellet_cur, size pellet_t
|
|
||||||
|
|
||||||
loc_30081:
|
|
||||||
cmp si, PELLET_COUNT
|
|
||||||
jl short loc_3006F
|
|
||||||
les bx, [bp+@@CPellets]
|
|
||||||
mov es:[bx+CPellets.PELLET_alive_count], 0
|
|
||||||
xor si, si
|
|
||||||
jmp short loc_300A5
|
|
||||||
; ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
loc_30094:
|
|
||||||
mov ax, si
|
|
||||||
add ax, ax
|
|
||||||
les bx, [bp+@@CPellets]
|
|
||||||
add bx, ax
|
|
||||||
mov es:[bx+PELLET_unknown_zero], 0
|
|
||||||
inc si
|
|
||||||
|
|
||||||
loc_300A5:
|
|
||||||
cmp si, 10
|
|
||||||
jl short loc_30094
|
|
||||||
|
|
||||||
loc_300AA:
|
|
||||||
mov dx, word ptr [bp+@@CPellets+2]
|
|
||||||
mov ax, word ptr [bp+@@CPellets]
|
|
||||||
pop si
|
|
||||||
pop bp
|
|
||||||
retf
|
|
||||||
sub_30047 endp
|
|
||||||
main_38__TEXT ends
|
|
||||||
|
|
||||||
main_38___TEXT segment byte public 'CODE' use16
|
|
||||||
extern @CPellets@add_pattern$qii16pellet_pattern_ti:proc
|
extern @CPellets@add_pattern$qii16pellet_pattern_ti:proc
|
||||||
extern @CPellets@add_single$qiiii15pellet_motion_tiii:proc
|
extern @CPellets@add_single$qiiii15pellet_motion_tiii:proc
|
||||||
extern @CPellets@motion_type_apply_for_cur$qv:proc
|
extern @CPellets@motion_type_apply_for_cur$qv:proc
|
||||||
extern @CPellets@visible_after_hittests_for_cur$qii:proc
|
extern @CPellets@visible_after_hittests_for_cur$qii:proc
|
||||||
extern _pellet_render:proc
|
extern _pellet_render:proc
|
||||||
|
main_38_TEXT ends
|
||||||
|
|
||||||
|
main_38__TEXT segment byte public 'CODE' use16
|
||||||
|
assume cs:main_38
|
||||||
|
assume es:nothing, ss:nothing, ds:_DATA, fs:nothing, gs:nothing
|
||||||
|
|
||||||
; =============== S U B R O U T I N E =======================================
|
; =============== S U B R O U T I N E =======================================
|
||||||
|
|
||||||
|
@ -54609,7 +54541,7 @@ sub_30F70 endp
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
dw 0
|
dw 0
|
||||||
main_38___TEXT ends
|
main_38__TEXT ends
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue