From 415bef11762f24d67c1606705d0aeea81b39eba1 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Tue, 16 Apr 2024 15:05:14 +0200 Subject: [PATCH] [Maintenance] [th03] SPRITE16: Move game-level code into `main/` We'd like t have a method to set the clipping coordinates from a player ID, but such a method requires a dependency on `playfld.hpp` in `main`. `SPF_DOWNWARDS_COLUMN` is kind of game-specific to begin with, too. Part of P0280, funded by [Anonymous], Blue Bolt, and JonathKane. --- th03/main/player/player.cpp | 2 +- th03/main/sprite16.cpp | 163 ++++++++++++++++++++++++++++++++++ th03/{ => main}/sprite16.hpp | 0 th03/main_011.cpp | 2 +- th03/sprite16.cpp | 164 +---------------------------------- th03/sprites/main_s16.hpp | 2 +- 6 files changed, 167 insertions(+), 166 deletions(-) create mode 100644 th03/main/sprite16.cpp rename th03/{ => main}/sprite16.hpp (100%) diff --git a/th03/main/player/player.cpp b/th03/main/player/player.cpp index ef03fe20..12265eb5 100644 --- a/th03/main/player/player.cpp +++ b/th03/main/player/player.cpp @@ -6,10 +6,10 @@ #include "decomp.hpp" #include "th03/common.h" #include "th03/playchar.hpp" -#include "th03/sprite16.hpp" #include "th03/hardware/input.h" #include "th03/main/playfld.hpp" #include "th03/main/collmap.hpp" +#include "th03/main/sprite16.hpp" #include "th03/main/chars/speed.hpp" #include "th03/main/player/shot.hpp" #include "th03/main/player/player.hpp" diff --git a/th03/main/sprite16.cpp b/th03/main/sprite16.cpp new file mode 100644 index 00000000..d7b4253b --- /dev/null +++ b/th03/main/sprite16.cpp @@ -0,0 +1,163 @@ +/* ReC98 + * ----- + * SPRITE16 display calls + */ + +#pragma option -zCSHARED -k- + +#include "platform.h" +#include "x86real.h" +#include "pc98.h" +#include "planar.h" +#include "master.hpp" +#include "platform/x86real/flags.hpp" +#include "libs/sprite16/sprite16.h" +extern "C" { +#include "th03/main/sprite16.hpp" + +void pascal sprite16_sprites_commit(void) +{ + sprite16_sprites_copy_page(1); + graph_accesspage(0); + _AH = SPRITE16_GENERATE_ALPHA; + geninterrupt(SPRITE16); +} + +// Register variables; declare them as local ones and remove this block when +// porting away from 16-bit x86 +#define sprite_offset_local (_DI) +#define putpos_left static_cast(_DX) +#define putpos_right static_cast(_BX) +#define putpos_right_high (_BH) +#define clip_left static_cast(_SI) +#define clip_right static_cast(_CX) +#define put_w_words (_AL) +#define should_draw_column (_SI) + +#define SETUP_VARS(left, top, so) \ + sprite_offset_local = so; \ + putpos_left = left; \ + put_w_words = sprite16_put_w.v; \ + putpos_right_high ^= putpos_right_high; \ + static_cast(putpos_right) = put_w_words; \ + putpos_right <<= 4; \ + putpos_right += putpos_left; \ + clip_left = sprite16_clip_left; \ + clip_right = sprite16_clip_right; + +#define CALL_PUT(left, top, put_w_words, so) \ + _AH = SPRITE16_PUT; \ + _DX = left; \ + _BX = top; \ + static_cast(_BX) >>= 1; \ + _AL = put_w_words; \ + _CX = sprite16_put_h; \ + _DI = so; \ + geninterrupt(SPRITE16); \ + +#define CLIP_LEFT_PART \ + do { \ + putpos_left += 16; \ + put_w_words--; \ + if(FLAGS_ZERO) { \ + return; \ + } \ + sprite_offset_local += (16 / 8); \ + } while(putpos_left < clip_left); + +#define CLIP_RIGHT_PART \ + do { \ + putpos_right -= 16; \ + put_w_words--; \ + if(FLAGS_ZERO) { \ + return; \ + } \ + } while(putpos_right >= clip_right); + +void pascal sprite16_put(screen_x_t left, screen_y_t top, sprite16_offset_t so) +{ + SETUP_VARS(left, top, so); + if(putpos_right < clip_right) { + if(putpos_left >= clip_left) { +put: + CALL_PUT(putpos_left, top, put_w_words, sprite_offset_local); + return; + } else if(putpos_right < clip_left) { + return; + } + // Sprite starts left of `clip_left` + CLIP_LEFT_PART; + goto put; + } else if(putpos_left >= clip_right) { + return; + } + // Sprite ends right of `clip_right` + CLIP_RIGHT_PART; + goto put; +} + +#pragma codestring "\x90" + +void pascal sprite16_putx( + screen_x_t left, + screen_y_t top, + sprite16_offset_t so, + sprite16_put_func_t func +) +{ + SETUP_VARS(left, top, so); + if(putpos_right < clip_right) { + if(putpos_left >= clip_left) { +put: + _AH = SPRITE16_PUT; + _DX = putpos_left; + _BX = top; + static_cast(_BX) >>= 1; + _AL = put_w_words; + _CX = sprite16_put_h; + _DI = sprite_offset_local; + while(1) { + should_draw_column = func; + geninterrupt(SPRITE16); + should_draw_column--; + if(FLAGS_ZERO) { + return; + } + _BX += _CX; + asm { cmp bx, SPRITE16_RES_Y; } + asm { jge end; } + } + } else if(putpos_right < clip_left) { + return; + } + // Sprite starts left of `clip_left` + CLIP_LEFT_PART; + goto put; + } else if(putpos_left >= clip_right) { + return; + } + // Sprite ends right of `clip_right` + CLIP_RIGHT_PART; + goto put; +end: +} + +#pragma codestring "\x90" + +void pascal sprite16_put_noclip( + screen_x_t left, screen_y_t top, sprite16_offset_t so +) +{ + // A completely useless SETUP_VARS variant without the `put_w_words` + // assignment, which actually makes it incorrect... + sprite_offset_local = so; + putpos_left = left; + putpos_right_high ^= putpos_right_high; + static_cast(putpos_right) = put_w_words; + putpos_right <<= 4; + putpos_right += putpos_left; + + CALL_PUT(putpos_left, top, sprite16_put_w.v, sprite_offset_local); +} + +} diff --git a/th03/sprite16.hpp b/th03/main/sprite16.hpp similarity index 100% rename from th03/sprite16.hpp rename to th03/main/sprite16.hpp diff --git a/th03/main_011.cpp b/th03/main_011.cpp index 0c1cc0c6..4490fa46 100644 --- a/th03/main_011.cpp +++ b/th03/main_011.cpp @@ -7,8 +7,8 @@ extern "C" { #include "platform.h" #include "pc98.h" #include "th03/common.h" -#include "th03/sprite16.hpp" #include "th03/main/playfld.hpp" +#include "th03/main/sprite16.hpp" #include "th03/main/player/shot.hpp" void pascal near shots_update(void) diff --git a/th03/sprite16.cpp b/th03/sprite16.cpp index 1c3f9ca0..6e23bdde 100644 --- a/th03/sprite16.cpp +++ b/th03/sprite16.cpp @@ -1,163 +1 @@ -/* ReC98 - * ----- - * SPRITE16 display calls - */ - -#pragma option -zCSHARED -k- - -#include "platform.h" -#include "x86real.h" -#include "pc98.h" -#include "planar.h" -#include "master.hpp" -#include "platform/x86real/flags.hpp" -#include "libs/sprite16/sprite16.h" -extern "C" { -#include "th03/sprite16.hpp" - -void pascal sprite16_sprites_commit(void) -{ - sprite16_sprites_copy_page(1); - graph_accesspage(0); - _AH = SPRITE16_GENERATE_ALPHA; - geninterrupt(SPRITE16); -} - -// Register variables; declare them as local ones and remove this block when -// porting away from 16-bit x86 -#define sprite_offset_local (_DI) -#define putpos_left static_cast(_DX) -#define putpos_right static_cast(_BX) -#define putpos_right_high (_BH) -#define clip_left static_cast(_SI) -#define clip_right static_cast(_CX) -#define put_w_words (_AL) -#define should_draw_column (_SI) - -#define SETUP_VARS(left, top, so) \ - sprite_offset_local = so; \ - putpos_left = left; \ - put_w_words = sprite16_put_w.v; \ - putpos_right_high ^= putpos_right_high; \ - static_cast(putpos_right) = put_w_words; \ - putpos_right <<= 4; \ - putpos_right += putpos_left; \ - clip_left = sprite16_clip_left; \ - clip_right = sprite16_clip_right; - -#define CALL_PUT(left, top, put_w_words, so) \ - _AH = SPRITE16_PUT; \ - _DX = left; \ - _BX = top; \ - static_cast(_BX) >>= 1; \ - _AL = put_w_words; \ - _CX = sprite16_put_h; \ - _DI = so; \ - geninterrupt(SPRITE16); \ - -#define CLIP_LEFT_PART \ - do { \ - putpos_left += 16; \ - put_w_words--; \ - if(FLAGS_ZERO) { \ - return; \ - } \ - sprite_offset_local += (16 / 8); \ - } while(putpos_left < clip_left); - -#define CLIP_RIGHT_PART \ - do { \ - putpos_right -= 16; \ - put_w_words--; \ - if(FLAGS_ZERO) { \ - return; \ - } \ - } while(putpos_right >= clip_right); - -void pascal sprite16_put(screen_x_t left, screen_y_t top, sprite16_offset_t so) -{ - SETUP_VARS(left, top, so); - if(putpos_right < clip_right) { - if(putpos_left >= clip_left) { -put: - CALL_PUT(putpos_left, top, put_w_words, sprite_offset_local); - return; - } else if(putpos_right < clip_left) { - return; - } - // Sprite starts left of `clip_left` - CLIP_LEFT_PART; - goto put; - } else if(putpos_left >= clip_right) { - return; - } - // Sprite ends right of `clip_right` - CLIP_RIGHT_PART; - goto put; -} - -#pragma codestring "\x90" - -void pascal sprite16_putx( - screen_x_t left, - screen_y_t top, - sprite16_offset_t so, - sprite16_put_func_t func -) -{ - SETUP_VARS(left, top, so); - if(putpos_right < clip_right) { - if(putpos_left >= clip_left) { -put: - _AH = SPRITE16_PUT; - _DX = putpos_left; - _BX = top; - static_cast(_BX) >>= 1; - _AL = put_w_words; - _CX = sprite16_put_h; - _DI = sprite_offset_local; - while(1) { - should_draw_column = func; - geninterrupt(SPRITE16); - should_draw_column--; - if(FLAGS_ZERO) { - return; - } - _BX += _CX; - asm { cmp bx, SPRITE16_RES_Y; } - asm { jge end; } - } - } else if(putpos_right < clip_left) { - return; - } - // Sprite starts left of `clip_left` - CLIP_LEFT_PART; - goto put; - } else if(putpos_left >= clip_right) { - return; - } - // Sprite ends right of `clip_right` - CLIP_RIGHT_PART; - goto put; -end: -} - -#pragma codestring "\x90" - -void pascal sprite16_put_noclip( - screen_x_t left, screen_y_t top, sprite16_offset_t so -) -{ - // A completely useless SETUP_VARS variant without the `put_w_words` - // assignment, which actually makes it incorrect... - sprite_offset_local = so; - putpos_left = left; - putpos_right_high ^= putpos_right_high; - static_cast(putpos_right) = put_w_words; - putpos_right <<= 4; - putpos_right += putpos_left; - - CALL_PUT(putpos_left, top, sprite16_put_w.v, sprite_offset_local); -} - -} +#include "th03/main/sprite16.cpp" diff --git a/th03/sprites/main_s16.hpp b/th03/sprites/main_s16.hpp index 8167c8c4..68021cd9 100644 --- a/th03/sprites/main_s16.hpp +++ b/th03/sprites/main_s16.hpp @@ -1,6 +1,6 @@ // SPRITE16 sprite area contents for MAIN.EXE. -#include "th03/sprite16.hpp" +#include "th03/main/sprite16.hpp" #define XY(x, y) ((y * ROW_SIZE) + (x / BYTE_DOTS))