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 @&&|
|
||||
$**
|
||||
|
|
||||
|
|
|
@ -269,6 +269,50 @@ Examples:
|
|||
**Certainty**: Maybe Borland (not Turbo) C++ has an optimization option
|
||||
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
|
||||
|
||||
### `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
|
||||
/// ---------
|
||||
// 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;
|
||||
/// -------
|
||||
|
||||
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(
|
||||
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);
|
||||
|
||||
public:
|
||||
CPellets(void);
|
||||
|
||||
// Spawns a number of bullets according to the given [pattern], with their
|
||||
// corresponding velocities, at (left, top). [speed_base] is tuned
|
||||
// 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_DECAY_FRAMES = 7;
|
||||
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
/* ReC98
|
||||
* -----
|
||||
* 1st part of code segment #38 of TH01's REIIDEN.EXE
|
||||
* Code segment #38 of TH01's REIIDEN.EXE
|
||||
*/
|
||||
|
||||
#pragma option -Z
|
||||
|
||||
extern "C" {
|
||||
#include "platform.h"
|
||||
#include "pc98.h"
|
||||
#include "planar.h"
|
||||
#include "th01/th01.h"
|
||||
#include "th01/ranks.h"
|
||||
#include "th01/snd/mdrv2.h"
|
||||
#include "th01/formats/ptn.hpp"
|
||||
#include "th01/hardware/egc.h"
|
||||
#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/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_25 group main_25_TEXT, main_25__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
|
||||
push bp
|
||||
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[1 * word], 60h
|
||||
mov _Shots.SHOT_unknown[2 * word], 70h
|
||||
|
@ -53930,90 +53930,22 @@ main_37_TEXT ends
|
|||
|
||||
; Segment type: Pure code
|
||||
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@unput_and_reset_all$qv:proc
|
||||
extern @CShots@unput_update_render$qv:proc
|
||||
extern @CShots@hittest_pellet$qii:proc
|
||||
extern @CShots@hittest_boss$qiiii: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@$bctr$qv:proc
|
||||
extern @CPellets@add_pattern$qii16pellet_pattern_ti:proc
|
||||
extern @CPellets@add_single$qiiii15pellet_motion_tiii:proc
|
||||
extern @CPellets@motion_type_apply_for_cur$qv:proc
|
||||
extern @CPellets@visible_after_hittests_for_cur$qii: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 =======================================
|
||||
|
||||
|
@ -54609,7 +54541,7 @@ sub_30F70 endp
|
|||
|
||||
; ---------------------------------------------------------------------------
|
||||
dw 0
|
||||
main_38___TEXT ends
|
||||
main_38__TEXT ends
|
||||
|
||||
.data
|
||||
|
||||
|
|
Loading…
Reference in New Issue