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