#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;
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;
}
{
int i, j, xoffs, yoffs, ntiles;
- /* reset sprite data */
-
yoffs = 0;
for(i=0; i<YTILES; i++) {
xoffs = i & 1 ? TILE_W / 2 : 0;
}
yoffs += TILE_H / 2;
}
+
+ begin_sprites();
+ draw_sprite(&test_sprite, 160, 100);
+ end_sprites();
}
#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++) {
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)
} else {
/* hw sprites */
spr[scount++] = s;
- s->x = x - origx;
- s->y = y - origy;
+ s->x = x - s->origx;
+ s->y = y - s->origy;
}
}