mirror of https://github.com/nmlgc/ReC98.git
[Decompilation] [th03] Shot update and render functions
Meh, can't overload arithmetic operators that take a Subpixel without generating a needless load and store, even with -Z. But heck, slightly uglifying subpixel/subpixel arithmetic is exactly the right trade-off. Completes P0061, funded by Touhou Patch Center.
This commit is contained in:
parent
8b01c60f44
commit
5f4f5d87dc
|
@ -81,8 +81,8 @@ bin\th03\op.exe: bin\th03\op.obj th03\op_02.c
|
|||
$**
|
||||
|
|
||||
|
||||
bin\th03\main.exe: bin\th03\main.obj th03\sprite16.cpp
|
||||
$(CC) $(CFLAGS) -ml -DGAME=3 -nbin\th03\ -eMAIN.EXE @&&|
|
||||
bin\th03\main.exe: bin\th03\main.obj th03\main_01.cpp th03\sprite16.cpp
|
||||
$(CC) $(CFLAGS) -ml -Z -DGAME=3 -nbin\th03\ -eMAIN.EXE @&&|
|
||||
$**
|
||||
|
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
| | |
|
||||
|-|-|
|
||||
| `DX` | First 8-bit variable declared *if no other function is called* |
|
||||
| `DX` | First 8-bit variable declared *if no other function is called*<br />Second 16-bit variable declared *if no other function is called* |
|
||||
| `[bp-1]` | First 8-bit variable declared *otherwise* |
|
||||
| `SI` | First 16-bit variable declared |
|
||||
| `DI` | Second 16-bit variable declared |
|
||||
| `DI` | Second 16-bit variable declared *if other functions are called* |
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -64,10 +64,16 @@ inline optimally though:
|
|||
|
||||
## C++
|
||||
|
||||
* Every class method that returns `void` inlines to the ideal representation.
|
||||
* Every class method that returns `*this` inlines to the ideal representation
|
||||
*only at the first nesting level*. Example: A class method calling an
|
||||
overloaded operator returning `*this` will generate (needless) instructions
|
||||
Class methods inline to their ideal representation if all of these are true:
|
||||
|
||||
* returns `void` || (returns `*this` && is at the first nesting level of
|
||||
inlining)
|
||||
* takes no parameters || takes only built-in, scalar-type parameters
|
||||
|
||||
Examples:
|
||||
|
||||
* A class method (first nesting level) calling an overloaded operator (second
|
||||
nesting level) returning `*this` will generate (needless) instructions
|
||||
equivalent to `MOV AX, *this`. Thus, any overloaded `=`, `+=`, `-=`, etc.
|
||||
operator should always return `void`.
|
||||
|
||||
|
@ -75,8 +81,8 @@ inline optimally though:
|
|||
custom types with overloaded assignment operators, with the resulting code
|
||||
generation being indistinguishable from equivalent C preprocessor macros.
|
||||
|
||||
* Returning *anything else* will first store that result in `AX`, leading any
|
||||
branches at the call site to then refer to `AX`.
|
||||
* Returning *anything else* but `void` or `*this` will first store that result
|
||||
in `AX`, leading any branches at the call site to then refer to `AX`.
|
||||
|
||||
**Certainty**: Maybe Borland (not Turbo) C++ has an optimization option
|
||||
against it?
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/* ReC98
|
||||
* -----
|
||||
* Code segment #1 of TH03's MAIN.EXE
|
||||
*/
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "pc98.h"
|
||||
#include "th03/sprite16.hpp"
|
||||
#include "th03/playfld.hpp"
|
||||
#include "th03/shots.hpp"
|
||||
|
||||
void pascal near shots_update(void)
|
||||
{
|
||||
shotpair_t near *shotpair = shotpairs;
|
||||
for(int i = 0; i < SHOTPAIR_COUNT; i++, shotpair++) {
|
||||
if(shotpair->flag) {
|
||||
shotpair->topleft.y.v += shotpair->velocity_y.v;
|
||||
if(shotpair->topleft.y.v <= to_sp(-1.0f)) {
|
||||
shotpair->flag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pascal near shots_render(void)
|
||||
{
|
||||
shotpair_t near *shotpair = shotpairs;
|
||||
|
||||
sprite16_put_w = SHOT_W;
|
||||
sprite16_put_h = SHOT_H;
|
||||
sprite16_clip_left = 0;
|
||||
sprite16_clip_right = RES_X - 1;
|
||||
|
||||
for(int i = 0; i < SHOTPAIR_COUNT; i++, shotpair++) {
|
||||
if(shotpair->flag) {
|
||||
int so = shotpair->so_anim + shotpair->so_pid;
|
||||
int left = playfield_fg_x_to_screen(
|
||||
shotpair->topleft.x, shotpair->pid
|
||||
);
|
||||
int top = shotpair->topleft.y.to_screen() + PLAYFIELD_Y;
|
||||
|
||||
sprite16_put(left + 0, top, so);
|
||||
sprite16_put(left + SHOTPAIR_DISTANCE, top, so);
|
||||
|
||||
shotpair->so_anim += SHOT_VRAM_W;
|
||||
if(shotpair->so_anim >= (SHOT_VRAM_W * SHOT_SPRITE_COUNT)) {
|
||||
shotpair->so_anim = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -26,6 +26,10 @@ public:
|
|||
void operator =(float screen_v) {
|
||||
v = static_cast<T>(to_sp(screen_v));
|
||||
}
|
||||
|
||||
T to_screen() const {
|
||||
return v >> 4;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> struct SPPointBase {
|
||||
|
|
|
@ -23,3 +23,6 @@ struct shotpair_t {
|
|||
#define SHOTPAIR_COUNT 32
|
||||
|
||||
extern shotpair_t shotpairs[SHOTPAIR_COUNT];
|
||||
|
||||
void pascal near shots_update(void);
|
||||
void pascal near shots_render(void);
|
||||
|
|
105
th03_main.asm
105
th03_main.asm
|
@ -289,7 +289,7 @@ loc_977E:
|
|||
call p2_1F332
|
||||
call p2_205D2
|
||||
call sub_B7E5
|
||||
call sub_E83F
|
||||
call shots_update
|
||||
mov byte ptr word_1FE88, 0
|
||||
mov byte ptr word_23AF0, 0
|
||||
call p1_2028C
|
||||
|
@ -350,7 +350,7 @@ loc_986C:
|
|||
mov byte ptr word_1FE88, 1
|
||||
mov byte ptr word_23AF0, 28h ; '('
|
||||
call p2_1F33A
|
||||
call sub_E86A
|
||||
call shots_render
|
||||
call sub_164DA
|
||||
call sub_1837C
|
||||
call sub_B80B
|
||||
|
@ -9078,105 +9078,8 @@ loc_E83B:
|
|||
retn
|
||||
sub_E737 endp
|
||||
|
||||
|
||||
; =============== S U B R O U T I N E =======================================
|
||||
|
||||
; Attributes: bp-based frame
|
||||
|
||||
sub_E83F proc near
|
||||
push bp
|
||||
mov bp, sp
|
||||
push si
|
||||
mov si, offset _shotpairs
|
||||
xor dx, dx
|
||||
jmp short loc_E862
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_E84A:
|
||||
cmp [si+shotpair_t.flag], 0
|
||||
jz short loc_E85E
|
||||
mov ax, [si+shotpair_t.velocity_y]
|
||||
add [si+shotpair_t.topleft.y], ax
|
||||
cmp [si+shotpair_t.topleft.y], -16
|
||||
jg short loc_E85E
|
||||
mov [si+shotpair_t.flag], 0
|
||||
|
||||
loc_E85E:
|
||||
inc dx
|
||||
add si, size shotpair_t
|
||||
|
||||
loc_E862:
|
||||
cmp dx, SHOTPAIR_COUNT
|
||||
jl short loc_E84A
|
||||
pop si
|
||||
pop bp
|
||||
retn
|
||||
sub_E83F endp
|
||||
|
||||
|
||||
; =============== S U B R O U T I N E =======================================
|
||||
|
||||
; Attributes: bp-based frame
|
||||
|
||||
sub_E86A proc near
|
||||
|
||||
@@top = word ptr -6
|
||||
@@left = word ptr -4
|
||||
@@sprite_offset = word ptr -2
|
||||
|
||||
enter 6, 0
|
||||
push si
|
||||
push di
|
||||
mov si, offset _shotpairs
|
||||
mov _sprite16_put_w, (SHOT_W / 16)
|
||||
mov _sprite16_put_h, SHOT_VRAM_H
|
||||
mov _sprite16_clip_left, PLAYFIELD1_CLIP_LEFT
|
||||
mov _sprite16_clip_right, PLAYFIELD2_CLIP_RIGHT
|
||||
xor di, di
|
||||
jmp short loc_E8EF
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_E88E:
|
||||
cmp [si+shotpair_t.flag], 0
|
||||
jz short loc_E8EB
|
||||
mov al, [si+shotpair_t.so_anim]
|
||||
mov ah, 0
|
||||
add ax, [si+shotpair_t.so_pid]
|
||||
mov [bp+@@sprite_offset], ax
|
||||
push [si+shotpair_t.topleft.x]
|
||||
mov al, [si+shotpair_t.pid]
|
||||
mov ah, 0
|
||||
push ax
|
||||
nopcall playfield_fg_x_to_screen
|
||||
mov [bp+@@left], ax
|
||||
mov ax, [si+shotpair_t.topleft.y]
|
||||
sar ax, 4
|
||||
add ax, PLAYFIELD_Y
|
||||
mov [bp+@@top], ax
|
||||
call sprite16_put pascal, [bp+@@left], ax, [bp+@@sprite_offset]
|
||||
mov ax, [bp+@@left]
|
||||
add ax, SHOTPAIR_DISTANCE
|
||||
call sprite16_put pascal, ax, [bp+@@top], [bp+@@sprite_offset]
|
||||
mov al, [si+shotpair_t.so_anim]
|
||||
add al, SHOT_VRAM_W
|
||||
mov [si+shotpair_t.so_anim], al
|
||||
cmp [si+shotpair_t.so_anim], SHOT_SPRITE_COUNT * SHOT_VRAM_W
|
||||
jb short loc_E8EB
|
||||
mov [si+shotpair_t.so_anim], 0
|
||||
|
||||
loc_E8EB:
|
||||
inc di
|
||||
add si, size shotpair_t
|
||||
|
||||
loc_E8EF:
|
||||
cmp di, SHOTPAIR_COUNT
|
||||
jl short loc_E88E
|
||||
pop di
|
||||
pop si
|
||||
leave
|
||||
retn
|
||||
sub_E86A endp
|
||||
|
||||
SHOTS_UPDATE procdesc pascal near
|
||||
SHOTS_RENDER procdesc pascal near
|
||||
main_01_TEXT ends
|
||||
|
||||
; ===========================================================================
|
||||
|
|
Loading…
Reference in New Issue