From 34a5f4d1838daaed13e0f3e1c71d70650991a479 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Thu, 6 Aug 2020 19:02:02 +0200 Subject: [PATCH] [Decompilation] [th01] Boss entities: Unaligned 1-line blitting "Oh wait, actually, I *do* want to blit 8 pixels at a time in some cases" :zunpet: First time in a long while that the VRAM access macros couldn't do the job, because code generation wants *both* pointer arithmetic *and* subscripts within the same expression. But *come on*, just blit the 16 pixels for the byte-aligned case! Part of P0107, funded by Yanga. --- ReC98.h | 1 + th01/main/boss/entity.cpp | 71 +++++++++- th01/main/boss/entity.hpp | 4 + th01_reiiden.asm | 284 ++------------------------------------ 4 files changed, 83 insertions(+), 277 deletions(-) diff --git a/ReC98.h b/ReC98.h index 2abe5cf0..5ea622d4 100644 --- a/ReC98.h +++ b/ReC98.h @@ -77,6 +77,7 @@ typedef union { struct { int8_t lo, hi; } byte; + uint8_t u[2]; int16_t v; } twobyte_t; diff --git a/th01/main/boss/entity.cpp b/th01/main/boss/entity.cpp index 7ab286cc..30603d88 100644 --- a/th01/main/boss/entity.cpp +++ b/th01/main/boss/entity.cpp @@ -1,7 +1,4 @@ -#include -#include "platform.h" -#include "pc98.h" -#include "planar.h" +#include "ReC98.h" #include "th01/hardware/graph.h" #include "th01/formats/sprfmt_h.hpp" #include "th01/formats/pf.hpp" @@ -129,4 +126,70 @@ void CBossEntity::put_8(int left, int top, int image) const } } } +void CBossEntity::put_1line(int left, int y, int image, int row) const +{ + int16_t vram_offset_row = vram_offset_shift(left, y); + int bos_word_x; + size_t bos_p = 0; + int16_t intended_y; + char first_bit = (left & (BYTE_DOTS - 1)); + char other_shift = ((1 * BYTE_DOTS) - first_bit); + + bos_image_t &bos = bos_images[bos_slot].image[image]; + if(bos_image_count <= image) { + return; + } + + int16_t vram_offset = vram_offset_row; + intended_y = vram_intended_y_for(vram_offset_row, left); + + bos_p = ((vram_w / 2) * row); + for(bos_word_x = 0; (vram_w / 2) > bos_word_x; bos_word_x++) { + if((vram_offset / ROW_SIZE) == intended_y) { + struct { + twobyte_t alpha, B, R, G, E; + } cur; + + cur.alpha.v = ~bos.alpha[bos_p]; + cur.B.v = bos.planes.B[bos_p]; + cur.R.v = bos.planes.R[bos_p]; + cur.G.v = bos.planes.G[bos_p]; + cur.E.v = bos.planes.E[bos_p]; + + #define vram_byte(plane, byte) \ + (VRAM_PLANE_##plane + vram_offset)[byte] + if(first_bit == 0) { + for(register int byte = 0; byte < sizeof(dots16_t); byte++) { + grcg_setcolor_rmw(0); + vram_byte(B, byte) = cur.alpha.u[byte]; + grcg_off(); + + vram_byte(B, byte) |= cur.B.u[byte]; + vram_byte(R, byte) |= cur.R.u[byte]; + vram_byte(G, byte) |= cur.G.u[byte]; + vram_byte(E, byte) |= cur.E.u[byte]; + } + } else { + for(register int byte = 0; byte < sizeof(dots16_t); byte++) { + grcg_setcolor_rmw(0); + vram_byte(B, byte + 0) = (cur.alpha.u[byte] >> first_bit); + vram_byte(B, byte + 1) = (cur.alpha.u[byte] << other_shift); + grcg_off(); + + vram_byte(B, byte + 0) |= (cur.B.u[byte] >> first_bit); + vram_byte(R, byte + 0) |= (cur.R.u[byte] >> first_bit); + vram_byte(G, byte + 0) |= (cur.G.u[byte] >> first_bit); + vram_byte(E, byte + 0) |= (cur.E.u[byte] >> first_bit); + vram_byte(B, byte + 1) |= (cur.B.u[byte] << other_shift); + vram_byte(R, byte + 1) |= (cur.R.u[byte] << other_shift); + vram_byte(G, byte + 1) |= (cur.G.u[byte] << other_shift); + vram_byte(E, byte + 1) |= (cur.E.u[byte] << other_shift); + } + } + #undef vram_byte + } + vram_offset += 2; + bos_p++; + } +} /// -------- diff --git a/th01/main/boss/entity.hpp b/th01/main/boss/entity.hpp index 68d3923b..1ecc849a 100644 --- a/th01/main/boss/entity.hpp +++ b/th01/main/boss/entity.hpp @@ -54,5 +54,9 @@ public: // Blits [image] to (⌊left/8⌋*8, top). // Additionally clips at the bottom edge of VRAM. void put_8(int left, int top, int image) const; + + // Blits line #[row] of [image] to (left, top). + // Additionally clips at the bottom edge of VRAM. + void put_1line(int left, int y, int image, int row) const; /// -------- }; diff --git a/th01_reiiden.asm b/th01_reiiden.asm index 593d8e41..4d4cbe96 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -8876,6 +8876,7 @@ main_21_TEXT segment byte public 'CODE' use16 extern @CBossEntity@bos_load$qxnxci:proc extern @CBossEntity@bos_metadata_get$xqmimuct1t1:proc extern @CBossEntity@put_8$xqiii:proc + extern @CBossEntity@put_1line$xqiiii:proc main_21_TEXT ends main_21__TEXT segment byte public 'CODE' use16 @@ -8883,269 +8884,6 @@ main_21__TEXT segment byte public 'CODE' use16 ;org 4 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_15A37 proc far - -var_18 = word ptr -18h -var_16 = word ptr -16h -var_14 = word ptr -14h -var_12 = word ptr -12h -var_10 = word ptr -10h -@@bos = dword ptr -0Eh -var_A = byte ptr -0Ah -var_9 = byte ptr -9 -var_8 = word ptr -8 -var_6 = word ptr -6 -var_4 = word ptr -4 -var_2 = word ptr -2 -arg_0 = dword ptr 6 -arg_4 = word ptr 0Ah -arg_6 = word ptr 0Ch -@@image = word ptr 0Eh -arg_A = word ptr 10h - - enter 18h, 0 - push si - push di - mov ax, [bp+arg_4] - sar ax, 3 - mov dx, [bp+arg_6] - shl dx, 6 - add ax, dx - mov dx, [bp+arg_6] - shl dx, 4 - add ax, dx - mov [bp+var_2], ax - mov [bp+var_6], 0 - mov al, byte ptr [bp+arg_4] - and al, 7 - mov [bp+var_9], al - mov al, 8 - sub al, [bp+var_9] - mov [bp+var_A], al - les bx, [bp+arg_0] - mov al, es:[bx+31h] - mov ah, 0 - imul ax, size bos_t - mov dx, [bp+@@image] - imul dx, size bos_image_t - add ax, dx - add ax, offset _bos_images - mov word ptr [bp+@@bos+2], ds - mov word ptr [bp+@@bos], ax - mov ax, es:[bx+20h] - cmp ax, [bp+@@image] - jle loc_15C7C - mov di, [bp+var_2] - cmp [bp+arg_4], 0 - jge short loc_15AA9 - mov ax, [bp+var_2] - mov bx, 50h ; 'P' - cwd - idiv bx - inc ax - jmp short loc_15AB2 -; --------------------------------------------------------------------------- - -loc_15AA9: - mov ax, [bp+var_2] - mov bx, 50h ; 'P' - cwd - idiv bx - -loc_15AB2: - mov [bp+var_8], ax - les bx, [bp+arg_0] - mov ax, es:[bx+8] - cwd - sub ax, dx - sar ax, 1 - imul [bp+arg_A] - mov [bp+var_6], ax - mov [bp+var_4], 0 - jmp loc_15C69 -; --------------------------------------------------------------------------- - -loc_15ACF: - mov ax, di - mov bx, 50h ; 'P' - cwd - idiv bx - cmp ax, [bp+var_8] - jnz loc_15C60 - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_alpha] - mov ax, [bp+var_6] - add ax, ax - add bx, ax - mov ax, es:[bx] - not ax - mov [bp+var_18], ax - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_B] - mov ax, [bp+var_6] - add ax, ax - add bx, ax - mov ax, es:[bx] - mov [bp+var_16], ax - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_R] - mov ax, [bp+var_6] - add ax, ax - add bx, ax - mov ax, es:[bx] - mov [bp+var_14], ax - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_G] - mov ax, [bp+var_6] - add ax, ax - add bx, ax - mov ax, es:[bx] - mov [bp+var_12], ax - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_E] - mov ax, [bp+var_6] - add ax, ax - add bx, ax - mov ax, es:[bx] - mov [bp+var_10], ax - cmp [bp+var_9], 0 - jnz short loc_15B9F - xor si, si - jmp short loc_15B97 -; --------------------------------------------------------------------------- - -loc_15B4D: - call _grcg_setcolor_rmw stdcall, 0 - pop cx - mov al, byte ptr [bp+si+var_18] - les bx, _VRAM_PLANE_B - add bx, di - mov es:[bx+si], al - call _grcg_off_func - mov al, byte ptr [bp+si+var_16] - les bx, _VRAM_PLANE_B - add bx, di - or es:[bx+si], al - mov al, byte ptr [bp+si+var_14] - les bx, _VRAM_PLANE_R - add bx, di - or es:[bx+si], al - mov al, byte ptr [bp+si+var_12] - les bx, _VRAM_PLANE_G - add bx, di - or es:[bx+si], al - mov al, byte ptr [bp+si+var_10] - les bx, _VRAM_PLANE_E - add bx, di - or es:[bx+si], al - inc si - -loc_15B97: - cmp si, 2 - jl short loc_15B4D - jmp loc_15C60 -; --------------------------------------------------------------------------- - -loc_15B9F: - xor si, si - jmp loc_15C59 -; --------------------------------------------------------------------------- - -loc_15BA4: - call _grcg_setcolor_rmw stdcall, 0 - pop cx - mov al, byte ptr [bp+si+var_18] - mov ah, 0 - mov cl, [bp+var_9] - sar ax, cl - les bx, _VRAM_PLANE_B - add bx, di - mov es:[bx+si], al - mov al, byte ptr [bp+si+var_18] - mov cl, [bp+var_A] - shl al, cl - mov bx, word ptr _VRAM_PLANE_B - add bx, di - mov es:[bx+si+1], al - call _grcg_off_func - mov al, byte ptr [bp+si+var_16] - mov ah, 0 - mov cl, [bp+var_9] - sar ax, cl - les bx, _VRAM_PLANE_B - add bx, di - or es:[bx+si], al - mov al, byte ptr [bp+si+var_14] - mov ah, 0 - sar ax, cl - les bx, _VRAM_PLANE_R - add bx, di - or es:[bx+si], al - mov al, byte ptr [bp+si+var_12] - mov ah, 0 - sar ax, cl - les bx, _VRAM_PLANE_G - add bx, di - or es:[bx+si], al - mov al, byte ptr [bp+si+var_10] - mov ah, 0 - sar ax, cl - les bx, _VRAM_PLANE_E - add bx, di - or es:[bx+si], al - mov al, byte ptr [bp+si+var_16] - mov cl, [bp+var_A] - shl al, cl - les bx, _VRAM_PLANE_B - add bx, di - or es:[bx+si+1], al - mov al, byte ptr [bp+si+var_14] - shl al, cl - les bx, _VRAM_PLANE_R - add bx, di - or es:[bx+si+1], al - mov al, byte ptr [bp+si+var_12] - shl al, cl - les bx, _VRAM_PLANE_G - add bx, di - or es:[bx+si+1], al - mov al, byte ptr [bp+si+var_10] - shl al, cl - les bx, _VRAM_PLANE_E - add bx, di - or es:[bx+si+1], al - inc si - -loc_15C59: - cmp si, 2 - jl loc_15BA4 - -loc_15C60: - add di, 2 - inc [bp+var_6] - inc [bp+var_4] - -loc_15C69: - les bx, [bp+arg_0] - mov ax, es:[bx+8] - cwd - sub ax, dx - sar ax, 1 - cmp ax, [bp+var_4] - jg loc_15ACF - -loc_15C7C: - pop di - pop si - leave - retf -sub_15A37 endp - - ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame @@ -9976,11 +9714,11 @@ sub_1612E endp sub_16344 proc far -var_2 = word ptr -2 -arg_0 = dword ptr 6 +@@left = word ptr -2 +@@CBossEntity = dword ptr 6 arg_4 = word ptr 0Ah -arg_6 = word ptr 0Ch -arg_8 = word ptr 0Eh +@@top = word ptr 0Ch +@@image = word ptr 0Eh arg_A = word ptr 10h arg_C = word ptr 12h arg_E = word ptr 14h @@ -10004,19 +9742,19 @@ loc_16351: cdq idiv ebx add ax, [bp+arg_4] - mov [bp+var_2], ax + mov [bp+@@left], ax mov ax, 256 cwd idiv [bp+arg_A] add di, ax push si - push [bp+arg_8] - mov ax, [bp+arg_6] + push [bp+@@image] + mov ax, [bp+@@top] add ax, si push ax - push [bp+var_2] - pushd [bp+arg_0] - call sub_15A37 + push [bp+@@left] + pushd [bp+@@CBossEntity] + call @CBossEntity@put_1line$xqiiii add sp, 0Ch inc si