[Decompilation] [th01] Orb physics

"Physics". Not only did ZUN restrict the X velocity to the 5 discrete
states of -8, -4, 0, 4, and 8 (because hey, unaligned blitting is slow
anyway?), but gravity is also only applied every 5 frames.

We're still missing quite a bit of usage code, but these are the core
functions. One of which turned out to be undecompilable, due to… a
rigorously defined instruction order when performing arithmetic between
`double`s and `float`s?! Still, spelling out all this stuff in ASM
seems much better than somehow splitting the data segment, just so that
we can immediately use literals there.

Part of P0097, funded by Ember2528.
This commit is contained in:
nmlgc 2020-06-09 20:39:44 +02:00
parent f364dc0182
commit 51de73bcc9
9 changed files with 334 additions and 306 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_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_12.c th01\main_13.cpp th01\main_13_.cpp th01\main_14.c th01\main_16.c th01\main_19.cpp th01\main_25.cpp th01\main_27.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_12.c th01\main_13.cpp th01\main_13_.cpp th01\main_14.c 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 @&&|
$**
|

View File

@ -33,7 +33,7 @@ where the scalar-type variable is declared in relation to them.
| `MOV al, var`<br />`MOV ah, 0`| `var` is *unsigned char* |
| `MOV al, var`<br />`CBW` | `var` is *char*, `AX` is *int* |
## Arithmetic
## Integer arithmetic
| | |
|-|-|
@ -55,6 +55,39 @@ must be spelled out to silence the `Possibly incorrect assignment` warning.
`SUB` means that `??` is unsigned. Might require suffixing `imm` with `u` in
case it's part of an arithmetic expression that was promoted to `int`.
## Floating-point arithmetic
* Since the x87 FPU can only load from memory, all temporary results of
arithmetic are spilled to one single compiler-generated variable (`fpu_tmp`)
on the stack, which is reused across all of the function:
| | |
|-|-|
| `MOV  AX, myint`<br />`INC  AX`<br />`MOV  fpu_tmp, ax`<br />`FILD fpu_tmp`<br />`FSTP ret` | `float ret = (myint + 1)` |
* The same `fpu_tmp` variable is also used as the destination for `FNSTSW`,
used in comparisons.
* Performing arithmetic or comparisons between `float` and `double` variables
*always* `FLD`s the `float` first, before emitting the corresponding FPU
instruction for the `double`, regardless of how the variables are placed in
the expression. The instruction order only matches the expression order for
literals:
```c++
char ret;
float f;
double d;
ret = (f > d); // FLD f, FCOMP d
ret = (d > f); // FLD f, FCOMP d
ret = (d > 3.14f); // FLD d, FCOMP 3.14f
ret = (3.14f > d); // FLD 3.14f, FCOMP d
ret = (f > 3.14); // FLD f, FCOMP 3.14 + 4
ret = (3.14 > f); // FLD 3.14, FCOMP f + 4
```
## `switch` statements
* Sequence of the individual cases is identical in both C and ASM

134
th01/main/player/orb.cpp Normal file
View File

