[C decompilation] [th01/reiiden] Randomly shaped VRAM copy functions, #1

So apparently, TH01 isn't double-buffered in the usual sense, and instead uses
the second hardware framebuffer (page 1) exclusively to keep the background
image and any non-animated sprites, including the cards. Then, in order to
limit flickering when animating the bullet, character and boss sprites on top
of that (or just to the limit number of VRAM accesses, who knows), ZUN goes to
great lengths and tries to make sure to only copy back the pixels that were
modified on plane 0 in the last frame.

(Which doesn't work that well though. When you play the game, you still notice
tons of flickering whenever sprites overlap.)

And by "great lengths", I mean "having a separate counterpart function for
each shape and sprite animated which recalculates and copies back the same
pixels from plane 1 to plane 0", because that's what the new functions here
lead me to believe. Both of them are only called at one place: the wave
function on the second half of Elis' entrance animation, and the horizontal
masked line function for Reimu's X attack animations.
This commit is contained in:
nmlgc 2015-03-10 17:39:00 +01:00
parent 519e24c459
commit 6d2fa9f077
7 changed files with 169 additions and 606 deletions

View File

@ -33,7 +33,7 @@ bin\th01\op.exe: bin\th01\op.obj th01\op_10.c th01\op_11.c th01\op_12.cpp
$**
|
bin\th01\reiiden.exe: bin\th01\reiiden.obj th01\main_12.c th01\main_16.c
bin\th01\reiiden.exe: bin\th01\reiiden.obj th01\main_12.c th01\main_13.c th01\main_16.c
$(CC) $(CFLAGS) -ml -3 -nbin\th01\ -eREIIDEN.EXE @&&|
$**
|

View File

@ -46,6 +46,14 @@ typedef enum {
PL_B, PL_R, PL_G, PL_E, PL_COUNT
} vram_plane_t;
typedef struct {
char B, R, G, E;
} vram_planar_8_pixels_t;
typedef struct {
int B, R, G, E;
} vram_planar_16_pixels_t;
// Since array subscripts create slightly different assembly in places, we
// offer both variants.
extern char *VRAM_PLANE[PL_COUNT];

View File

