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, scale;
210 theta = -(bank << 3);
211 scale = MAXBANK + (abs(bank) >> 3);
212 sa = SIN(theta) / scale;
213 ca = COS(theta) / scale;
215 REG_BG2X = -ca * 120 - sa * 80 + (120 << 8);
216 REG_BG2Y = sa * 120 - ca * 80 + (80 << 8);
223 keystate = ~REG_KEYINPUT;
225 if((keystate & (BN_LEFT | BN_RIGHT)) == 0) {
227 bank -= bankdir << 4;
229 } else if(keystate & BN_LEFT) {
231 if(bank > -MAXBANK) bank -= 16;
232 } else if(keystate & BN_RIGHT) {
234 if(bank < MAXBANK) bank += 16;
239 static uint16_t skygrad[] __attribute__((section(".data"))) = {
241 0x662a, 0x660a, 0x660a, 0x660b, 0x660b, 0x660b, 0x660b, 0x6a0b, 0x6a0c,
242 0x6a0c, 0x6a0c, 0x6a0c, 0x6a0c, 0x6a0d, 0x6a0d, 0x6a0d, 0x6a0d, 0x6a0d,
243 0x6a0d, 0x6a0e, 0x6e0e, 0x6e0e, 0x6e0e, 0x6e0e, 0x6e0f, 0x6e0f, 0x6e0f,
244 0x6e0f, 0x6e0f, 0x6e0f, 0x6e10, 0x6e10, 0x7210, 0x7210, 0x7210, 0x7211,
245 0x7211, 0x7211, 0x71f1, 0x71f1, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2,
246 0x75f2, 0x75f3, 0x75f3, 0x75f3, 0x75f3, 0x75f3, 0x75f4, 0x75f4, 0x75f4,
247 0x75f4, 0x75f4, 0x75f5, 0x79f5, 0x79f5, 0x79f5, 0x79f5, 0x79f5, 0x79f6,
248 0x79f6, 0x79f6, 0x79f6, 0x79f6, 0x79f7, 0x79f7, 0x79f7, 0x7df7, 0x7df7,
249 0x7df7, 0x7df8, 0x7df8, 0x7df8, 0x7dd8, 0x7dd8, 0x7dd9, 0x7dd9,
251 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
252 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
253 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
254 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
255 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9,
256 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 0x7dd9, 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
263 static void hblank(void)
265 int vcount = REG_VCOUNT;
266 gba_bgpal[255] = skygrad[vcount];