19 static int gamescr_start(void);
20 static void gamescr_stop(void);
21 static void gamescr_frame(void);
22 static void gamescr_vblank(void);
24 static void update(void);
25 static void draw(void);
27 static struct screen gamescr = {
35 static uint16_t *framebuf;
37 static int nframes, backbuf;
38 static uint16_t *vram[] = { gba_vram_lfb0, gba_vram_lfb1 };
40 static int32_t pos[2], angle, horizon = 80;
41 static struct voxscape *vox;
43 #define COLOR_HORIZON 192
44 #define COLOR_ZENITH 255
47 static uint16_t oam[4 * MAX_SPR];
48 static int dynspr_base, dynspr_count;
50 static int num_tur, total_tur;
54 struct screen *init_game_screen(void)
59 static int gamescr_start(void)
63 gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1);
67 pos[0] = pos[1] = VOX_SZ << 15;
69 if(!(vox = vox_create(VOX_SZ, VOX_SZ, height_pixels, color_pixels))) {
70 panic(get_pc(), "vox_create");
72 vox_proj(vox, FOV, NEAR, FAR);
73 vox_view(vox, pos[0], pos[1], -40, angle);
75 /* setup color image palette */
76 for(i=0; i<256; i++) {
77 int r = color_cmap[i * 3];
78 int g = color_cmap[i * 3 + 1];
79 int b = color_cmap[i * 3 + 2];
80 gba_bgpal[i] = (((uint16_t)b << 7) & 0x7c00) | (((uint16_t)g << 2) & 0x3e0) | (((uint16_t)r >> 3) & 0x1f);
84 interrupt(INTR_HBLANK, hblank);
85 REG_DISPSTAT |= DISPSTAT_IEN_HBLANK;
90 spr_setup(16, 8, spr_game_pixels, spr_game_cmap);
94 for(i=0; i<MAX_SPR; i++) {
95 spr_oam_clear(oam, i);
99 spr_oam(oam, sidx++, SPRID_CROSS, 120-8, 80-8, SPR_SZ16 | SPR_256COL);
100 spr_oam(oam, sidx++, SPRID_UIMID, 0, 144, SPR_VRECT | SPR_256COL);
101 spr_oam(oam, sidx++, SPRID_UIRIGHT, 48, 144, SPR_SZ16 | SPR_256COL);
102 spr_oam(oam, sidx++, SPRID_UILEFT, 168, 144, SPR_SZ16 | SPR_256COL);
103 spr_oam(oam, sidx++, SPRID_UITGT, 184, 144, SPR_SZ16 | SPR_256COL);
104 spr_oam(oam, sidx++, SPRID_UISLASH, 216, 144, SPR_VRECT | SPR_256COL);
108 dma_copy32(3, (void*)OAM_ADDR, oam, sidx * 2, 0);
118 static void gamescr_stop(void)
120 /*mask(INTR_HBLANK);*/
123 static void gamescr_frame(void)
125 backbuf = ++nframes & 1;
126 framebuf = vram[backbuf];
128 vox_framebuf(vox, 240, 160, framebuf, horizon);
137 if(!(nframes & 15)) {
138 emuprint("vbl: %d", vblperf_count);
147 #define NS(x) (SPRID_UINUM + ((x) << 1))
148 static int numspr[][2] = {
149 {NS(0),NS(0)}, {NS(0),NS(1)}, {NS(0),NS(2)}, {NS(0),NS(3)}, {NS(0),NS(4)},
150 {NS(0),NS(5)}, {NS(0),NS(6)}, {NS(0),NS(7)}, {NS(0),NS(8)}, {NS(0),NS(9)},
151 {NS(1),NS(0)}, {NS(1),NS(1)}, {NS(1),NS(2)}, {NS(1),NS(3)}, {NS(1),NS(4)},
152 {NS(1),NS(5)}, {NS(1),NS(6)}, {NS(1),NS(7)}, {NS(1),NS(8)}, {NS(1),NS(9)},
153 {NS(2),NS(0)}, {NS(2),NS(1)}, {NS(2),NS(2)}, {NS(2),NS(3)}, {NS(2),NS(4)},
154 {NS(2),NS(5)}, {NS(2),NS(6)}, {NS(2),NS(7)}, {NS(2),NS(8)}, {NS(2),NS(9)},
155 {NS(3),NS(0)}, {NS(3),NS(1)}, {NS(3),NS(2)}, {NS(3),NS(3)}, {NS(3),NS(4)},
156 {NS(3),NS(5)}, {NS(3),NS(6)}, {NS(3),NS(7)}, {NS(3),NS(8)}, {NS(3),NS(9)}
159 #define WALK_SPEED 0x40000
160 #define TURN_SPEED 0x200
163 static void update(void)
165 int32_t fwd[2], right[2];
170 if(KEYPRESS(BN_SELECT)) {
175 if(keystate & BN_LEFT) {
178 if(keystate & BN_RIGHT) {
182 fwd[0] = -SIN(angle);
187 if(keystate & BN_A) {
192 if(keystate & BN_DOWN) {
197 if(keystate & BN_UP) {
198 if(horizon > 40) horizon -= ELEV_SPEED;
200 if(keystate & BN_DOWN) {
201 if(horizon < 200 - ELEV_SPEED) horizon += ELEV_SPEED;
203 if(keystate & BN_RT) {
207 if(keystate & BN_LT) {
212 vox_view(vox, pos[0], pos[1], -40, angle);
216 spr_oam(oam, dynspr_base, numspr[num_tur][0], 200, 144, SPR_VRECT | SPR_256COL);
217 spr_oam(oam, dynspr_base + 1, numspr[num_tur][1], 208, 144, SPR_VRECT | SPR_256COL);
218 spr_oam(oam, dynspr_base + 2, numspr[total_tur][0], 224, 144, SPR_VRECT | SPR_256COL);
219 spr_oam(oam, dynspr_base + 3, numspr[total_tur][1], 232, 144, SPR_VRECT | SPR_256COL);
221 if(energy == MAX_ENERGY) {
222 ledspr = SPRID_LEDBLU;
224 ledspr = energy > 2 ? SPRID_LEDGRN : SPRID_LEDRED;
227 spr_oam(oam, dynspr_base + i + 4, i >= energy ? SPRID_LEDOFF : ledspr,
228 8 + (i << 3), 144, SPR_VRECT | SPR_256COL);
233 static void draw(void)
235 //dma_fill16(3, framebuf, 0, 240 * 160 / 2);
236 fillblock_16byte(framebuf, 0, 240 * 160 / 16);
239 //vox_sky_grad(vox, COLOR_HORIZON, COLOR_ZENITH);
240 //vox_sky_solid(vox, COLOR_ZENITH);
243 #define MAXBANK 0x100
246 static void gamescr_vblank(void)
248 static int bank, bankdir, theta, s;
253 dma_copy32(3, (void*)(OAM_ADDR + dynspr_base * 8), oam + dynspr_base * 4, dynspr_count * 2, 0);
255 theta = -(bank << 3);
257 s = 0x100000 / (MAXBANK + (abs(bank) >> 3));
258 sa = ((SIN(theta) >> 8) * s) >> 12;
259 ca = ((COS(theta) >> 8) * s) >> 12;
261 s = (MAXBANK + (abs(bank) >> 3));
266 REG_BG2X = -ca * 120 - sa * 80 + (120 << 8);
267 REG_BG2Y = sa * 120 - ca * 80 + (80 << 8);
274 keystate = ~REG_KEYINPUT;
276 if((keystate & (BN_LEFT | BN_RIGHT)) == 0) {
278 bank -= bankdir << 4;
280 } else if(keystate & BN_LEFT) {
282 if(bank > -MAXBANK) bank -= 16;
283 } else if(keystate & BN_RIGHT) {
285 if(bank < MAXBANK) bank += 16;
290 static uint16_t skygrad[] __attribute__((section(".data"))) = {
292 0x662a, 0x660a, 0x660a, 0x660b, 0x660b, 0x660b, 0x660b, 0x6a0b, 0x6a0c,
293 0x6a0c, 0x6a0c, 0x6a0c, 0x6a0c, 0x6a0d, 0x6a0d, 0x6a0d, 0x6a0d, 0x6a0d,
294 0x6a0d, 0x6a0e, 0x6e0e, 0x6e0e, 0x6e0e, 0x6e0e, 0x6e0f, 0x6e0f, 0x6e0f,
295 0x6e0f, 0x6e0f, 0x6e0f, 0x6e10, 0x6e10, 0x7210, 0x7210, 0x7210, 0x7211,
296 0x7211, 0x7211, 0x71f1, 0x71f1, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2,
297 0x75f2, 0x75f3, 0x75f3, 0x75f3, 0x75f3, 0x75f3, 0x75f4, 0x75f4, 0x75f4,
298 0x75f4, 0x75f4, 0x75f5, 0x79f5, 0x79f5, 0x79f5, 0x79f5, 0x79f5, 0x79f6,
299 0x79f6, 0x79f6, 0x79f6, 0x79f6, 0x79f7, 0x79f7, 0x79f7, 0x7df7, 0x7df7,
300 0x7df7, 0x7df8, 0x7df8, 0x7df8, 0x7dd8, 0x7dd8, 0x7dd9, 0x7dd9,
302 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
303 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
304 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
305 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
306 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
307 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
308 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
309 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
310 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9
314 static void hblank(void)
316 int vcount = REG_VCOUNT;
317 gba_bgpal[255] = skygrad[vcount];