@ -17,10 +17,6 @@ void scale_2x(unsigned long *dst32, int src16)
mask = 0xFF00FF00; *dst32 |= _lrotr(dst_local & mask, 8);
}
typedef struct {
int B, R, G, E;
} vram_planar_16_pixels_t;
void graph_slow_2xscale_rect_1_to_0(int x0, int y0, int x1, int y1, int w1, int h1)
{
int row_p1 = (x1 / 8) + (y1 * ROW_SIZE);

47
th01/main_13.c Normal file
View File

@ -0,0 +1,47 @@
/* ReC98
* -----
* Code segment #13 of TH01's REIIDEN.EXE
*/
#include "th01/th01.h"
#pragma option -2
#pragma option -O-
#pragma option -Z-
#include "th01/grps2xsc.c"
void egc_copy_wave_1_to_0(int x, int y, int len, int amp, int ph, int w, int h)
{
int row;
int t = ph;
for(row = 0; row < h; row++) {
int x_wave = (((long)amp * Sin8(t)) / 256) + x;
t += 256 / len;
egc_copy_rect_1_to_0(x_wave, y + row, w, 1);
}
}
void graph_copy_hline_mask_1_to_0(int x, int y, char *mask, int w)
{
vram_planar_8_pixels_t px8;
int col;
register int p = VRAM_OFFSET(x, y);
for(col = 0; col < w; col++, p++) {
if(mask[col]) {
graph_accesspage(1);
px8.B = mask[col] & VRAM_PLANE_B[p];
px8.R = mask[col] & VRAM_PLANE_R[p];
px8.G = mask[col] & VRAM_PLANE_G[p];
px8.E = mask[col] & VRAM_PLANE_E[p];
graph_accesspage(0);
grcg_setcolor_rmw(0);
VRAM_PLANE_B[p] = mask[col];
grcg_off();
VRAM_PLANE_B[p] |= px8.B;
VRAM_PLANE_R[p] |= px8.R;
VRAM_PLANE_G[p] |= px8.G;
VRAM_PLANE_E[p] |= px8.E;
}
}
}

View File

@ -6,6 +6,8 @@
#include "ReC98.h"
// Hardware
void egc_copy_rect_1_to_0(int x, int y, int w, int h);
void graph_accesspage_func(int page);
void grcg_setcolor_rmw(int color);
void grcg_off_func(void);

File diff suppressed because it is too large Load Diff

View File

@ -6921,7 +6921,7 @@ arg_4 = word ptr 0Ah
add ax, dx
mov di, ax
push 0Ah
call sub_EA71
call _grcg_setcolor_rmw
pop cx
xor si, si
jmp short loc_1F1EA
@ -6969,7 +6969,7 @@ loc_1F1F8:
loc_1F21B:
cmp si, 8
jl short loc_1F1F8
call sub_EB05
call _grcg_off_func
pop di
pop si
pop bp
@ -11507,7 +11507,7 @@ loc_218C1:
push 7
loc_218C7:
call sub_EA71
call _grcg_setcolor_rmw
pop cx
jmp short loc_218D8
; ---------------------------------------------------------------------------
@ -11542,7 +11542,7 @@ loc_218DE:
loc_2190D:
cmp [bp+var_2], 0Fh
jb short loc_218DE
call sub_EB05
call _grcg_off_func
pop di
pop si
leave
@ -23242,7 +23242,7 @@ loc_2802A:
add ax, 0FFFEh
push ax
pushd [dword_3982A]
call sub_11EA1
call _egc_copy_wave_1_to_0
add sp, 0Eh
loc_28082:
@ -23282,7 +23282,7 @@ loc_280AE:
loc_280D6:
pushd [dword_3982A]
call sub_11EA1
call _egc_copy_wave_1_to_0
mov word_39856, 0
mov word_3984E, 0
push 30000h
@ -26323,7 +26323,7 @@ loc_29BE5:
loc_29BE7:
add ax, word_3AC5E
push ax
call sub_EA71
call _grcg_setcolor_rmw
pop cx
les bx, _VRAM_PLANE_B
add bx, word_3AC5C
@ -26348,7 +26348,7 @@ loc_29C16:
loc_29C1D:
push 0Ch
call sub_EA71
call _grcg_setcolor_rmw
pop cx
xor di, di
jmp loc_29CAC
@ -26449,7 +26449,7 @@ loc_29CB8:
mov word_3AC5C, ax
loc_29D06:
call sub_EB05
call _grcg_off_func
inc [bp+var_2]
loc_29D0E:
@ -26641,7 +26641,7 @@ loc_29EA2:
sar ax, cl
and [bp+var_3], al
push 0Ch
call sub_EA71
call _grcg_setcolor_rmw
push 0
call _graph_accesspage_func
add sp, 6
@ -26714,7 +26714,7 @@ loc_29F62:
mov al, [si+1445h]
cbw
push ax
call sub_EA71
call _grcg_setcolor_rmw
push 0
call _graph_accesspage_func
add sp, 8
@ -26739,7 +26739,7 @@ loc_29FD6:
loc_29FD7:
cmp si, 1Eh
jl loc_29E46
call sub_EB05
call _grcg_off_func
loc_29FE3:
pop di
@ -27293,7 +27293,7 @@ loc_2A4D9:
sar ax, cl
and [bp+var_5], al
push 0Ch
call sub_EA71
call _grcg_setcolor_rmw
push 0
call _graph_accesspage_func
add sp, 8
@ -27382,7 +27382,7 @@ loc_2A618:
mov al, [si+1465h]
cbw
push ax
call sub_EA71
call _grcg_setcolor_rmw
push 0
call _graph_accesspage_func
add sp, 8
@ -27408,7 +27408,7 @@ loc_2A68A:
loc_2A68B:
cmp si, 1Eh
jl loc_2A4D9
call sub_EB05
call _grcg_off_func
loc_2A697:
pop di
@ -28913,7 +28913,7 @@ loc_2B3F4:
loc_2B4A2:
push 0Ch
call sub_EA71
call _grcg_setcolor_rmw
push 0
call _graph_accesspage_func
add sp, 4
@ -29082,7 +29082,7 @@ loc_2B671:
mov al, [si+1483h]
cbw
push ax
call sub_EA71
call _grcg_setcolor_rmw
push 0
call _graph_accesspage_func
add sp, 4
@ -29125,7 +29125,7 @@ loc_2B6D7:
loc_2B6D8:
cmp si, 1Eh
jl loc_2B3F4
call sub_EB05
call _grcg_off_func
loc_2B6E4:
pop di
@ -38189,13 +38189,13 @@ arg_4 = word ptr 0Ah
push bp
mov bp, sp
push 7
call sub_EA71
call _grcg_setcolor_rmw
push [bp+arg_4]
push [bp+arg_2]
push [bp+arg_0]
call sub_308A1
add sp, 8
call sub_EB05
call _grcg_off_func
pop bp
retf
sub_308E9 endp