// 1bpp packed u32 gba_btn_a_data[] = { 0xc0300804, 0x844242c2, 0x030c1020, 0x21424243, 0x42440408, 0x30c00000, 0x42222010, 0x0c030000, }; u32 gba_btn_b_data[] = { 0xc0300804, 0xc442c242, 0x030c1020, 0x21424142, 0x42c40408, 0x30c00000, 0x42212010, 0x0c030000, }; u32 gba_btn_updown_data[] = { 0x00f01010, 0x90d01010, 0x001f1011, 0x13171111, 0x101020c0, 0x00000000, 0x11110807, 0x00000000, }; u32 gba_btn_leftright_data[] = { 0x000000f8, 0x0888c8e8, 0x0000000f, 0x1020202f, 0xc88808f8, 0x00000000, 0x2020100f, 0x00000000, }; u32 gba_btn_l_data[] = { 0xfc028181, 0x818101ff, 0xff808080, 0x808380ff, }; u32 gba_btn_r_data[] = { 0xff018181, 0x818101ff, 0x3f408182, 0x818280ff, }; u32 gba_btn_ab_shadow_data[] = { 0x00020204, 0x040830c0, 0x00404020, 0x20100c03, }; u32 gba_btn_up_shadow_data[] = { 0x00000010, 0x1020c000, 0x00000010, 0x10080700, }; u32 gba_btn_down_shadow_data[] = { 0x00000000, 0x10f00000, 0x00000000, 0x101f0000, }; u32 gba_btn_leftright_shadow_data[] = { 0x00000000, 0x000008f8, 0x00000000, 0x2020100f, }; u32 gba_btn_lr_shadow_data[] = { 0x00000000, 0x000001ff, 0x00000000, 0x000080ff, }; u32 gba_btn_startselect_data[] = { 0x0000f804, 0xfcf80000, 0x00001f20, 0x3f1f0000, 0x000000f8, 0x04f80000, 0x0000001f, 0x201f0000, }; u32 gba_btn_fx_downup[] = { 0x00000000, 0x00000000, 0x04000000, 0x00000000, 0x40000100, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000201, 0x00000000, 0x00008000, 0x01010000, 0x00000001, 0x00000000, 0x00000000, 0x80000000, 0x00000001, 0x00000000, 0x00000000, 0x00010100, 0x00000001, 0x02000000, 0x00000000, 0x00400000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040000, }; typedef struct SpriteAnimation { size_t *tile_offsets; size_t n_frames; } SpriteAnimation; typedef enum {BTN_STATE_IDLE, BTN_STATE_PRESSED, BTN_STATE_RELEASED, BTN_STATE_HOLD} BtnState; static size_t btn_state_idle[] = {0}; // static size_t btn_state_pressed[] = {16, 16, 32, 32, 48, 48, 64, 64, 80, 96}; static size_t btn_state_pressed[] = {0}; static SpriteAnimation *animation_states[] = { &(SpriteAnimation){ .tile_offsets = &btn_state_idle, .n_frames = sizeof(btn_state_idle) / sizeof(size_t), }, &(SpriteAnimation){ .tile_offsets = &btn_state_pressed, .n_frames = sizeof(btn_state_pressed) / sizeof(size_t), }, }; typedef struct AnimationEntry { int x_offset; int y_offset; int tile_offset; // NOTE: Maybe this should be a part of an animation? // For example, hidden state, h/v flip. u16 hidden; // u16 obj_attr_1; // u16 obj_attr_2; } AnimationEntry; typedef struct ObjState { size_t id; int x; int y; u32 *data; size_t base_tile; size_t n_tiles; size_t frames; u16 obj_attr_0; u16 obj_attr_1; u16 obj_attr_2; } ObjState; AnimationEntry *btn_down_animation[] = { &(AnimationEntry[]){ {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 2, 0, 0}, {0, 2, 0, 0}, {0, 2, 0, 0}, {0, 2, 0, 0}, }, &(AnimationEntry[]){ {0, 11, 0, 0}, {0, 11, 0, 0}, {0, 11, 0, 0}, {0, 11, 0, 0}, {0, 11, 0, 0}, {0, 11, 0, 0}, {0, 11, 0, 0}, {0, 11, 0, 0}, }, &(AnimationEntry[]){ {-8, 17, 0, 1}, {-8, 17, 0, 0}, {-8, 17, 4, 0}, {-8, 17, 4, 0}, {-8, 17, 8, 0}, {-8, 17, 8, 0}, {-8, 17, 12, 0}, {-8, 17, 12, 1}, }, };