new sprite system first successfull test
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 2 Aug 2018 22:45:09 +0000 (01:45 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 2 Aug 2018 22:45:09 +0000 (01:45 +0300)
src/game.c
src/oldsprite.s [new file with mode: 0644]
src/sprite.c

index 37c39b2..89b4e5a 100644 (file)
@@ -3,6 +3,7 @@
 #include "gfx.h"
 #include "copper.h"
 #include "data.h"
+#include "sprite.h"
 
 #include "hwregs.h"    /* XXX */
 
 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<YTILES; i++) {
                xoffs = i & 1 ? TILE_W / 2 : 0;
@@ -94,6 +70,10 @@ void game_draw(void)
                }
                yoffs += TILE_H / 2;
        }
+
+       begin_sprites();
+       draw_sprite(&test_sprite, 160, 100);
+       end_sprites();
 }
 
 
diff --git a/src/oldsprite.s b/src/oldsprite.s
new file mode 100644 (file)
index 0000000..f938108
--- /dev/null
@@ -0,0 +1,339 @@
+       .data
+
+
+       .global spr0a
+spr0a:
+       .short 0, 0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x200, 0x600
+       .short 0x100, 0x300
+       .short 0x180, 0xc0
+       .short 0x60, 0x60
+       .short 0x30, 0x30
+       .short 0x8, 0x18
+       .short 0xe, 0x5
+       .short 0x6, 0x7
+       .short 0x1, 0x1
+       .short 0x1, 0x1
+       .short 0x3, 0x3
+       .short 0x31, 0xe
+       .short 0x35, 0x10
+       .short 0x2e, 0x20
+       .short 0x1e, 0x10
+       .short 0x11, 0x11
+       .short 0x1b, 0x1b
+       .short 0x8, 0x8
+       .short 0x8, 0x0
+       .short 0x7, 0x5
+       .short 0x5, 0x4
+       .short 0x2, 0x0
+       .short 0x1, 0x0
+       .short 0xe03d, 0x1
+       .short 0xfbf, 0x1
+       .short 0x1ff, 0x0
+       .short 0x7ff, 0x0
+       .short 0x3ff, 0x0
+       .short 0xff, 0x0
+       .short 0x3f, 0x0
+       .short 0x7, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .long 0
+
+       .global spr0b
+spr0b:
+       .short 0, 0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x600, 0x600
+       .short 0x300, 0x300
+       .short 0x1c0, 0x1c0
+       .short 0x60, 0x60
+       .short 0x30, 0x30
+       .short 0x18, 0x18
+       .short 0xe, 0xf
+       .short 0x3, 0x7
+       .short 0x7, 0x6
+       .short 0x1, 0x0
+       .short 0x2, 0x1
+       .short 0x3f, 0x3f
+       .short 0x27, 0x38
+       .short 0xe, 0x31
+       .short 0xe, 0x11
+       .short 0x8, 0x17
+       .short 0x0, 0x1f
+       .short 0x5, 0xa
+       .short 0x8, 0xf
+       .short 0x2, 0x5
+       .short 0x0, 0x7
+       .short 0x2, 0x3
+       .short 0x1, 0x1
+       .short 0x1, 0x0
+       .short 0x1, 0x1
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .long 0
+
+       .global spr1a
+spr1a:
+       .short 0, 0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x2000, 0x2000
+       .short 0x6c00, 0x3800
+       .short 0x6800, 0x5400
+       .short 0x7200, 0x6400
+       .short 0x4b00, 0x4100
+       .short 0xa00, 0x1a00
+       .short 0xce00, 0xc800
+       .short 0xf980, 0xb600
+       .short 0xeb80, 0x1700
+       .short 0xe380, 0x1e00
+       .short 0x55c0, 0x40
+       .short 0xfc40, 0x8040
+       .short 0xf400, 0x4400
+       .short 0xf500, 0x3400
+       .short 0xf700, 0x6500
+       .short 0xdcc0, 0x4280
+       .short 0xcec0, 0x8980
+       .short 0xcf40, 0x89c0
+       .short 0xc8a0, 0xc9e0
+       .short 0xfb80, 0x9be0
+       .short 0xd8c0, 0x70
+       .short 0xbc20, 0x2030
+       .short 0xf800, 0xc018
+       .short 0xe610, 0x641c
+       .short 0xfb00, 0x308
+       .short 0xfc00, 0x1800
+       .short 0xfd00, 0x900
+       .short 0xfa00, 0x700
+       .short 0xfae0, 0x380
+       .short 0x7e38, 0x380
+       .short 0xd00, 0x380
+       .short 0x200, 0x780
+       .short 0x800, 0xf80
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .long 0
+
+       .global spr1b
+spr1b:
+       .short 0, 0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x2000, 0x1000
+       .short 0x5400, 0x3c00
+       .short 0x7c00, 0x3c00
+       .short 0x1600, 0x7e00
+       .short 0x5a00, 0x3f00
+       .short 0x0, 0x3f00
+       .short 0x9680, 0x6f00
+       .short 0x4f00, 0xff80
+       .short 0xfe00, 0xff80
+       .short 0xfc00, 0xff80
+       .short 0xfe00, 0x580
+       .short 0x7d80, 0x8600
+       .short 0xb3c0, 0xcc00
+       .short 0xc2c0, 0xfc00
+       .short 0x9880, 0xe540
+       .short 0xb980, 0xc740
+       .short 0x4500, 0xfe40
+       .short 0x47c0, 0xfe00
+       .short 0x40, 0xff00
+       .short 0x40e0, 0xff00
+       .short 0xd0b0, 0x7f00
+       .short 0xde10, 0xb000
+       .short 0x3818, 0xf600
+       .short 0x4a08, 0x3404
+       .short 0x1904, 0x60c
+       .short 0x404, 0xf04
+       .short 0x500, 0xe00
+       .short 0x100, 0x0
+       .short 0x100, 0x0
+       .short 0x180, 0x0
+       .short 0x80, 0x0
+       .short 0x180, 0x0
+       .short 0x780, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .long 0
+
+       .global spr2a
+spr2a:
+       .short 0, 0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .long 0
+
+       .global spr2b
+spr2b:
+       .short 0, 0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .short 0x0, 0x0
+       .long 0
+
+       .global sprpal
+sprpal:
+       .short 0xf0f
+       .short 0x000
+       .short 0x200
+       .short 0x410
+       .short 0x223
+       .short 0x222
+       .short 0x510
+       .short 0x422
+       .short 0x333
+       .short 0x334
+       .short 0x543
+       .short 0x444
+       .short 0x653
+       .short 0x555
+       .short 0x777
+       .short 0x999
index 3a00881..7b68892 100644 (file)
@@ -1,21 +1,45 @@
 #include <string.h>
 #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; i<scount; i++) {
@@ -36,22 +60,51 @@ void end_sprites(void)
                uint16_t sx = 0x80 + s->x;
                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; j<s->hwslices; 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;
        }
 }