aboutsummaryrefslogtreecommitdiffstats
path: root/src/sprites.h
blob: 6c15387ca5179e48d455ae7156567ec6810009a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
Copyright (c) 2021 Bad Diode

Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/

#ifndef GBAEXP_SPRITES_H
#define GBAEXP_SPRITES_H

#include "common.h"

typedef struct Sprite {
    // A unique sprite identifier.
    size_t id;
    // The number of tiles for a single sprite frame.
    size_t n_tiles;
    // The starting tile of this sprite.
    size_t tile_start;
    // The associated palette bank for this sprite.
    size_t pal_bank;
} Sprite;


#define NUM_SPRITES 128
Sprite sprites[NUM_SPRITES];

// Keeping track of unique sprites and current sprite memory pointer using
// global singletons.
size_t sprite_counter = 0;
size_t sprite_tile_counter = 0;
u32 *sprite_memory = NULL;

// Loads the sprite data into video memory and initialize the Sprite structure.
size_t
load_sprite_data(u32 *sprite_data, size_t n_tiles, size_t n_frames) {
    memcpy(sprite_memory, sprite_data, 8 * n_tiles * n_frames * sizeof(u32));
    sprite_memory += 8 * n_tiles * n_frames;
    Sprite sprite = {
        .id = sprite_counter,
        .n_tiles = n_tiles,
        .tile_start = sprite_tile_counter,
    };
    sprite_tile_counter += n_tiles * n_frames;
    sprites[sprite_counter] = sprite;
    return sprite_counter++;
}

size_t
load_packed_sprite_data(u32 *sprite_data, size_t n_tiles, size_t n_frames) {
    unpack_tiles(sprite_data, sprite_memory, n_tiles * n_frames);
    sprite_memory += 8 * n_tiles * n_frames;
    Sprite sprite = {
        .id = sprite_counter,
        .n_tiles = n_tiles,
        .tile_start = sprite_tile_counter,
    };
    sprite_tile_counter += n_tiles * n_frames;
    sprites[sprite_counter] = sprite;
    return sprite_counter++;
}

void
init_sprites(size_t starting_tile) {
    // Initialize all attributes by disabling rendering. If we don't do this,
    // glitches may appear.
    for (size_t i = 0; i < 128; ++i) {
        OBJ_ATTR_0(i) = (1 << 9);
    }

    sprite_counter = 0;
    // Prepare global sprite_memory address.
    sprite_memory = &TILE_MEM[4][starting_tile];
    sprite_tile_counter = starting_tile;
}

void
init_sprite_pal(size_t starting_index, Color col) {
    // Add colors to the sprite color palette. Tiles with color number 0 are
    // treated as transparent.
    for (size_t i = 0; i < 16; ++i) {
        PAL_BUFFER_SPRITES[i + starting_index] = col;
    }
}

#endif // GBAEXP_SPRITES_H