fdb0318c596b0632addf40201d61d9f6ddbe5909
[gbajam22] / src / gba / sprite.c
1 #include "sprite.h"
2 #include "gbaregs.h"
3
4
5 void spr_setup(int xtiles, int ytiles, unsigned char *pixels, unsigned char *cmap)
6 {
7         int i, j, num_tiles;
8         uint16_t *cptr, *src, *dst;
9
10         num_tiles = xtiles * ytiles;
11         dst = (uint16_t*)VRAM_LFB_OBJ_ADDR;
12         src = (uint16_t*)pixels;
13         for(i=0; i<num_tiles; i++) {
14                 /* copy every row of tile i (8x8) */
15                 for(j=0; j<8; j++) {
16                         *dst++ = src[j * 64];
17                         *dst++ = src[j * 64 + 1];
18                         *dst++ = src[j * 64 + 2];
19                         *dst++ = src[j * 64 + 3];
20                 }
21                 src += 4;
22
23                 if((i & 15) == 15) {
24                         src += 7 * 64;  /* skip to the next row of tiles (skip 7 rows of pixels) */
25                 }
26         }
27
28         cptr = (uint16_t*)CRAM_OBJ_ADDR;
29         for(i=0; i<128; i++) {
30                 unsigned char r = *cmap++ >> 3;
31                 unsigned char g = *cmap++ >> 3;
32                 unsigned char b = *cmap++ >> 3;
33                 *cptr++ = r | ((uint16_t)g << 5) | ((uint16_t)b << 10);
34         }
35 }
36
37 void spr_clear(void)
38 {
39         int i;
40
41         for(i=0; i<128; i++) {
42                 spr_oam_clear(0, i);
43         }
44 }
45
46 void spr_oam(uint16_t *oam, int idx, int spr, int x, int y, unsigned int flags)
47 {
48         if(!oam) oam = (uint16_t*)OAM_ADDR;
49
50         oam += idx << 2;
51
52         oam[0] = (y & 0xff) | (flags & 0xff00);
53         oam[1] = (x & 0x1ff) | ((flags >> 8) & 0xfe00);
54         oam[2] = (spr & 0x3ff) | ((flags & 3) << 10);
55 }
56
57 void spr_spr_oam(uint16_t *oam, int idx, struct sprite *spr)
58 {
59         int i;
60         struct hwsprite *s;
61
62         s = spr->hwspr;
63         for(i=0; i<spr->num_hwspr; i++) {
64                 spr_oam(oam, idx, s->id, spr->x + s->x, spr->y + s->y, s->flags);
65                 s++;
66         }
67 }
68
69 void spr_transform(uint16_t *oam, int idx, int16_t *mat)
70 {
71         if(!oam) oam = (uint16_t*)OAM_ADDR;
72
73         oam += (idx << 4) + 3;
74
75         oam[0] = *mat++;
76         oam[4] = *mat++;
77         oam[8] = *mat++;
78         oam[12] = *mat;
79 }