better input, button for quality selection
[gbajam22] / src / gamescr.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include "gbaregs.h"
4 #include "game.h"
5 #include "dma.h"
6 #include "util.h"
7 #include "intr.h"
8 #include "input.h"
9 #include "player.h"
10 #include "gba.h"
11 #include "sprite.h"
12 #include "debug.h"
13 #include "level.h"
14 #include "voxscape.h"
15 #include "data.h"
16
17 #define FOV             30
18 #define NEAR    2
19 #define FAR             85
20
21 static int gamescr_start(void);
22 static void gamescr_stop(void);
23 static void gamescr_frame(void);
24 static void gamescr_vblank(void);
25
26 static void update(void);
27 static void draw(void);
28
29 static struct screen gamescr = {
30         "game",
31         gamescr_start,
32         gamescr_stop,
33         gamescr_frame,
34         gamescr_vblank
35 };
36
37 static uint16_t *framebuf;
38
39 static int nframes, backbuf;
40 static uint16_t *vram[] = { gba_vram_lfb0, gba_vram_lfb1 };
41
42 static int32_t pos[2], angle, horizon = 80;
43 static struct voxscape *vox;
44
45 #define COLOR_HORIZON   192
46 #define COLOR_ZENITH    255
47
48 #define MAX_SPR         8
49 static uint16_t oam[4 * MAX_SPR];
50
51
52 struct screen *init_game_screen(void)
53 {
54         return &gamescr;
55 }
56
57 static int gamescr_start(void)
58 {
59         int i;
60
61         gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1);
62
63         vblperf_setcolor(0);
64
65         pos[0] = pos[1] = VOX_SZ << 15;
66
67         if(!(vox = vox_create(VOX_SZ, VOX_SZ, height_pixels, color_pixels))) {
68                 panic(get_pc(), "vox_create");
69         }
70         vox_proj(vox, FOV, NEAR, FAR);
71         vox_view(vox, pos[0], pos[1], -40, angle);
72
73         /* setup color image palette */
74         for(i=0; i<256; i++) {
75                 int r = color_cmap[i * 3];
76                 int g = color_cmap[i * 3 + 1];
77                 int b = color_cmap[i * 3 + 2];
78                 gba_bgpal[i] = (((uint16_t)b << 7) & 0x7c00) | (((uint16_t)g << 2) & 0x3e0) | (((uint16_t)r >> 3) & 0x1f);
79         }
80         /*
81         intr_disable();
82         interrupt(INTR_HBLANK, hblank);
83         REG_DISPSTAT |= DISPSTAT_IEN_HBLANK;
84         unmask(INTR_HBLANK);
85         intr_enable();
86         */
87
88         spr_setup(16, 2, spr_game_pixels, spr_game_cmap);
89
90         wait_vblank();
91         spr_clear();
92         spr_oam(oam, 0, 516, 0, 144, SPR_SZ16 | SPR_256COL);
93         spr_oam(oam, 1, 516, 16, 144, SPR_SZ16 | SPR_256COL);
94         spr_oam(oam, 2, 516, 32, 144, SPR_SZ16 | SPR_256COL);
95         spr_oam(oam, 3, 520, 48, 144, SPR_SZ16 | SPR_256COL);
96
97         spr_oam(oam, 4, 512, 176, 144, SPR_SZ16 | SPR_256COL);
98         spr_oam(oam, 5, 516, 192, 144, SPR_SZ16 | SPR_256COL);
99         spr_oam(oam, 6, 516, 208, 144, SPR_SZ16 | SPR_256COL);
100         spr_oam(oam, 7, 516, 224, 144, SPR_SZ16 | SPR_256COL);
101         dma_copy16(3, (void*)OAM_ADDR, oam, sizeof oam / 2, 0);
102
103         nframes = 0;
104         return 0;
105 }
106
107 static void gamescr_stop(void)
108 {
109         /*mask(INTR_HBLANK);*/
110 }
111
112 static void gamescr_frame(void)
113 {
114         backbuf = ++nframes & 1;
115         framebuf = vram[backbuf];
116
117         vox_framebuf(vox, 240, 160, framebuf, horizon);
118
119         update();
120         draw();
121
122         vblperf_end();
123         wait_vblank();
124         present(backbuf);
125
126         if(!(nframes & 15)) {
127                 emuprint("vbl: %d", vblperf_count);
128         }
129 #ifdef VBLBAR
130         vblperf_begin();
131 #else
132         vblperf_count = 0;
133 #endif
134 }
135
136 #define WALK_SPEED      0x40000
137 #define TURN_SPEED      0x200
138 #define ELEV_SPEED      8
139
140 static void update(void)
141 {
142         int32_t fwd[2], right[2];
143
144         update_keyb();
145
146         if(KEYPRESS(BN_SELECT)) {
147                 vox_quality ^= 1;
148         }
149
150         if(keystate) {
151                 if(keystate & BN_LEFT) {
152                         angle += TURN_SPEED;
153                 }
154                 if(keystate & BN_RIGHT) {
155                         angle -= TURN_SPEED;
156                 }
157
158                 fwd[0] = -SIN(angle);
159                 fwd[1] = COS(angle);
160                 right[0] = fwd[1];
161                 right[1] = -fwd[0];
162
163                 if(keystate & BN_A) {
164                         pos[0] += fwd[0];
165                         pos[1] += fwd[1];
166                 }
167                 /*
168                 if(keystate & BN_DOWN) {
169                         pos[0] -= fwd[0];
170                         pos[1] -= fwd[1];
171                 }
172                 */
173                 if(keystate & BN_UP) {
174                         if(horizon > 40) horizon -= ELEV_SPEED;
175                 }
176                 if(keystate & BN_DOWN) {
177                         if(horizon < 200 - ELEV_SPEED) horizon += ELEV_SPEED;
178                 }
179                 if(keystate & BN_RT) {
180                         pos[0] += right[0];
181                         pos[1] += right[1];
182                 }
183                 if(keystate & BN_LT) {
184                         pos[0] -= right[0];
185                         pos[1] -= right[1];
186                 }
187
188                 vox_view(vox, pos[0], pos[1], -40, angle);
189         }
190 }
191
192 static void draw(void)
193 {
194         dma_fill16(3, framebuf, 0, 240 * 160 / 2);
195         //fillblock_16byte(framebuf, 0, 240 * 160 / 16);
196
197         vox_render(vox);
198         //vox_sky_grad(vox, COLOR_HORIZON, COLOR_ZENITH);
199         //vox_sky_solid(vox, COLOR_ZENITH);
200 }
201
202 #define MAXBANK         0x100
203
204 ARM_IWRAM
205 static void gamescr_vblank(void)
206 {
207         static int bank, bankdir, theta, scale;
208         int32_t sa, ca;
209
210         theta = -(bank << 3);
211         scale = MAXBANK + (abs(bank) >> 3);
212         sa = SIN(theta) / scale;
213         ca = COS(theta) / scale;
214
215         REG_BG2X = -ca * 120 - sa * 80 + (120 << 8);
216         REG_BG2Y = sa * 120 - ca * 80 + (80 << 8);
217
218         REG_BG2PA = ca;
219         REG_BG2PB = sa;
220         REG_BG2PC = -sa;
221         REG_BG2PD = ca;
222
223         keystate = ~REG_KEYINPUT;
224
225         if((keystate & (BN_LEFT | BN_RIGHT)) == 0) {
226                 if(bank) {
227                         bank -= bankdir << 4;
228                 }
229         } else if(keystate & BN_LEFT) {
230                 bankdir = -1;
231                 if(bank > -MAXBANK) bank -= 16;
232         } else if(keystate & BN_RIGHT) {
233                 bankdir = 1;
234                 if(bank < MAXBANK) bank += 16;
235         }
236 }
237
238 /*
239 static uint16_t skygrad[] __attribute__((section(".data"))) = {
240
241         0x662a, 0x660a, 0x660a, 0x660b, 0x660b, 0x660b, 0x660b, 0x6a0b, 0x6a0c,
242         0x6a0c, 0x6a0c, 0x6a0c, 0x6a0c, 0x6a0d, 0x6a0d, 0x6a0d, 0x6a0d, 0x6a0d,
243         0x6a0d, 0x6a0e, 0x6e0e, 0x6e0e, 0x6e0e, 0x6e0e, 0x6e0f, 0x6e0f, 0x6e0f,
244         0x6e0f, 0x6e0f, 0x6e0f, 0x6e10, 0x6e10, 0x7210, 0x7210, 0x7210, 0x7211,
245         0x7211, 0x7211, 0x71f1, 0x71f1, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2,
246         0x75f2, 0x75f3, 0x75f3, 0x75f3, 0x75f3, 0x75f3, 0x75f4, 0x75f4, 0x75f4,
247         0x75f4, 0x75f4, 0x75f5, 0x79f5, 0x79f5, 0x79f5, 0x79f5, 0x79f5, 0x79f6,
248         0x79f6, 0x79f6, 0x79f6, 0x79f6, 0x79f7, 0x79f7, 0x79f7, 0x7df7, 0x7df7,
249         0x7df7, 0x7df8, 0x7df8, 0x7df8, 0x7dd8, 0x7dd8, 0x7dd9, 0x7dd9,
250
251         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
252         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
253         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
254         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
255         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
256         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
257         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
258         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
259         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9
260 };
261
262 ARM_IWRAM
263 static void hblank(void)
264 {
265         int vcount = REG_VCOUNT;
266         gba_bgpal[255] = skygrad[vcount];
267 }
268 */