cf3b9161cdaf555320f5bfee21fc000a4050260d
[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, s;
208         int32_t sa, ca;
209
210         theta = -(bank << 3);
211 #if 0
212         s = 0x100000 / (MAXBANK + (abs(bank) >> 3));
213         sa = ((SIN(theta) >> 8) * s) >> 12;
214         ca = ((COS(theta) >> 8) * s) >> 12;
215 #else
216         s = (MAXBANK + (abs(bank) >> 3));
217         sa = SIN(theta) / s;
218         ca = COS(theta) / s;
219 #endif
220
221         REG_BG2X = -ca * 120 - sa * 80 + (120 << 8);
222         REG_BG2Y = sa * 120 - ca * 80 + (80 << 8);
223
224         REG_BG2PA = ca;
225         REG_BG2PB = sa;
226         REG_BG2PC = -sa;
227         REG_BG2PD = ca;
228
229         keystate = ~REG_KEYINPUT;
230
231         if((keystate & (BN_LEFT | BN_RIGHT)) == 0) {
232                 if(bank) {
233                         bank -= bankdir << 4;
234                 }
235         } else if(keystate & BN_LEFT) {
236                 bankdir = -1;
237                 if(bank > -MAXBANK) bank -= 16;
238         } else if(keystate & BN_RIGHT) {
239                 bankdir = 1;
240                 if(bank < MAXBANK) bank += 16;
241         }
242 }
243
244 /*
245 static uint16_t skygrad[] __attribute__((section(".data"))) = {
246
247         0x662a, 0x660a, 0x660a, 0x660b, 0x660b, 0x660b, 0x660b, 0x6a0b, 0x6a0c,
248         0x6a0c, 0x6a0c, 0x6a0c, 0x6a0c, 0x6a0d, 0x6a0d, 0x6a0d, 0x6a0d, 0x6a0d,
249         0x6a0d, 0x6a0e, 0x6e0e, 0x6e0e, 0x6e0e, 0x6e0e, 0x6e0f, 0x6e0f, 0x6e0f,
250         0x6e0f, 0x6e0f, 0x6e0f, 0x6e10, 0x6e10, 0x7210, 0x7210, 0x7210, 0x7211,
251         0x7211, 0x7211, 0x71f1, 0x71f1, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2,
252         0x75f2, 0x75f3, 0x75f3, 0x75f3, 0x75f3, 0x75f3, 0x75f4, 0x75f4, 0x75f4,
253         0x75f4, 0x75f4, 0x75f5, 0x79f5, 0x79f5, 0x79f5, 0x79f5, 0x79f5, 0x79f6,
254         0x79f6, 0x79f6, 0x79f6, 0x79f6, 0x79f7, 0x79f7, 0x79f7, 0x7df7, 0x7df7,
255         0x7df7, 0x7df8, 0x7df8, 0x7df8, 0x7dd8, 0x7dd8, 0x7dd9, 0x7dd9,
256
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, 0x7dd9,
260         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
261         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
262         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
263         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
264         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
265         0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9
266 };
267
268 ARM_IWRAM
269 static void hblank(void)
270 {
271         int vcount = REG_VCOUNT;
272         gba_bgpal[255] = skygrad[vcount];
273 }
274 */