better menu screen
[gbajam22] / src / menuscr.c
1 #include "game.h"
2 #include "data.h"
3 #include "gba.h"
4 #include "util.h"
5 #include "dma.h"
6 #include "input.h"
7 #include "sprite.h"
8 #include "debug.h"
9
10 enum {
11         MENU_START,
12         MENU_CTRL,
13         MENU_COLORS,
14         MENU_SCORE,
15
16         NUM_MENU_ITEMS
17 };
18
19 static int menuscr_start(void);
20 static void menuscr_stop(void);
21 static void menuscr_frame(void);
22 static void menuscr_vblank(void);
23
24 static struct screen menuscr = {
25         "menu",
26         menuscr_start,
27         menuscr_stop,
28         menuscr_frame,
29         menuscr_vblank
30 };
31
32 static int num_vbl;
33 static int cur_x, cur_y;
34 static int sel;
35 static int running;
36
37 static const short pos[][2] = {{76, 88}, {87, 108}, {29, 128}, {75, 148}};
38 #define CUR_XOFFS       16
39
40 struct screen *init_menu_screen(void)
41 {
42         return &menuscr;
43 }
44
45 static void setup_palette(void)
46 {
47         int i;
48         unsigned char *cmap = gba_colors ? menuscr_gba_cmap : menuscr_cmap;
49
50         for(i=0; i<256; i++) {
51                 int r = cmap[i * 3];
52                 int g = cmap[i * 3 + 1];
53                 int b = cmap[i * 3 + 2];
54                 gba_bgpal[i] = RGB555(r, g, b);
55         }
56 }
57
58 static int menuscr_start(void)
59 {
60         gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ);
61         dma_copy16(3, gba_vram_lfb0, menuscr_pixels, 240 * 160 / 2, 0);
62
63         setup_palette();
64
65         spr_setup(16, 4, spr_menu_pixels, spr_menu_cmap);
66
67         wait_vblank();
68         spr_clear();
69
70         cur_x = pos[0][0] - CUR_XOFFS;
71         cur_y = pos[0][1];
72
73         running = 1;
74         return 0;
75 }
76
77 static void menuscr_stop(void)
78 {
79         running = 0;
80         wait_vblank();
81         spr_clear();
82 }
83
84 static void menuscr_frame(void)
85 {
86         update_keyb();
87
88         if(KEYPRESS(BN_START) || (sel == 0 && KEYPRESS(BN_A))) {
89                 change_screen(find_screen("game"));
90                 return;
91         }
92
93         if(KEYPRESS(BN_DOWN) && sel <= NUM_MENU_ITEMS) {
94                 cur_x = pos[++sel][0] - CUR_XOFFS;
95                 cur_y = pos[sel][1];
96         }
97         if(KEYPRESS(BN_UP) && sel > 0) {
98                 cur_x = pos[--sel][0] - CUR_XOFFS;
99                 cur_y = pos[sel][1];
100         }
101         if((KEYPRESS(BN_LEFT) || KEYPRESS(BN_RIGHT)) && sel == MENU_COLORS) {
102                 gba_colors ^= 1;
103                 setup_palette();
104         }
105
106         wait_vblank();
107 }
108
109 static const int curspr[] = {
110         SPRID(0, 0), SPRID(32, 0), SPRID(64, 0), SPRID(96, 0),
111         SPRID(0, 16), SPRID(32, 16), SPRID(64, 16), SPRID(96, 16)
112 };
113
114 #define MENU_COLOR_FBPTR                (void*)(VRAM_LFB_FB0_ADDR + 117 * 240)
115
116 static void menuscr_vblank(void)
117 {
118         int anm, frm;
119         unsigned int flags = SPR_SZ32 | SPR_HRECT | SPR_256COL;
120         void *src;
121
122         if(!running) return;
123
124         anm = (num_vbl++ >> 3) & 0xf;
125         frm = anm & 7;
126
127         if(anm >= 8) flags |= SPR_VFLIP;
128
129         spr_oam(0, 0, curspr[frm], cur_x - 16, cur_y - 8, flags);
130
131         src = menuscr_pixels + (gba_colors ? 160 : 117) * 240;
132         dma_copy32(3, MENU_COLOR_FBPTR, src, 16 * 240 / 4, 0);
133 }