@ -0,0 +1,134 @@
#include "th01/main/playfld.hpp"
#include "th01/main/player/orb.hpp"
extern const double ORB_VELOCITY_Y_MIN;
extern const float ORB_VELOCITY_Y_MAX;
extern const double ORB_COEFFICIENT_OF_RESTITUTION;
inline double gravity_for(const double& force)
{
return ((orb_force_frame / 5) + orb_force);
}
/// Temporary data segment workarounds
/// ----------------------------------
// Also needs to be spelled out in ASM to avoid the unwanted WAIT instruction
// afterwards.
#define GRAVITY_FOR(force) \
_AX = orb_force_frame / 5; \
asm mov [bp-2], ax; \
asm fild word ptr [bp-2]; \
asm fadd force;
// Neither WAIT nor FWAIT emit the emulated WAIT we want...
#define FWAIT db 0xCD, 0x3D;
/// ----------------------------------
int orb_velocity_y_update(void)
{
/* TODO: Proper decompilation, once data can be emitted here:
* ----------------------------------------------------------
orb_velocity_y = gravity_for(orb_force);
if(orb_velocity_y > ORB_VELOCITY_Y_MAX) {
orb_velocity_y = ORB_VELOCITY_Y_MAX;
} else if(orb_velocity_y < ORB_VELOCITY_Y_MIN) {
orb_velocity_y = ORB_VELOCITY_Y_MIN;
}
return gravity_for(orb_force);
* ----------------------------------------------------------
* Performing arithmetic or comparisons between a double (orb_velocity_y)
* and a float (ORB_VELOCITY_Y_MAX) variable always FLDs the float first,
* before emitting the corresponding FPU instruction with the double,
* which is not what we want here.
*/
GRAVITY_FOR(orb_force);
asm {
fstp orb_velocity_y;
fld orb_velocity_y;
fcomp ORB_VELOCITY_Y_MAX;
fstsw [bp-2];
FWAIT;
mov ax, [bp-2];
sahf;
jbe min_velocity_check;
fld ORB_VELOCITY_Y_MAX;
}
goto set_velocity;
min_velocity_check:
if(orb_velocity_y < ORB_VELOCITY_Y_MIN) asm {
fld ORB_VELOCITY_Y_MIN;
set_velocity:
fstp orb_velocity_y;
FWAIT;
}
return gravity_for(orb_force);
}
#define random_velocity_change(val, new_velocity) \
if(orb_force_frame < 17) { \
if((rand() % 50) == val) { \
orb_velocity_x = new_velocity; \
} \
}
void orb_force_new(double immediate, orb_force_t force)
{
extern const float ORB_FORCE_2_0;
extern const double ORB_FORCE_SHOT_BASE;
if(force == OF_BOUNCE_FROM_GROUND) {
orb_force = (-orb_velocity_y * ORB_COEFFICIENT_OF_RESTITUTION);
if(orb_velocity_x == OVX_0) {
random_velocity_change(0, OVX_4_LEFT);
random_velocity_change(1, OVX_4_RIGHT);
}
}
if(force == OF_BOUNCE_FROM_TOP) {
orb_force = ((-orb_velocity_y) - (orb_force_frame / 4));
}
if(force == OF_SHOT) {
/* TODO: Proper decompilation, once data can be emitted here:
* ----------------------------------------------------------
orb_force = ((orb_velocity_y / ORB_FORCE_2_0) + ORB_FORCE_SHOT_BASE);
* ----------------------------------------------------------
* Performing arithmetic or comparisons between a double
* (orb_velocity_y) and a float (ORB_FORCE_2_0) variable always FLDs
* the float first, before emitting the corresponding FPU instruction
* with the double, which is not what we want here.
*/
asm {
fld orb_velocity_y;
fdiv ORB_FORCE_2_0;
fadd ORB_FORCE_SHOT_BASE;
fstp orb_force;
FWAIT;
}
}
if(force == OF_IMMEDIATE) {
orb_force = immediate;
}
orb_force_frame = 0;
}
void orb_move_x(orb_velocity_x_t velocity_x)
{
switch(velocity_x) {
case OVX_4_LEFT: orb_cur_left -= 4; break;
case OVX_4_RIGHT: orb_cur_left += 4; break;
case OVX_8_LEFT: orb_cur_left -= 8; break;
case OVX_8_RIGHT: orb_cur_left += 8; break;
}
if(orb_cur_left <= ORB_LEFT_MIN) {
if(orb_velocity_x == OVX_4_LEFT) {
orb_velocity_x = OVX_4_RIGHT;
} else if(orb_velocity_x == OVX_8_LEFT) {
orb_velocity_x = OVX_8_RIGHT;
}
}
if(orb_cur_left >= ORB_LEFT_MAX) {
if(orb_velocity_x == OVX_4_RIGHT) {
orb_velocity_x = OVX_4_LEFT;
} else if(orb_velocity_x == OVX_8_RIGHT) {
orb_velocity_x = OVX_8_LEFT;
}
}
}

View File

