From ec01dbdb5d5058ec54f1243629479becec4f2bda Mon Sep 17 00:00:00 2001 From: MikeDX Date: Wed, 5 Aug 2026 10:38:54 +0100 Subject: [PATCH] Refactor sprite drawing functions to use column coordinates and improve actor rendering. Introduce BLITX macro for coordinate conversion. Add draw_box function for solid box rendering. Update game logic to accommodate new coordinate system. --- presets/williams/game1.c | 33 +++++++++++++++++++------------- presets/williams/williams.c | 38 ++++++++++++++++++++++++++----------- presets/williams/williams.h | 2 ++ 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/presets/williams/game1.c b/presets/williams/game1.c index 75cfef54..4e3438c0 100644 --- a/presets/williams/game1.c +++ b/presets/williams/game1.c @@ -272,6 +272,9 @@ static word score; // bcd score #define PLAYER 1 #define LASER 2 +// blit_* functions use column coordinates; game logic uses pixels +#define BLITX(x) ((byte)((x) >> 1)) + void add_actor(Actor** list, Actor* a) { if (*list) (*list)->prevptr = &a->next; a->next = *list; @@ -285,15 +288,19 @@ void remove_actor(Actor* a) { } void draw_actor_normal(Actor* a) { - blit_sprite(a->shape, a->x, a->y); + blit_sprite(a->shape, BLITX(a->x), a->y); } void draw_actor_exploding(Actor* a) { - unblit_sprite_strided(a->shape, a->x, a->y, a->u.enemy.exploding); - if (a->u.enemy.exploding > 10) { + byte stride = a->u.enemy.exploding; + if (stride == 1) { + blit_sprite_solid(a->shape, BLITX(a->x), a->y, 0); + } + unblit_sprite_strided(a->shape, BLITX(a->x), a->y, stride); + if (stride > 10) { a->draw = NULL; } else { - blit_sprite_strided(a->shape, a->x, a->y, ++a->u.enemy.exploding); + blit_sprite_strided(a->shape, BLITX(a->x), a->y, ++a->u.enemy.exploding); } } @@ -301,7 +308,7 @@ void update_actor(Actor* a) { // if NULL shape, we don't have anything if (a->shape) { // erase the sprite - blit_sprite_solid(a->shape, a->x, a->y, 0); + blit_sprite_solid(a->shape, BLITX(a->x), a->y, 0); // call update callback if (a->update) { a->update(a); @@ -426,14 +433,14 @@ void destroy_player() { for (i=0; i<60; i++) { WATCHDOG; while (video_counter != 0xfc) ; - blit_sprite_solid(a->shape, a->x, a->y, i); + blit_sprite_solid(a->shape, BLITX(a->x), a->y, i); while (video_counter == 0xfc) ; } for (i=1; i<60; i++) { WATCHDOG; while (video_counter != 0xfc) ; - blit_sprite_strided(a->shape, a->x+i, a->y, i); - blit_sprite_strided(a->shape, a->x-i, a->y, i); + blit_sprite_strided(a->shape, BLITX(a->x+i), a->y, i); + blit_sprite_strided(a->shape, BLITX(a->x-i), a->y, i); while (video_counter == 0xfc) ; } } @@ -547,7 +554,7 @@ Actor* new_effect(void (*draw)(struct Actor *)) { void init() { byte i; - blit_solid(0, 0, 255, 255, 0); + blit_solid(0, 0, 152, 255, 0); memset(actors, 0, sizeof(actors)); memcpy(palette, palette_data, 16); player_list = fast_list = obstacle_list = free_list = NULL; @@ -579,8 +586,8 @@ void make_enemy_actors() { for (i=3; ix = (byte)xrand(); - a->y = (byte)xrand() + 24; + a->x = (byte)xrand() + (byte)xrand(); + a->y = (byte)xrand() + (byte)xrand(); } while ((byte)(a->x - 96) < 64 && (byte)(a->y - 96) < 64); a->shape = (byte*) all_sprites[i%9]; a->update = random_walk; @@ -612,7 +619,8 @@ void draw_score(Actor* a) { } void draw_playfield(Actor* a) { -// draw_box(0,0,275,255,0x11); + a; + draw_box(0, 0, 275, 255, 0x11); } int main() { @@ -635,7 +643,6 @@ int main() { case 0: break; } - score = bcd_add(score, 1); frame++; } return 0; diff --git a/presets/williams/williams.c b/presets/williams/williams.c index df7d8261..f60e428d 100644 --- a/presets/williams/williams.c +++ b/presets/williams/williams.c @@ -63,22 +63,30 @@ void unblit_sprite_rect(const byte* data, byte x, byte y) { } void blit_sprite_strided(const byte* data, byte x, byte y, byte stride) { - const byte* src = data+2; - byte height = data[1]^4; - byte width = data[0]^4; - while (height--) { - blit_copy(x, y, width, 1, src); - y += stride; + byte i; + byte width = data[0]; + byte height = data[1]; + signed int yy = (signed int)y - (height * (stride - 1) / 2); + const byte* src = data + 2; + for (i=0; i= 0 && yy < 0xf0 && (byte)(x + XBIAS) < 0x90) { + blit_copy(x, (byte)yy, width, 1, src); + } + yy += stride; src += width; } } void unblit_sprite_strided(const byte* data, byte x, byte y, byte stride) { - byte height = data[1]^4; - byte width = data[0]^4; - while (height--) { - blit_solid(x, y, width, 1, 0); - y += stride; + byte i; + byte width = data[0]; + byte height = data[1]; + signed int yy = (signed int)y - (height * (stride - 1) / 2); + for (i=0; i= 0 && yy < 0xf0 && (byte)(x + XBIAS) < 0x90) { + blit_solid(x, (byte)yy, width, 1, 0); + } + yy += stride; } } @@ -120,6 +128,14 @@ void draw_copy_solid(word xx, byte y, byte w, byte h, const byte* data, byte sol blitter.flags = (xx&1) ? DSTSCREEN|RSHIFT : DSTSCREEN; } +void draw_box(word x1, byte y1, word x2, byte y2, byte color) { + byte w = (byte)((x2 - x1) >> 1); + draw_solid(x1, y1, w, 1, color); + draw_solid(x1, y2, w, 1, color); + draw_vline(x1, y1, y2 - y1, color); + draw_vline(x2, y1, y2 - y1, color); +} + void draw_pixel(word xx, byte y, byte color) { blitter.width = 1^4; blitter.height = 1^4; diff --git a/presets/williams/williams.h b/presets/williams/williams.h index 1e82a0df..0768d4ec 100644 --- a/presets/williams/williams.h +++ b/presets/williams/williams.h @@ -111,6 +111,8 @@ void draw_vline(word x, byte y, byte h, byte color); void draw_copy_solid(word x, byte y, byte w, byte h, const byte* data, byte solid); +void draw_box(word x1, byte y1, word x2, byte y2, byte color); + // BCD asm word bcd_add(word a, word b);