[Decompilation] [th01] Alternating left/right-shift VRAM row page transition

Is that a correct word order? The main effect behind the transition to
the TOTLE screen, and all its fanciness comes from alternating shift
directions on every row. No wave code anywhere.

Part of P0212, funded by GhostRiderCog, Lmocinemod, and LeyDud.
This commit is contained in:
nmlgc 2022-08-09 21:53:28 +02:00
parent 613f340b33
commit bd8e9ffa2e
3 changed files with 63 additions and 106 deletions

View File

@ -198,5 +198,6 @@ static inline vram_offset_t vram_offset_divshift_wtf(screen_x_t x, vram_y_t y) {
typedef dots16_t egc_temp_t;
#define egc_chunk(offset) \
/* For code generation reasons, [offset] must NOT be parenthesized here */ \
VRAM_CHUNK(B, offset, 16)
// ----------

View File

@ -4,6 +4,7 @@
#include "planar.h"
#include "th01/formats/ptn.hpp"
extern "C" {
#include "th01/hardware/graph.h"
#include "th01/snd/mdrv2.h"
}
@ -65,3 +66,59 @@ void pascal near totle_metric_digit_animate(
ptn_sloppy_unput_before_alpha_put = false;
}
static const int ROWSHIFT_CHUNK_DOTS = (EGC_REGISTER_DOTS * 2);
static const int ROWSHIFT_CHUNK_SIZE = (EGC_REGISTER_SIZE * 2);
// Shifts [ROWSHIFT_CHUNK_DOTS] pixels of the given row on VRAM page 0 from
// either the right edge of VRAM to the left or vice versa depending on whether
// [y] is even or odd, then fills the freed-up chunk with a chunk of pixels
// from VRAM page 1 that start [transferred_offset] bytes away from the shifted
// edge.
// Assumes that VRAM page 0 is accessed, and that the EGC is active and
// initialized for a copy.
void pascal near egc_pagetrans_rowshift_alternating(
vram_y_t y, vram_byte_amount_t transferred_offset
)
{
enum {
CHUNK_OFFSET_LEFT = (0 * EGC_REGISTER_SIZE),
CHUNK_OFFSET_RIGHT = (1 * EGC_REGISTER_SIZE),
};
uvram_offset_t vo_p0;
egc_temp_t dots;
vram_byte_amount_t negative_chunk_delta; // negative for extra confusion?
union {
vram_dword_amount_t num;
vram_offset_t vo_p1;
} u1;
// Shift
if(y & 1) {
vo_p0 = vram_offset_muldiv((RES_X - ROWSHIFT_CHUNK_DOTS), y);
negative_chunk_delta = -ROWSHIFT_CHUNK_SIZE;
} else {
vo_p0 = vram_offset_muldiv(0, y);
negative_chunk_delta = ROWSHIFT_CHUNK_SIZE;
}
for(u1.num = 0; u1.num < ((ROW_SIZE / ROWSHIFT_CHUNK_SIZE) - 1); u1.num++) {
vo_p0 += negative_chunk_delta;
// Inconsistent parentheses? Blame code generation.
dots = egc_chunk(vo_p0 + CHUNK_OFFSET_LEFT);
egc_chunk((vo_p0 - negative_chunk_delta + CHUNK_OFFSET_LEFT)) = dots;
dots = egc_chunk(vo_p0 + CHUNK_OFFSET_RIGHT);
egc_chunk((vo_p0 - negative_chunk_delta + CHUNK_OFFSET_RIGHT)) = dots;
}
// Transfer new pixels
u1.vo_p1 = ((negative_chunk_delta > 0)
? ((y * ROW_SIZE) + transferred_offset)
: ((y * ROW_SIZE) + ROW_SIZE - ROWSHIFT_CHUNK_SIZE - transferred_offset)
);
graph_accesspage_func(1); dots = egc_chunk(u1.vo_p1 + CHUNK_OFFSET_LEFT);
graph_accesspage_func(0); egc_chunk(vo_p0 + CHUNK_OFFSET_LEFT) = dots;
graph_accesspage_func(1); dots = egc_chunk(u1.vo_p1 + CHUNK_OFFSET_RIGHT);
graph_accesspage_func(0); egc_chunk(vo_p0 + CHUNK_OFFSET_RIGHT) = dots;
}

View File

@ -2896,6 +2896,8 @@ main_17_TEXT ends
main_18_TEXT segment byte public 'CODE' use16
@TOTLE_METRIC_DIGIT_ANIMATE$QIII procdesc pascal near \
digit:word, place_and_top:dword
@EGC_PAGETRANS_ROWSHIFT_ALTERNATI$QII procdesc pascal near \
y: word, transferred_chunk_left:word
main_18_TEXT ends
main_18__TEXT segment byte public 'CODE' use16
@ -2903,109 +2905,6 @@ main_18__TEXT segment byte public 'CODE' use16
;org 0Bh
assume es:nothing, ss:nothing, ds:_DATA, fs:nothing, gs:nothing
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_12C62 proc near
var_4 = word ptr -4
var_2 = word ptr -2
arg_0 = word ptr 4
arg_2 = word ptr 6
enter 4, 0
push si
push di
test byte ptr [bp+arg_2], 1
jz short loc_12C80
mov ax, [bp+arg_2]
imul ax, 50h
add ax, 4Ch ; 'L'
mov si, ax
mov [bp+var_2], 0FFFCh
jmp short loc_12C8D
; ---------------------------------------------------------------------------
loc_12C80:
mov ax, [bp+arg_2]
imul ax, 50h
mov si, ax
mov [bp+var_2], 4
loc_12C8D:
mov [bp+var_4], 0
jmp short loc_12CCC
; ---------------------------------------------------------------------------
loc_12C94:
add si, [bp+var_2]
les bx, _VRAM_PLANE_B
add bx, si
mov di, es:[bx]
mov ax, si
sub ax, [bp+var_2]
mov bx, word ptr _VRAM_PLANE_B
add bx, ax
mov es:[bx], di
mov bx, word ptr _VRAM_PLANE_B
add bx, si
mov di, es:[bx+2]
mov ax, si
sub ax, [bp+var_2]
add ax, 2
mov bx, word ptr _VRAM_PLANE_B
add bx, ax
mov es:[bx], di
inc [bp+var_4]
loc_12CCC:
cmp [bp+var_4], 13h
jl short loc_12C94
cmp [bp+var_2], 0
jle short loc_12CE3
mov ax, [bp+arg_2]
imul ax, 50h
add ax, [bp+arg_0]
jmp short loc_12CEF
; ---------------------------------------------------------------------------
loc_12CE3:
mov ax, [bp+arg_2]
imul ax, 50h
add ax, 4Ch ; 'L'
sub ax, [bp+arg_0]
loc_12CEF:
mov [bp+var_4], ax
push 1
call _graph_accesspage_func
les bx, _VRAM_PLANE_B
add bx, [bp+var_4]
mov di, es:[bx]
push 0
call _graph_accesspage_func
les bx, _VRAM_PLANE_B
add bx, si
mov es:[bx], di
push 1
call _graph_accesspage_func
les bx, _VRAM_PLANE_B
add bx, [bp+var_4]
mov di, es:[bx+2]
push 0
call _graph_accesspage_func
add sp, 8
les bx, _VRAM_PLANE_B
add bx, si
mov es:[bx+2], di
pop di
pop si
leave
retn 4
sub_12C62 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
@ -3071,13 +2970,13 @@ loc_12DC9:
add bx, ax
cmp word ptr es:[bx], 0
jz short loc_12E0C
push si
push si ; y
mov ax, si
add ax, ax
les bx, [bp+_font]
add bx, ax
push word ptr es:[bx]
call sub_12C62
push word ptr es:[bx] ; transferred_chunk_left
call @egc_pagetrans_rowshift_alternati$qii
mov ax, si
add ax, ax
les bx, [bp+_font]