diff --git a/planar.h b/planar.h index b5605bbf..f4262641 100644 --- a/planar.h +++ b/planar.h @@ -64,11 +64,14 @@ extern dots8_t *VRAM_PLANE_G; extern dots8_t *VRAM_PLANE_R; extern dots8_t *VRAM_PLANE_E; +#define VRAM_OFFSET_SHIFT(x, y) \ + (x >> 3) + (y << 6) + (y << 4) + #ifdef __cplusplus // MODDERS: Replace with a single function static inline unsigned int vram_offset_shift(int x, int y) { - return (x >> 3) + (y << 6) + (y << 4); + return VRAM_OFFSET_SHIFT(x, y); } static inline unsigned int vram_offset_muldiv(int x, int y) diff --git a/th01/main/boss/entity.cpp b/th01/main/boss/entity.cpp index a193c9d4..5c9d5f58 100644 --- a/th01/main/boss/entity.cpp +++ b/th01/main/boss/entity.cpp @@ -236,6 +236,12 @@ void pascal near vram_put_unaligned_bg_fg( vram_put_bg_fg(fg.G, VRAM_PLANE_G, vram_offset, bg.G); \ vram_put_bg_fg(fg.E, VRAM_PLANE_E, vram_offset, bg.E); +#define vram_put_bg_word_planar(vram_offset, bg, planes, p) \ + vram_put_bg_fg(planes.B[p], VRAM_PLANE_B, vram_offset, bg.B); \ + vram_put_bg_fg(planes.R[p], VRAM_PLANE_R, vram_offset, bg.R); \ + vram_put_bg_fg(planes.G[p], VRAM_PLANE_G, vram_offset, bg.G); \ + vram_put_bg_fg(planes.E[p], VRAM_PLANE_E, vram_offset, bg.E); + #define vram_put_unaligned_bg_fg_planar(vram_offset, bg, fg, first_bit) \ vram_put_unaligned_bg_fg(fg.B, VRAM_PLANE_B, vram_offset, bg.B, first_bit); \ vram_put_unaligned_bg_fg(fg.R, VRAM_PLANE_R, vram_offset, bg.R, first_bit); \ @@ -453,4 +459,47 @@ void CBossEntity::egc_sloppy_wave_unput_double_broken( } } } + +void CBossEntity::unput_and_put_16x8_8(int bos_left, int bos_top) const +{ + int16_t vram_offset_row = vram_offset_shift(cur_left, cur_top); + int bos_row; + size_t bos_p = 0; + int intended_y; + int image = bos_image; + Planar bg_masked; + bos_image_t &bos = bos_images[bos_slot].image[image]; + + // Yes, the macro form. Out of all places that could have required it, it + // had to be an originally unused function… + vram_offset_row += VRAM_OFFSET_SHIFT(bos_left, bos_top); + bos_p = (((vram_w / 2) * bos_top) + (bos_left / 16)); + + if(bos_image_count <= image) { + return; + } + + for(bos_row = 0; bos_row < 8; bos_row++) { + int16_t vram_offset = vram_offset_row; + // Note the difference between this and vram_offset_at_intended_y_16()! + intended_y = (bos_left < 0) + ? ((vram_offset_row / ROW_SIZE) - 1) + : ((vram_offset_row / ROW_SIZE) - 0); + if( + (((vram_offset + 1) / ROW_SIZE) == intended_y) && + (vram_offset >= 0) // Clip at the top edge + ) { + graph_accesspage_func(1); + vram_snap_masked_planar(bg_masked, vram_offset, bos.alpha[bos_p]); + graph_accesspage_func(0); + vram_put_bg_word_planar(vram_offset, bg_masked, bos.planes, bos_p); + vram_offset += 2; + } + bos_p += (vram_w / 2); + vram_offset_row += ROW_SIZE; + if(vram_offset_row >= PLANE_SIZE) { // Clip at the bottom edge + break; + } + } +} /// -------- diff --git a/th01/main/boss/entity.hpp b/th01/main/boss/entity.hpp index 5d0ca619..bfa00974 100644 --- a/th01/main/boss/entity.hpp +++ b/th01/main/boss/entity.hpp @@ -96,5 +96,13 @@ public: int left_2, int len_2, int amp_2, int phase_2 ) const; + + // Blits the 16×8 pixels of [bos_image] in [bos_slot] starting at + // (bos_left, bos_top), relative to the top-left corner of the sprite, to + // ((⌊cur_left/8⌋ + bos_left/8⌋) * 8, (cur_top + bos_top)) + // after precisely restoring pixels according to the alpha mask of the + // pixels to be blitted from VRAM page 1. + // Additionally clips at the top and bottom edges of VRAM. + void unput_and_put_16x8_8(int bos_left, int bos_top) const; /// -------- }; diff --git a/th01_reiiden.asm b/th01_reiiden.asm index bde48969..ac8c3e93 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -8876,9 +8876,6 @@ 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 - VRAM_SNAP_MASKED procdesc pascal near - VRAM_PUT_BG_FG procdesc pascal near \ - fg:word, plane:dword, vram_offset:word, bg_masked:word extern @CBossEntity@unput_and_put_1line$xqiiii:proc extern @CBossEntity@unput_and_put_8$xqiii:proc extern @CBossEntity@wave_put$xqiiiiii:proc @@ -8889,211 +8886,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_164E6 proc far - -@@bos = dword ptr -14h -var_10 = word ptr -10h -var_E = word ptr -0Eh -var_C = word ptr -0Ch -var_A = word ptr -0Ah -@@image = 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 - - enter 14h, 0 - push si - push di - les bx, [bp+arg_0] - mov ax, es:[bx] - sar ax, 3 - mov dx, es:[bx+2] - shl dx, 6 - add ax, dx - mov dx, es:[bx+2] - shl dx, 4 - add ax, dx - mov [bp+var_2], ax - xor di, di - mov ax, es:[bx+24h] - mov [bp+@@image], ax - 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, [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 - add [bp+var_2], ax - mov ax, es:[bx+8] - cwd - sub ax, dx - sar ax, 1 - imul [bp+arg_6] - push ax - mov ax, [bp+arg_4] - mov bx, 10h - cwd - idiv bx - pop dx - add dx, ax - mov di, dx - mov bx, word ptr [bp+arg_0] - mov ax, es:[bx+20h] - cmp ax, [bp+@@image] - jle loc_166CE - mov [bp+var_4], 0 - jmp loc_166C6 -; --------------------------------------------------------------------------- - -loc_16578: - mov si, [bp+var_2] - cmp [bp+arg_4], 0 - jge short loc_1658D - mov ax, [bp+var_2] - mov bx, 50h ; 'P' - cwd - idiv bx - dec ax - jmp short loc_16596 -; --------------------------------------------------------------------------- - -loc_1658D: - mov ax, [bp+var_2] - mov bx, 50h ; 'P' - cwd - idiv bx - -loc_16596: - mov [bp+var_6], ax - lea ax, [si+1] - mov bx, 50h ; 'P' - cwd - idiv bx - cmp ax, [bp+var_6] - jnz loc_166AA - or si, si - jl loc_166AA - push 1 - call _graph_accesspage_func - push ss - lea ax, [bp+var_10] - push ax - pushd [_VRAM_PLANE_B] - push si - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_alpha] - mov ax, di - add ax, ax - add bx, ax - push word ptr es:[bx] - call vram_snap_masked - push ss - lea ax, [bp+var_E] - push ax - pushd [_VRAM_PLANE_R] - push si - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_alpha] - mov ax, di - add ax, ax - add bx, ax - push word ptr es:[bx] - call vram_snap_masked - push ss - lea ax, [bp+var_C] - push ax - pushd [_VRAM_PLANE_G] - push si - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_alpha] - mov ax, di - add ax, ax - add bx, ax - push word ptr es:[bx] - call vram_snap_masked - push ss - lea ax, [bp+var_A] - push ax - pushd [_VRAM_PLANE_E] - push si - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_alpha] - mov ax, di - add ax, ax - add bx, ax - push word ptr es:[bx] - call vram_snap_masked - push 0 - call _graph_accesspage_func - add sp, 4 - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_B] - mov ax, di - add ax, ax - add bx, ax - call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_B], si, [bp+var_10] - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_R] - mov ax, di - add ax, ax - add bx, ax - call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_R], si, [bp+var_E] - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_G] - mov ax, di - add ax, ax - add bx, ax - call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_G], si, [bp+var_C] - les bx, [bp+@@bos] - les bx, es:[bx+bos_image_t.BOS_E] - mov ax, di - add ax, ax - add bx, ax - call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_E], si, [bp+var_A] - add si, 2 - -loc_166AA: - les bx, [bp+arg_0] - mov ax, es:[bx+8] - cwd - sub ax, dx - sar ax, 1 - add di, ax - add [bp+var_2], 50h ; 'P' - cmp [bp+var_2], 7D00h - jge short loc_166CE - inc [bp+var_4] - -loc_166C6: - cmp [bp+var_4], 8 - jl loc_16578 - -loc_166CE: - pop di - pop si - leave - retf -sub_164E6 endp - - ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame