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];
50 static int dynspr_base, dynspr_count;
52 static int num_tur, total_tur;
56 struct screen *init_game_screen(void)
61 static int gamescr_start(void)
65 gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1);
69 pos[0] = pos[1] = VOX_SZ << 15;
71 if(!(vox = vox_create(VOX_SZ, VOX_SZ, height_pixels, color_pixels))) {
72 panic(get_pc(), "vox_create");
74 vox_proj(vox, FOV, NEAR, FAR);
75 vox_view(vox, pos[0], pos[1], -40, angle);
77 /* setup color image palette */
78 for(i=0; i<256; i++) {
79 int r = color_cmap[i * 3];
80 int g = color_cmap[i * 3 + 1];
81 int b = color_cmap[i * 3 + 2];
82 gba_bgpal[i] = (((uint16_t)b << 7) & 0x7c00) | (((uint16_t)g << 2) & 0x3e0) | (((uint16_t)r >> 3) & 0x1f);
86 interrupt(INTR_HBLANK, hblank);
87 REG_DISPSTAT |= DISPSTAT_IEN_HBLANK;
92 spr_setup(16, 8, spr_game_pixels, spr_game_cmap);
96 for(i=0; i<MAX_SPR; i++) {
97 spr_oam_clear(oam, i);
101 spr_oam(oam, sidx++, SPRID_CROSS, 120-8, 80-8, SPR_SZ16 | SPR_256COL);
102 spr_oam(oam, sidx++, SPRID_UIMID, 0, 144, SPR_VRECT | SPR_256COL);
103 spr_oam(oam, sidx++, SPRID_UIRIGHT, 48, 144, SPR_SZ16 | SPR_256COL);
104 spr_oam(oam, sidx++, SPRID_UILEFT, 168, 144, SPR_SZ16 | SPR_256COL);
105 spr_oam(oam, sidx++, SPRID_UITGT, 184, 144, SPR_SZ16 | SPR_256COL);
106 spr_oam(oam, sidx++, SPRID_UISLASH, 216, 144, SPR_VRECT | SPR_256COL);
110 dma_copy32(3, (void*)OAM_ADDR, oam, sidx * 2, 0);
120 static void gamescr_stop(void)
122 /*mask(INTR_HBLANK);*/
125 static void gamescr_frame(void)
127 backbuf = ++nframes & 1;
128 framebuf = vram[backbuf];
130 vox_framebuf(vox, 240, 160, framebuf, horizon);
139 if(!(nframes & 15)) {
140 emuprint("vbl: %d", vblperf_count);
149 #define NS(x) (SPRID_UINUM + ((x) << 1))
150 static int numspr[][2] = {
151 {NS(0),NS(0)}, {NS(0),NS(1)}, {NS(0),NS(2)}, {NS(0),NS(3)}, {NS(0),NS(4)},
152 {NS(0),NS(5)}, {NS(0),NS(6)}, {NS(0),NS(7)}, {NS(0),NS(8)}, {NS(0),NS(9)},
153 {NS(1),NS(0)}, {NS(1),NS(1)}, {NS(1),NS(2)}, {NS(1),NS(3)}, {NS(1),NS(4)},
154 {NS(1),NS(5)}, {NS(1),NS(6)}, {NS(1),NS(7)}, {NS(1),NS(8)}, {NS(1),NS(9)},
155 {NS(2),NS(0)}, {NS(2),NS(1)}, {NS(2),NS(2)}, {NS(2),NS(3)}, {NS(2),NS(4)},
156 {NS(2),NS(5)}, {NS(2),NS(6)}, {NS(2),NS(7)}, {NS(2),NS(8)}, {NS(2),NS(9)},
157 {NS(3),NS(0)}, {NS(3),NS(1)}, {NS(3),NS(2)}, {NS(3),NS(3)}, {NS(3),NS(4)},
158 {NS(3),NS(5)}, {NS(3),NS(6)}, {NS(3),NS(7)}, {NS(3),NS(8)}, {NS(3),NS(9)}
161 #define WALK_SPEED 0x40000
162 #define TURN_SPEED 0x200
165 static void update(void)
167 int32_t fwd[2], right[2];
172 if(KEYPRESS(BN_SELECT)) {
177 if(keystate & BN_LEFT) {
180 if(keystate & BN_RIGHT) {
184 fwd[0] = -SIN(angle);
189 if(keystate & BN_A) {
194 if(keystate & BN_DOWN) {
199 if(keystate & BN_UP) {
200 if(horizon > 40) horizon -= ELEV_SPEED;
202 if(keystate & BN_DOWN) {
203 if(horizon < 200 - ELEV_SPEED) horizon += ELEV_SPEED;
205 if(keystate & BN_RT) {
209 if(keystate & BN_LT) {
214 vox_view(vox, pos[0], pos[1], -40, angle);
218 spr_oam(oam, dynspr_base, numspr[num_tur][0], 200, 144, SPR_VRECT | SPR_256COL);
219 spr_oam(oam, dynspr_base + 1, numspr[num_tur][1], 208, 144, SPR_VRECT | SPR_256COL);
220 spr_oam(oam, dynspr_base + 2, numspr[total_tur][0], 224, 144, SPR_VRECT | SPR_256COL);
221 spr_oam(oam, dynspr_base + 3, numspr[total_tur][1], 232, 144, SPR_VRECT | SPR_256COL);
223 if(energy == MAX_ENERGY) {
224 ledspr = SPRID_LEDBLU;
226 ledspr = energy > 2 ? SPRID_LEDGRN : SPRID_LEDRED;
229 spr_oam(oam, dynspr_base + i + 4, i >= energy ? SPRID_LEDOFF : ledspr,
230 8 + (i << 3), 144, SPR_VRECT | SPR_256COL);
235 static void draw(void)
237 //dma_fill16(3, framebuf, 0, 240 * 160 / 2);
238 fillblock_16byte(framebuf, 0, 240 * 160 / 16);
241 //vox_sky_grad(vox, COLOR_HORIZON, COLOR_ZENITH);
242 //vox_sky_solid(vox, COLOR_ZENITH);
245 #define MAXBANK 0x100
248 static void gamescr_vblank(void)
250 static int bank, bankdir, theta, s;
255 dma_copy32(3, (void*)(OAM_ADDR + dynspr_base * 8), oam + dynspr_base * 4, dynspr_count * 2, 0);
257 theta = -(bank << 3);
259 s = 0x100000 / (MAXBANK + (abs(bank) >> 3));
260 sa = ((SIN(theta) >> 8) * s) >> 12;
261 ca = ((COS(theta) >> 8) * s) >> 12;
263 s = (MAXBANK + (abs(bank) >> 3));
268 REG_BG2X = -ca * 120 - sa * 80 + (120 << 8);
269 REG_BG2Y = sa * 120 - ca * 80 + (80 << 8);
276 keystate = ~REG_KEYINPUT;
278 if((keystate & (BN_LEFT | BN_RIGHT)) == 0) {
280 bank -= bankdir << 4;
282 } else if(keystate & BN_LEFT) {
284 if(bank > -MAXBANK) bank -= 16;
285 } else if(keystate & BN_RIGHT) {
287 if(bank < MAXBANK) bank += 16;
292 static uint16_t skygrad[] __attribute__((section(".data"))) = {
294 0x662a, 0x660a, 0x660a, 0x660b, 0x660b, 0x660b, 0x660b, 0x6a0b, 0x6a0c,
295 0x6a0c, 0x6a0c, 0x6a0c, 0x6a0c, 0x6a0d, 0x6a0d, 0x6a0d, 0x6a0d, 0x6a0d,
296 0x6a0d, 0x6a0e, 0x6e0e, 0x6e0e, 0x6e0e, 0x6e0e, 0x6e0f, 0x6e0f, 0x6e0f,
297 0x6e0f, 0x6e0f, 0x6e0f, 0x6e10, 0x6e10, 0x7210, 0x7210, 0x7210, 0x7211,
298 0x7211, 0x7211, 0x71f1, 0x71f1, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2,
299 0x75f2, 0x75f3, 0x75f3, 0x75f3, 0x75f3, 0x75f3, 0x75f4, 0x75f4, 0x75f4,
300 0x75f4, 0x75f4, 0x75f5, 0x79f5, 0x79f5, 0x79f5, 0x79f5, 0x79f5, 0x79f6,
301 0x79f6, 0x79f6, 0x79f6, 0x79f6, 0x79f7, 0x79f7, 0x79f7, 0x7df7, 0x7df7,
302 0x7df7, 0x7df8, 0x7df8, 0x7df8, 0x7dd8, 0x7dd8, 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, 0x7dd9,
311 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
312 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9
316 static void hblank(void)
318 int vcount = REG_VCOUNT;
319 gba_bgpal[255] = skygrad[vcount];