--- /dev/null
+#include <string.h>
+#include "sprite.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 */
+
+void begin_sprites(void)
+{
+ scount = 0;
+ memset(hwspr_used, 0, sizeof hwspr_used);
+}
+
+void end_sprites(void)
+{
+ int i, j;
+
+ /* sort sprites by increasing start position */
+ for(i=0; i<scount; i++) {
+ for(j=i+1; j<scount; j++) {
+ if(spr[j]->y < spr[i]->y) {
+ struct sprite *tmp = spr[i];
+ spr[i] = spr[j];
+ spr[j] = tmp;
+ }
+ }
+ }
+
+ /* set sprite positions and populate copperlist to draw
+ * hardware sprites
+ */
+ for(i=0; i<scount; i++) {
+ struct sprite *s = spr[i];
+ uint16_t sx = 0x80 + s->x;
+ uint16_t sy = 0x2c + s->y;
+ uint16_t vstop = sy + s->height;
+
+ int chan = -1;
+ for(j=0; j<4; j++) {
+ if(!hwspr[j] || hwspr[j]->y + hwspr[j]->height < s->y) {
+ chan = j;
+ hwspr[j] = s;
+ }
+ }
+ if(chan == -1) continue;
+
+ for(j=0; j<s->hwslices; j++) {
+ 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;
+ }
+ }
+}
+
+void draw_sprite(struct sprite *s, int x, int y)
+{
+ if(s->img) {
+ /* blitter sprite */
+ } else {
+ /* hw sprites */
+ spr[scount++] = s;
+ s->x = x - origx;
+ s->y = y - origy;
+ }
+}
#ifndef SPRITE_H_
#define SPRITE_H_
+#include <stdint.h>
+
struct sprite {
- int width, height;
- int origx, origy;
+ int16_t x, y;
+ uint16_t width, height;
+ int16_t origx, origy;
/* img/mask used for blitter sprites */
void *img, *mask;
/* hardware sprite data */
- int hwslices;
uint16_t *hwspr[8];
+ uint8_t hwslices;
};
-void begin_sprites();
-void end_sprites();
+void begin_sprites(void);
+void end_sprites(void);
void draw_sprite(struct sprite *s, int x, int y);
#endif /* SPRITE_H_ */