21 static int gamescr_start(void);
22 static void gamescr_stop(void);
23 static void gamescr_frame(void);
24 static void gamescr_vblank(void);
26 static void update(void);
27 static void draw(void);
29 static struct screen gamescr = {
37 static uint16_t *framebuf;
39 static int nframes, backbuf;
40 static uint16_t *vram[] = { gba_vram_lfb0, gba_vram_lfb1 };
42 static int32_t pos[2], angle, horizon = 80;
43 static struct voxscape *vox;
45 #define COLOR_HORIZON 192
46 #define COLOR_ZENITH 255
49 static uint16_t oam[4 * MAX_SPR];
52 struct screen *init_game_screen(void)
57 static int gamescr_start(void)
61 gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1);
65 pos[0] = pos[1] = VOX_SZ << 15;
67 if(!(vox = vox_create(VOX_SZ, VOX_SZ, height_pixels, color_pixels))) {
68 panic(get_pc(), "vox_create");
70 vox_proj(vox, FOV, NEAR, FAR);
71 vox_view(vox, pos[0], pos[1], -40, angle);
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);
82 interrupt(INTR_HBLANK, hblank);
83 REG_DISPSTAT |= DISPSTAT_IEN_HBLANK;
88 spr_setup(16, 2, spr_game_pixels, spr_game_cmap);
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);
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);
107 static void gamescr_stop(void)
109 /*mask(INTR_HBLANK);*/
112 static void gamescr_frame(void)
114 backbuf = ++nframes & 1;
115 framebuf = vram[backbuf];
117 vox_framebuf(vox, 240, 160, framebuf, horizon);
126 if(!(nframes & 15)) {
127 emuprint("vbl: %d", vblperf_count);
136 #define WALK_SPEED 0x40000
137 #define TURN_SPEED 0x200
140 static void update(void)
142 int32_t fwd[2], right[2];
146 if(KEYPRESS(BN_SELECT)) {
151 if(keystate & BN_LEFT) {
154 if(keystate & BN_RIGHT) {
158 fwd[0] = -SIN(angle);
163 if(keystate & BN_A) {
168 if(keystate & BN_DOWN) {
173 if(keystate & BN_UP) {
174 if(horizon > 40) horizon -= ELEV_SPEED;
176 if(keystate & BN_DOWN) {
177 if(horizon < 200 - ELEV_SPEED) horizon += ELEV_SPEED;
179 if(keystate & BN_RT) {
183 if(keystate & BN_LT) {
188 vox_view(vox, pos[0], pos[1], -40, angle);
192 static void draw(void)
194 dma_fill16(3, framebuf, 0, 240 * 160 / 2);
195 //fillblock_16byte(framebuf, 0, 240 * 160 / 16);
198 //vox_sky_grad(vox, COLOR_HORIZON, COLOR_ZENITH);
199 //vox_sky_solid(vox, COLOR_ZENITH);
202 #define MAXBANK 0x100
205 static void gamescr_vblank(void)
207 static int bank, bankdir, theta, s;
210 theta = -(bank << 3);
212 s = 0x100000 / (MAXBANK + (abs(bank) >> 3));
213 sa = ((SIN(theta) >> 8) * s) >> 12;
214 ca = ((COS(theta) >> 8) * s) >> 12;
216 s = (MAXBANK + (abs(bank) >> 3));
221 REG_BG2X = -ca * 120 - sa * 80 + (120 << 8);
222 REG_BG2Y = sa * 120 - ca * 80 + (80 << 8);
229 keystate = ~REG_KEYINPUT;
231 if((keystate & (BN_LEFT | BN_RIGHT)) == 0) {
233 bank -= bankdir << 4;
235 } else if(keystate & BN_LEFT) {
237 if(bank > -MAXBANK) bank -= 16;
238 } else if(keystate & BN_RIGHT) {
240 if(bank < MAXBANK) bank += 16;
245 static uint16_t skygrad[] __attribute__((section(".data"))) = {
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,
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
269 static void hblank(void)
271 int vcount = REG_VCOUNT;
272 gba_bgpal[255] = skygrad[vcount];