strcpy
[retrocrawl] / src / sprite.c
1 #include <stdio.h>
2 #include <string.h>
3 #include "sprite.h"
4 #include "hwregs.h"
5 #include "copper.h"
6
7 #define MAX_SPRITES     32
8
9 static int scount;
10 static struct sprite *spr[MAX_SPRITES];
11 static struct sprite *hwspr[4]; /* 4 channels because we support only attached sprites */
12
13 static uint16_t nullspr[] = {
14         0x2000, 0x2100,
15         0x0000, 0x0000,
16         0x0000, 0x0000
17 };
18 static uint32_t nullspr_addr = (intptr_t)nullspr;
19
20 static uint32_t *coplist;
21
22
23 void begin_sprites(void)
24 {
25         scount = 0;
26         memset(hwspr, 0, sizeof hwspr);
27
28         coplist = copperlist_end;
29 }
30
31 void end_sprites(void)
32 {
33         int i, j, reg;
34
35         copperlist_end = coplist;
36
37         /* initially point all sprites to the null sprite */
38         reg = REGN_SPR0PTH;
39         for(i=0; i<8; i++) {
40                 add_copper(COPPER_MOVE(reg, nullspr_addr >> 16));
41                 add_copper(COPPER_MOVE(reg + 2, nullspr_addr));
42                 reg += 4;
43         }
44
45 #if 0
46         /* sort sprites by increasing start position */
47         for(i=0; i<scount; i++) {
48                 for(j=i+1; j<scount; j++) {
49                         if(spr[j]->y < spr[i]->y) {
50                                 struct sprite *tmp = spr[i];
51                                 spr[i] = spr[j];
52                                 spr[j] = tmp;
53                         }
54                 }
55         }
56 #endif
57
58         /* set sprite positions and populate copperlist to draw
59          * hardware sprites
60          */
61         for(i=0; i<scount; i++) {
62                 struct sprite *s = spr[i];
63                 uint16_t sx = 0x80 + s->x;
64                 uint16_t sy = 0x2c + s->y;
65                 uint16_t vstop = sy + s->height;
66                 uint32_t addr;
67                 int reuse = 0;
68
69                 int chan[4];
70                 int nchan_found = 0;
71                 for(j=0; j<4; j++) {
72                         if(!hwspr[j] || hwspr[j]->y + hwspr[j]->height < s->y) {
73                                 if(hwspr[j]) {
74                                         reuse = 1;
75                                 }
76                                 chan[nchan_found++] = j;
77                                 hwspr[j] = s;
78                                 if(nchan_found >= s->hwslices) {
79                                         break;
80                                 }
81                         }
82                 }
83                 if(nchan_found < s->hwslices) continue;
84
85 //              if(reuse) {
86                         printf("copper wait: %d\n", (int)s->y - 1);
87                         add_copper(COPPER_VWAIT(s->y - 1));
88 //              }
89
90                 for(j=0; j<s->hwslices; j++) {
91                         int idx = chan[j] * 2;
92                         reg = REGN_SPR0PTH + idx * 4;
93
94                         s->hwspr[idx][0] = s->hwspr[idx + 1][0] = (sx >> 1) | (sy << 8);
95                         s->hwspr[idx][1] = s->hwspr[idx + 1][1] = (vstop << 8) |
96                                 ((vstop >> 7) & 2) | (sx & 1) | 0x80;
97
98                         addr = (intptr_t)s->hwspr[idx];
99                         add_copper(COPPER_MOVE(reg, addr >> 16));
100                         add_copper(COPPER_MOVE(reg + 2, addr));
101                         reg += 4;
102                         addr = (intptr_t)s->hwspr[idx + 1];
103                         add_copper(COPPER_MOVE(reg, addr >> 16));
104                         add_copper(COPPER_MOVE(reg + 2, addr));
105
106                         sx += 16;
107                 }
108         }
109
110         *copperlist_end = COPPER_END;
111         copperlist_end = coplist;
112 }
113
114 void draw_sprite(struct sprite *s, int x, int y)
115 {
116         if(s->img) {
117                 /* blitter sprite */
118         } else {
119                 /* hw sprites */
120                 spr[scount++] = s;
121                 s->x = x - s->origx;
122                 s->y = y - s->origy;
123         }
124 }