@ -11,3 +11,45 @@ static const int ORB_TOP_START = ( ORB_TOP_MAX - 88);
extern int orb_cur_left, orb_cur_top;
extern int orb_prev_left, orb_prev_top;
/// Physics
/// -------
#pragma option -b
enum orb_velocity_x_t {
OVX_0 = 0,
OVX_4_LEFT = 1,
OVX_4_RIGHT = 2,
OVX_8_LEFT = 3,
OVX_8_RIGHT = 4,
};
enum orb_force_t {
OF_BOUNCE_FROM_GROUND = 0,
OF_BOUNCE_FROM_TOP = 1,
OF_SHOT = 2,
OF_IMMEDIATE = 3, // new force passed directly in [immediate]
};
#pragma option -b.
// Initial value of the current force acting on the orb
extern double orb_force;
// Number of frames that [orb_force] has been acting on the orb
extern int orb_force_frame;
extern orb_velocity_x_t orb_velocity_x;
extern double orb_velocity_y;
// Applies a new force of the given type onto the orb. Sets [orb_force], and
// reses [orb_force_frame].
void orb_force_new(double immediate, orb_force_t force);
// Updates [orb_velocity_y] with the currently active force, and returns the
// orb's velocity for this frame, in pixels to be added to [orb_cur_top].
int orb_velocity_y_update(void);
// Updates [orb_cur_left] *and* the global [orb_velocity_x] (!) to bounce the
// orb off the left or right edge of the playfield, if necessary, depending on
// the passed [velocity_x].
void orb_move_x(orb_velocity_x_t velocity_x);
/// -------

View File

@ -9,6 +9,7 @@ ORB_TOP_MAX = (PLAYFIELD_BOTTOM - ORB_H)
ORB_LEFT_START = (ORB_LEFT_MAX - 8)
ORB_TOP_START = ( ORB_TOP_MAX - 88)
public _orb_cur_left, _orb_cur_top
public _orb_cur_left, _orb_cur_top, _orb_force_frame
_orb_cur_left dw ?
_orb_cur_top dw ?
_orb_force_frame dw ?

View File

@ -0,0 +1,14 @@
OVX_0 = 0
OVX_4_LEFT = 1
OVX_4_RIGHT = 2
OVX_8_LEFT = 3
OVX_8_RIGHT = 4
OF_BOUNCE_FROM_GROUND = 0
OF_BOUNCE_FROM_TOP = 1
OF_SHOT = 2
OF_IMMEDIATE = 3
public _orb_velocity_y, _orb_force
_orb_velocity_y dq 0.0
_orb_force dq 0.0

View File

