diff options
Diffstat (limited to 'src/sprites.h')
-rw-r--r-- | src/sprites.h | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/sprites.h b/src/sprites.h new file mode 100644 index 0000000..e7439f1 --- /dev/null +++ b/src/sprites.h | |||
@@ -0,0 +1,98 @@ | |||
1 | #ifndef GBAEXP_SPRITES_H | ||
2 | #define GBAEXP_SPRITES_H | ||
3 | |||
4 | #include "common.h" | ||
5 | |||
6 | u32 | ||
7 | unpack_1bb(u8 hex) { | ||
8 | const u32 conversion_u32[16] = { | ||
9 | 0x00000000, 0x00000001, 0x00000010, 0x00000011, | ||
10 | 0x00000100, 0x00000101, 0x00000110, 0x00000111, | ||
11 | 0x00001000, 0x00001001, 0x00001010, 0x00001011, | ||
12 | 0x00001100, 0x00001101, 0x00001110, 0x00001111, | ||
13 | }; | ||
14 | u8 low = hex & 0xF; | ||
15 | u8 high = (hex >> 4) & 0xF; | ||
16 | return (conversion_u32[high] << 16) | conversion_u32[low]; | ||
17 | } | ||
18 | |||
19 | typedef struct Sprite { | ||
20 | // A unique sprite identifier. | ||
21 | size_t id; | ||
22 | // The number of tiles for a single sprite frame. | ||
23 | size_t n_tiles; | ||
24 | // The starting tile of this sprite. | ||
25 | size_t tile_start; | ||
26 | // The associated palette bank for this sprite. | ||
27 | size_t pal_bank; | ||
28 | } Sprite; | ||
29 | |||
30 | |||
31 | #define NUM_SPRITES 128 | ||
32 | Sprite sprites[NUM_SPRITES]; | ||
33 | |||
34 | // Keeping track of unique sprites and current sprite memory pointer using | ||
35 | // global singletons. | ||
36 | size_t sprite_counter = 0; | ||
37 | size_t sprite_tile_counter = 0; | ||
38 | u32 *sprite_memory = NULL; | ||
39 | |||
40 | // Loads the sprite data into video memory and initialize the Sprite structure. | ||
41 | size_t | ||
42 | load_sprite_data(u32 *sprite_data, size_t n_tiles, size_t n_frames) { | ||
43 | memcpy(sprite_memory, sprite_data, 8 * n_tiles * n_frames * sizeof(u32)); | ||
44 | sprite_memory += 8 * n_tiles * n_frames; | ||
45 | Sprite sprite = { | ||
46 | .id = sprite_counter, | ||
47 | .n_tiles = n_tiles, | ||
48 | .tile_start = sprite_tile_counter, | ||
49 | }; | ||
50 | sprite_tile_counter += n_tiles * n_frames; | ||
51 | sprites[sprite_counter] = sprite; | ||
52 | return sprite_counter++; | ||
53 | } | ||
54 | |||
55 | size_t | ||
56 | load_packed_sprite_data(u32 *sprite_data, size_t n_tiles, size_t n_frames) { | ||
57 | size_t counter = 0; | ||
58 | for (size_t i = 0; i < 8 * n_tiles * n_frames / 4; ++i) { | ||
59 | u32 hex = sprite_data[i]; | ||
60 | sprite_memory[counter++] = unpack_1bb((hex >> 24) & 0xFF); | ||
61 | sprite_memory[counter++] = unpack_1bb((hex >> 16) & 0xFF); | ||
62 | sprite_memory[counter++] = unpack_1bb((hex >> 8) & 0xFF); | ||
63 | sprite_memory[counter++] = unpack_1bb((hex) & 0xFF); | ||
64 | } | ||
65 | sprite_memory += 8 * n_tiles * n_frames; | ||
66 | Sprite sprite = { | ||
67 | .id = sprite_counter, | ||
68 | .n_tiles = n_tiles, | ||
69 | .tile_start = sprite_tile_counter, | ||
70 | }; | ||
71 | sprite_tile_counter += n_tiles * n_frames; | ||
72 | sprites[sprite_counter] = sprite; | ||
73 | return sprite_counter++; | ||
74 | } | ||
75 | |||
76 | void | ||
77 | init_sprites(size_t starting_tile) { | ||
78 | // Initialize all attributes by disabling rendering. If we don't do this, | ||
79 | // glitches may appear. | ||
80 | for (size_t i = 0; i < 128; ++i) { | ||
81 | OBJ_ATTR_0(i) = (1 << 9); | ||
82 | } | ||
83 | |||
84 | sprite_counter = 0; | ||
85 | // Prepare global sprite_memory address. | ||
86 | sprite_memory = &TILE_MEM[4][starting_tile]; | ||
87 | } | ||
88 | |||
89 | void | ||
90 | init_sprite_pal(size_t starting_index, Color col) { | ||
91 | // Add colors to the sprite color palette. Tiles with color number 0 are | ||
92 | // treated as transparent. | ||
93 | for (size_t i = 0; i < 16; ++i) { | ||
94 | PAL_BUFFER_SPRITES[i + starting_index] = col; | ||
95 | } | ||
96 | |||
97 | } | ||
98 | #endif // GBAEXP_SPRITES_H | ||