From 4c23d7e521ae7ce598447792cec02cba4cf05c87 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Fri, 3 Aug 2018 01:45:09 +0300 Subject: [PATCH] new sprite system first successfull test --- src/game.c | 48 +++----- src/oldsprite.s | 339 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/sprite.c | 71 ++++++++++-- 3 files changed, 415 insertions(+), 43 deletions(-) create mode 100644 src/oldsprite.s diff --git a/src/game.c b/src/game.c index 37c39b2..89b4e5a 100644 --- a/src/game.c +++ b/src/game.c @@ -3,6 +3,7 @@ #include "gfx.h" #include "copper.h" #include "data.h" +#include "sprite.h" #include "hwregs.h" /* XXX */ @@ -12,20 +13,13 @@ void draw_tile(int tid, int x, int y, int light); static uint16_t *sprdata[NUM_HWSPRITES]; -static uint16_t nullspr[] = { - 0x2000, 0x2100, - 0x0000, 0x0000, - 0x0000, 0x0000 -}; - -#define SPR_POS(x, y) \ - (((uint16_t)((x) + 0x40) & 0xff) | ((uint16_t)((y) + 0x2c) << 8)) +/* hardcoded test sprite */ +static struct sprite test_sprite; int game_init(void) { - int i, sprpos[] = {136, 76}; - uint32_t nullspr_addr = (intptr_t)nullspr; + int i; REG_COLOR0 = 0x221; REG_COLOR1 = 0x222; @@ -47,31 +41,15 @@ int game_init(void) sprdata[4] = spr2a; sprdata[5] = spr2b; + test_sprite.width = test_sprite.height = 48; + test_sprite.origx = 24; + test_sprite.origy = 24; + test_sprite.img = test_sprite.mask = 0; + test_sprite.hwslices = 3; for(i=0; i<8; i++) { - int reg = REGN_SPR0PTH + i * 4; - if(i < NUM_HWSPRITES) { - uint16_t sx, sy, vstop; - /* initialize active sprites, and set the sprite pointers */ - uint32_t addr = (intptr_t)sprdata[i]; - add_copper(COPPER_MOVE(reg, addr >> 16)); - add_copper(COPPER_MOVE(reg + 2, addr)); - - sx = 0x80 + sprpos[0] + (i >> 1) * 16; - sy = 0x2c + sprpos[1]; - vstop = sy + SPRITE_HEIGHT; - - sprdata[i][0] = (sx >> 1) | (sy << 8); - sprdata[i][1] = (vstop << 8) | ((vstop >> 7) & 2) | - (sx & 1) | ((i & 1) ? 0x80 : 0); - } else { - /* point the sprite pointers to the null sprite for the rest */ - add_copper(COPPER_MOVE(reg, nullspr_addr >> 16)); - add_copper(COPPER_MOVE(reg + 2, nullspr_addr)); - } + test_sprite.hwspr[i] = i < 6 ? sprdata[i] : 0; } - *copperlist_end = COPPER_END; - return 0; } @@ -82,8 +60,6 @@ void game_draw(void) { int i, j, xoffs, yoffs, ntiles; - /* reset sprite data */ - yoffs = 0; for(i=0; i #include "sprite.h" +#include "hwregs.h" +#include "copper.h" #define MAX_SPRITES 32 static int scount; -static sprite *spr[MAX_SPRITES]; -static sprite *hwspr[4]; /* 4 channels because we support only attached sprites */ +static struct sprite *spr[MAX_SPRITES]; +static struct sprite *hwspr[4]; /* 4 channels because we support only attached sprites */ + +static uint16_t nullspr[] = { + 0x2000, 0x2100, + 0x0000, 0x0000, + 0x0000, 0x0000 +}; +static uint32_t nullspr_addr = (intptr_t)nullspr; + +static uint32_t *coplist; + void begin_sprites(void) { scount = 0; - memset(hwspr_used, 0, sizeof hwspr_used); + memset(hwspr, 0, sizeof hwspr); + + coplist = copperlist_end; } void end_sprites(void) { - int i, j; + int i, j, reg; + + copperlist_end = coplist; + + /* initially point all sprites to the null sprite */ + reg = REGN_SPR0PTH; + for(i=0; i<8; i++) { + add_copper(COPPER_MOVE(reg, nullspr_addr >> 16)); + add_copper(COPPER_MOVE(reg + 2, nullspr_addr)); + reg += 4; + } /* sort sprites by increasing start position */ for(i=0; ix; uint16_t sy = 0x2c + s->y; uint16_t vstop = sy + s->height; + uint32_t addr; + int reuse = 0; - int chan = -1; + int chan[4]; + int nchan_found = 0; for(j=0; j<4; j++) { if(!hwspr[j] || hwspr[j]->y + hwspr[j]->height < s->y) { - chan = j; + if(hwspr[j]) { + reuse = 1; + } + chan[nchan_found++] = j; hwspr[j] = s; + if(nchan_found >= s->hwslices) { + break; + } } } - if(chan == -1) continue; + if(nchan_found < s->hwslices) continue; + + if(reuse) { + add_copper(COPPER_VWAIT(sy)); + } for(j=0; jhwslices; j++) { + int idx = chan[j] * 2; + reg = REGN_SPR0PTH + idx * 4; + s->hwspr[idx][0] = s->hwspr[idx + 1][0] = (sx >> 1) | (sy << 8); s->hwspr[idx][1] = s->hwspr[idx + 1][1] = (vstop << 8) | ((vstop >> 7) & 2) | (sx & 1) | 0x80; + + addr = (intptr_t)s->hwspr[idx]; + add_copper(COPPER_MOVE(reg, addr >> 16)); + add_copper(COPPER_MOVE(reg + 2, addr)); + reg += 4; + addr = (intptr_t)s->hwspr[idx + 1]; + add_copper(COPPER_MOVE(reg, addr >> 16)); + add_copper(COPPER_MOVE(reg + 2, addr)); + + sx += 16; } } + + *copperlist_end = COPPER_END; + copperlist_end = coplist; } void draw_sprite(struct sprite *s, int x, int y) @@ -61,7 +114,7 @@ void draw_sprite(struct sprite *s, int x, int y) } else { /* hw sprites */ spr[scount++] = s; - s->x = x - origx; - s->y = y - origy; + s->x = x - s->origx; + s->y = y - s->origy; } } -- 1.7.10.4