@ -1,6 +1,6 @@
/* ReC98
* -----
* Code segment #1 of TH01's REIIDEN.EXE
* 1st part of code segment #1 of TH01's REIIDEN.EXE
*/
extern "C" {

13
th01/main_01_.cpp Normal file
View File

@ -0,0 +1,13 @@
/* ReC98
* -----
* 2nd part of code segment #1 of TH01's REIIDEN.EXE
*/
#pragma codeseg main_01__TEXT main_01
extern "C" {
#include "ReC98.h"
#include "th01/main/player/orb.cpp"
}

View File

@ -65,7 +65,7 @@ include th01/main/playfld.inc
extern _toupper:proc
extern _vsprintf:proc
main_01 group main_01_TEXT, main_01__TEXT
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_25 group main_25_TEXT, main_25__TEXT
@ -1744,221 +1744,13 @@ loc_C5B1:
pop bp
retf
sub_C466 endp
main_01__TEXT ends
main_01___TEXT segment byte public 'CODE' use16
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_C5B4 proc far
var_2 = word ptr -2
enter 2, 0
mov ax, word_36C2C
mov bx, 5
cwd
idiv bx
mov [bp+var_2], ax
fild [bp+var_2]
fadd dbl_34A9C
fstp dbl_34A94
fld dbl_34A94
fcomp flt_34B64
fstsw [bp+var_2]
fwait
mov ax, [bp+var_2]
sahf
jbe short loc_C5EF
fld flt_34B64
jmp short loc_C60A
; ---------------------------------------------------------------------------
loc_C5EF:
fld dbl_34A94
fcomp dbl_34B68
fstsw [bp+var_2]
fwait
mov ax, [bp+var_2]
sahf
jnb short loc_C611
fld dbl_34B68
loc_C60A:
fstp dbl_34A94
fwait
loc_C611:
mov ax, word_36C2C
mov bx, 5
cwd
idiv bx
mov [bp+var_2], ax
fild [bp+var_2]
fadd dbl_34A9C
call ftol@
leave
retf
sub_C5B4 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
; int __cdecl __far sub_C62D(double, int)
sub_C62D proc far
var_2 = word ptr -2
arg_0 = qword ptr 6
arg_8 = word ptr 0Eh
enter 2, 0
push si
mov si, [bp+arg_8]
or si, si
jnz short loc_C68D
fld dbl_34A94
fchs
fmul dbl_34B70
fstp dbl_34A9C
fwait
cmp word_34A7C, 0
jnz short loc_C68D
cmp word_36C2C, 11h
jge short loc_C670
call IRand
mov bx, 32h ; '2'
cwd
idiv bx
or dx, dx
jnz short loc_C670
mov word_34A7C, 1
loc_C670:
cmp word_36C2C, 11h
jge short loc_C68D
call IRand
mov bx, 32h ; '2'
cwd
idiv bx
cmp dx, 1
jnz short loc_C68D
mov word_34A7C, 2
loc_C68D:
cmp si, 1
jnz short loc_C6B4
mov ax, word_36C2C
mov bx, 4
cwd
idiv bx
mov [bp+var_2], ax
fild [bp+var_2]
fld dbl_34A94
fchs
fsubrp st(1), st
fstp dbl_34A9C
fwait
loc_C6B4:
cmp si, 2
jnz short loc_C6CF
fld dbl_34A94
fdiv flt_34B78
fadd dbl_34B7C
fstp dbl_34A9C
fwait
loc_C6CF:
cmp si, 3
jnz short loc_C6DF
fld [bp+arg_0]
fstp dbl_34A9C
fwait
loc_C6DF:
mov word_36C2C, 0
pop si
leave
retf
sub_C62D endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_C6E8 proc far
arg_0 = word ptr 6
push bp
mov bp, sp
mov bx, [bp+arg_0]
dec bx
cmp bx, 3
ja short loc_C715
add bx, bx
jmp cs:off_C75E[bx]
loc_C6FB:
sub _orb_cur_left, 4
jmp short loc_C715
; ---------------------------------------------------------------------------
loc_C702:
add _orb_cur_left, 4
jmp short loc_C715
; ---------------------------------------------------------------------------
loc_C709:
sub _orb_cur_left, 8
jmp short loc_C715
; ---------------------------------------------------------------------------
loc_C710:
add _orb_cur_left, 8
loc_C715:
cmp _orb_cur_left, 0
jg short loc_C738
cmp word_34A7C, 1
jnz short loc_C72B
mov word_34A7C, 2
jmp short loc_C738
; ---------------------------------------------------------------------------
loc_C72B:
cmp word_34A7C, 3
jnz short loc_C738
mov word_34A7C, 4
loc_C738:
cmp _orb_cur_left, ORB_LEFT_MAX
jl short loc_C75C
cmp word_34A7C, 2
jnz short loc_C74F
mov word_34A7C, 1
pop bp
retf
; ---------------------------------------------------------------------------
loc_C74F:
cmp word_34A7C, 4
jnz short loc_C75C
mov word_34A7C, 3
loc_C75C:
pop bp
retf
sub_C6E8 endp
; ---------------------------------------------------------------------------
off_C75E dw offset loc_C6FB
dw offset loc_C702
dw offset loc_C709
dw offset loc_C710
extern _orb_velocity_y_update:proc
extern _orb_force_new:proc
extern _orb_move_x:proc
; =============== S U B R O U T I N E =======================================
@ -1975,24 +1767,23 @@ arg_0 = word ptr 6
mov si, [bp+arg_0]
cmp word_34A86, 0
jnz loc_C816
push word_34A7C
call sub_C6E8
call _orb_move_x stdcall, _orb_velocity_x
pop cx
call sub_C5B4
call _orb_velocity_y_update
add _orb_cur_top, ax
inc word_34A92
cmp word_34A7C, 1
cmp _orb_velocity_x, OVX_4_LEFT
jz short loc_C799
cmp word_34A7C, 3
cmp _orb_velocity_x, OVX_8_LEFT
jnz short loc_C79D
loc_C799:
inc word_34A7E
loc_C79D:
cmp word_34A7C, 2
cmp _orb_velocity_x, OVX_4_RIGHT
jz short loc_C7AB
cmp word_34A7C, 4
cmp _orb_velocity_x, OVX_8_RIGHT
jnz short loc_C7AF
loc_C7AB:
@ -2011,12 +1802,12 @@ loc_C7BC:
loc_C7C9:
cmp _orb_cur_top, ORB_TOP_MAX
jle short loc_C7F4
push 0 ; int
fld dbl_34B70
push OF_BOUNCE_FROM_GROUND
fld _ORB_COEFFICIENT_OF_RESTITUTION
sub sp, 8
fstp [bp+var_C]
fwait
call sub_C62D
call _orb_force_new
add sp, 0Ah
mov _orb_cur_top, ORB_TOP_MAX
mov word_34A84, 0
@ -2024,12 +1815,12 @@ loc_C7C9:
loc_C7F4:
cmp _orb_cur_top, ORB_TOP_MIN
jge short loc_C816
push 1 ; int
push OF_BOUNCE_FROM_TOP
fldz
sub sp, 8
fstp [bp+var_C]
fwait
call sub_C62D
call _orb_force_new
add sp, 0Ah
mov _orb_cur_top, ORB_TOP_MIN
@ -4007,10 +3798,10 @@ loc_DB04:
loc_DB0A:
fld dbl_34FF5
fstp dbl_34A9C
fstp _orb_force
fwait
mov word_36C2C, 0
mov word_34A7C, 1
mov _orb_force_frame, 0
mov _orb_velocity_x, OVX_4_LEFT
mov _orb_prev_left, ORB_LEFT_START
mov _orb_prev_top, ORB_TOP_START
mov byte_34A57, 0
@ -4165,7 +3956,7 @@ loc_DCCA:
call sub_181AC
call sub_1851E
inc dword_36C20
inc word_36C2C
inc _orb_force_frame
inc dword_34A62
inc _bomb_doubletap_frames
test byte ptr _rand, 3
@ -4735,7 +4526,7 @@ sub_E319 proc far
retf
sub_E319 endp
main_01__TEXT ends
main_01___TEXT ends
; ===========================================================================
@ -18612,14 +18403,14 @@ loc_1AD1A:
mov ax, _player_left
sub ax, _orb_cur_left
jnz short loc_1AD66
mov word_34A7C, 0
mov _orb_velocity_x, OVX_0
call IRand
mov bx, 8
cwd
idiv bx
or dx, dx
jnz short loc_1AD4E
mov word_34A7C, 1
mov _orb_velocity_x, OVX_4_LEFT
loc_1AD4E:
call IRand
@ -18630,15 +18421,15 @@ loc_1AD4E:
jnz short loc_1AD6C
loc_1AD5E:
mov word_34A7C, 1
mov _orb_velocity_x, OVX_4_LEFT
jmp short loc_1AD6C
; ---------------------------------------------------------------------------
loc_1AD66:
mov word_34A7C, 2
mov _orb_velocity_x, OVX_4_RIGHT
loc_1AD6C:
push 3
push OF_IMMEDIATE
mov ax, si
cwd
sub ax, dx
@ -18684,38 +18475,38 @@ loc_1ADBB:
jge short loc_1AE0A
cmp si, 65h ; 'e'
jnz short loc_1ADCD
mov word_34A7C, 1
mov _orb_velocity_x, OVX_4_LEFT
jmp short loc_1ADF2
; ---------------------------------------------------------------------------
loc_1ADCD:
cmp si, 66h ; 'f'
jnz short loc_1ADDA
mov word_34A7C, 2
mov _orb_velocity_x, OVX_4_RIGHT
jmp short loc_1ADF2
; ---------------------------------------------------------------------------
loc_1ADDA:
cmp si, 67h ; 'g'
jnz short loc_1ADE7
mov word_34A7C, 4
mov _orb_velocity_x, OVX_8_RIGHT
jmp short loc_1ADF2
; ---------------------------------------------------------------------------
loc_1ADE7:
cmp si, 68h ; 'h'
jnz short loc_1ADF2
mov word_34A7C, 3
mov _orb_velocity_x, OVX_8_LEFT
loc_1ADF2:
push 3 ; int
push OF_IMMEDIATE
fld dbl_35B49
loc_1ADF9:
sub sp, 8
fstp [bp+var_E]
fwait
call sub_C62D
call _orb_force_new
add sp, 0Ah
loc_1AE0A:
@ -29184,28 +28975,28 @@ loc_20F14:
loc_20F24:
mov _orb_cur_top, ax
cmp word_34A7C, 2
cmp _orb_velocity_x, OVX_4_RIGHT
jnz short loc_20F3C
cmp [bp+var_6], 0
jge short loc_20F3C
mov word_34A7C, 1
mov _orb_velocity_x, OVX_4_LEFT
jmp short loc_20F4F
; ---------------------------------------------------------------------------
loc_20F3C:
cmp word_34A7C, 1
cmp _orb_velocity_x, OVX_4_LEFT
jnz short loc_20F4F
cmp [bp+var_6], 0
jle short loc_20F4F
mov word_34A7C, 2
mov _orb_velocity_x, OVX_4_RIGHT
loc_20F4F:
push 0 ; int
push OF_BOUNCE_FROM_GROUND
fld flt_35C9A
sub sp, 8
fstp [bp+var_1A]
fwait
call sub_C62D
call _orb_force_new
add sp, 0Ah
loc_20F67:
@ -29348,13 +29139,13 @@ loc_21060:
cmp word ptr es:[bx], 0
jnz short loc_210B1
inc word ptr es:[bx]
push 3 ; int
fld dbl_34A94
push OF_IMMEDIATE
fld _orb_velocity_y
fchs
sub sp, 8
fstp [bp+var_1A]
fwait
call sub_C62D
call _orb_force_new
add sp, 0Ah
loc_210B1:
@ -29388,13 +29179,13 @@ loc_210C6:
cmp word ptr es:[bx], 0
jnz short loc_21117
inc word ptr es:[bx]
push 3 ; int
fld dbl_34A94
push OF_IMMEDIATE
fld _orb_velocity_y
fchs
sub sp, 8
fstp [bp+var_1A]
fwait
call sub_C62D
call _orb_force_new
add sp, 0Ah
loc_21117:
@ -29431,42 +29222,42 @@ loc_2112C:
jnz short loc_211CD
inc word ptr es:[bx]
mov byte_39EB2, 1
cmp word_34A7C, 0
cmp _orb_velocity_x, OVX_0
jnz short loc_21198
push 3 ; int
fld dbl_34A94
push OF_IMMEDIATE
fld _orb_velocity_y
fchs
sub sp, 8
fstp [bp+var_1A]
fwait
call sub_C62D
call _orb_force_new
add sp, 0Ah
jmp short loc_211CD
; ---------------------------------------------------------------------------
loc_21198:
cmp word_34A7C, 1
cmp _orb_velocity_x, OVX_4_LEFT
jnz short loc_211A4
mov ax, 2
jmp short loc_211CA
; ---------------------------------------------------------------------------
loc_211A4:
cmp word_34A7C, 2
cmp _orb_velocity_x, OVX_4_RIGHT
jnz short loc_211B0
mov ax, 1
jmp short loc_211CA
; ---------------------------------------------------------------------------
loc_211B0:
cmp word_34A7C, 3
cmp _orb_velocity_x, OVX_8_LEFT
jnz short loc_211BC
mov ax, 4
jmp short loc_211CA
; ---------------------------------------------------------------------------
loc_211BC:
cmp word_34A7C, 4
cmp _orb_velocity_x, OVX_8_RIGHT
jnz short loc_211C8
mov ax, 3
jmp short loc_211CA
@ -29476,7 +29267,7 @@ loc_211C8:
xor ax, ax
loc_211CA:
mov word_34A7C, ax
mov _orb_velocity_x, ax
loc_211CD:
mov ax, si
@ -29512,42 +29303,42 @@ loc_211E2:
jnz short loc_21283
inc word ptr es:[bx]
mov byte_39EB2, 1
cmp word_34A7C, 0
cmp _orb_velocity_x, OVX_0
jnz short loc_2124E
push 3 ; int
fld dbl_34A94
push OF_IMMEDIATE
fld _orb_velocity_y
fchs
sub sp, 8
fstp [bp+var_1A]
fwait
call sub_C62D
call _orb_force_new
add sp, 0Ah
jmp short loc_21283
; ---------------------------------------------------------------------------
loc_2124E:
cmp word_34A7C, 1
cmp _orb_velocity_x, OVX_4_LEFT
jnz short loc_2125A
mov ax, 2
jmp short loc_21280
; ---------------------------------------------------------------------------
loc_2125A:
cmp word_34A7C, 2
cmp _orb_velocity_x, OVX_4_RIGHT
jnz short loc_21266
mov ax, 1
jmp short loc_21280
; ---------------------------------------------------------------------------
loc_21266:
cmp word_34A7C, 3
cmp _orb_velocity_x, OVX_8_LEFT
jnz short loc_21272
mov ax, 4
jmp short loc_21280
; ---------------------------------------------------------------------------
loc_21272:
cmp word_34A7C, 4
cmp _orb_velocity_x, OVX_8_RIGHT
jnz short loc_2127E
mov ax, 3
jmp short loc_21280
@ -29557,7 +29348,7 @@ loc_2127E:
xor ax, ax
loc_21280:
mov word_34A7C, ax
mov _orb_velocity_x, ax
loc_21283:
mov ax, si
@ -30121,8 +29912,8 @@ loc_21777:
mov bx, 5
cwd
idiv bx
mov word_34A7C, dx
push 3 ; int
mov _orb_velocity_x, dx
push OF_IMMEDIATE
call IRand
mov bx, 13h
cwd
@ -30133,7 +29924,7 @@ loc_21777:
sub sp, 8
fstp [bp+var_12]
fwait
call sub_C62D
call _orb_force_new
add sp, 0Ah
mov ax, point_39EB9.x
mov _orb_cur_left, ax
@ -30595,26 +30386,26 @@ loc_21B11:
dec word ptr es:[bx]
les bx, [bp+arg_4]
mov word ptr es:[bx], 1
cmp word_34A7C, 1
cmp _orb_velocity_x, OVX_4_LEFT
jz short loc_21B53
cmp word_34A7C, 3
cmp _orb_velocity_x, OVX_8_LEFT
jz short loc_21B53
cmp word_34A7C, 2
cmp _orb_velocity_x, OVX_4_RIGHT
jz short loc_21B5B
cmp word_34A7C, 4
cmp _orb_velocity_x, OVX_8_RIGHT
jz short loc_21B5B
cmp word_34A7C, 0
cmp _orb_velocity_x, OVX_0
jnz short loc_21B61
cmp _orb_cur_left, (PLAYFIELD_CENTER - (ORB_W / 2))
jge short loc_21B5B
loc_21B53:
mov word_34A7C, 2
mov _orb_velocity_x, OVX_4_RIGHT
jmp short loc_21B61
; ---------------------------------------------------------------------------
loc_21B5B:
mov word_34A7C, 1
mov _orb_velocity_x, OVX_4_LEFT
loc_21B61:
movsx eax, [bp+arg_12]
@ -49544,10 +49335,10 @@ loc_2C8AE:
mov _orb_cur_top, ORB_TOP_START
mov _player_left, PLAYER_LEFT_START
fld dbl_35FAA
fstp dbl_34A9C
fstp _orb_force
fwait
mov word_36C2C, 0
mov word_34A7C, 1
mov _orb_force_frame, 0
mov _orb_velocity_x, OVX_4_LEFT
mov byte_34A57, 0
mov byte_34A58, 0
push 0
@ -55170,7 +54961,7 @@ arg_8 = word ptr 0Eh
sub ax, di
cmp ax, 8
jle short loc_2FEB2
mov word_34A7C, 1
mov _orb_velocity_x, OVX_4_LEFT
jmp short loc_2FEE6
; ---------------------------------------------------------------------------
@ -55183,7 +54974,7 @@ loc_2FEB2:
sub ax, di
cmp ax, 8
jnz short loc_2FECD
mov word_34A7C, 0
mov _orb_velocity_x, OVX_0
jmp short loc_2FEE6
; ---------------------------------------------------------------------------
@ -55196,23 +54987,22 @@ loc_2FECD:
sub ax, di
cmp ax, 0FFF0h
jle short loc_2FEE6
mov word_34A7C, 2
mov _orb_velocity_x, OVX_4_RIGHT
loc_2FEE6:
push 2 ; int
push OF_SHOT
fldz
sub sp, 8
fstp [bp+var_E]
fwait
call sub_C62D
call _orb_force_new
add sp, 0Ah
les bx, [bp+arg_0]
add bx, si
mov byte ptr es:[bx+30h], 0
push word_34A7C
call sub_C6E8
call _orb_move_x stdcall, _orb_velocity_x
pop cx
call sub_C5B4
call _orb_velocity_y_update
add _orb_cur_top, ax
mov ax, 1
jmp short loc_2FF20
@ -57321,7 +57111,8 @@ word_34A74 dw 0
dw 0
word_34A78 dw 0
dw 0
word_34A7C dw 0
public _orb_velocity_x
_orb_velocity_x dw 0
word_34A7E dw 0
_rem_lives dw 4
word_34A82 dw 0
@ -57334,8 +57125,7 @@ public _orb_prev_left, _orb_prev_top
_orb_prev_left dw ORB_LEFT_START
_orb_prev_top dw ORB_TOP_START
word_34A92 dw 0
dbl_34A94 dq 0.0
dbl_34A9C dq 0.0
include th01/main/player/orb[data].asm
byte_34AA4 db 0
unk_34AA5 db 0Fh
db 0Fh
@ -57413,11 +57203,13 @@ a0m db 1Bh,'[0m',0
s2 db 'empty.grf',0
aKuzi1_grc db 'kuzi1.grc',0
aKuzi2_grc db 'kuzi2.grc',0
flt_34B64 dd 16.0
dbl_34B68 dq -16.0
dbl_34B70 dq 0.78
flt_34B78 dd 2.0
dbl_34B7C dq -10.0
public _ORB_VELOCITY_Y_MAX, _ORB_VELOCITY_Y_MIN
public _ORB_COEFFICIENT_OF_RESTITUTION, _ORB_FORCE_2_0, _ORB_FORCE_SHOT_BASE
_ORB_VELOCITY_Y_MAX dd 16.0
_ORB_VELOCITY_Y_MIN dq -16.0
_ORB_COEFFICIENT_OF_RESTITUTION dq 0.78
_ORB_FORCE_2_0 dd 2.0
_ORB_FORCE_SHOT_BASE dq -10.0
aVovVtvrvd db '',0
aB@nKjb@b@pic db ' 再開  終了',0
aBB@b@b@b@b@b@ db '●      ',0
@ -58437,7 +58229,6 @@ _mode_debug db ?
dword_36C20 dd ?
include th01/main/player/player[bss].asm
include th01/main/player/orb[bss].asm
word_36C2C dw ?
db 1275 dup(?)
unk_37129 db ? ;
db 645 dup(?)