17 static int gamescr_start(void);
18 static void gamescr_stop(void);
19 static void gamescr_frame(void);
20 static void gamescr_vblank(void);
22 static void update(void);
23 static void draw(void);
25 static struct screen gamescr = {
33 static uint16_t *framebuf;
35 static int nframes, backbuf;
36 static uint16_t *vram[] = { gba_vram_lfb0, gba_vram_lfb1 };
38 static int32_t pos[2], angle;
39 static struct voxscape *vox;
41 #define COLOR_HORIZON 192
42 #define COLOR_ZENITH 255
45 static uint16_t oam[4 * MAX_SPR];
48 struct screen *init_game_screen(void)
53 static int gamescr_start(void)
57 gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1);
61 pos[0] = pos[1] = VOX_SZ << 15;
63 if(!(vox = vox_create(VOX_SZ, VOX_SZ, height_pixels, color_pixels))) {
64 panic(get_pc(), "vox_create");
66 vox_proj(vox, 30, 2, 85);
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);
77 interrupt(INTR_HBLANK, hblank);
78 REG_DISPSTAT |= DISPSTAT_IEN_HBLANK;
83 spr_setup(16, 2, spr_game_pixels, spr_game_cmap);
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);
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);
102 static void gamescr_stop(void)
104 /*mask(INTR_HBLANK);*/
107 static void gamescr_frame(void)
109 backbuf = ++nframes & 1;
110 framebuf = vram[backbuf];
112 vox_framebuf(vox, 240, 160, framebuf, -1);
121 if(!(nframes & 15)) {
122 emuprint("vbl: %d", vblperf_count);
131 #define WALK_SPEED 0x40000
132 #define TURN_SPEED 0x200
134 static volatile uint16_t input;
136 static void update(void)
138 int32_t fwd[2], right[2];
140 if((input = read_input())) {
142 if(input & BN_LEFT) {
145 if(input & BN_RIGHT) {
149 fwd[0] = -SIN(angle);
158 if(input & BN_DOWN) {
171 vox_view(vox, pos[0], pos[1], -40, angle);
175 static void draw(void)
177 dma_fill16(3, framebuf, 0, 240 * 160 / 2);
178 //fillblock_16byte(framebuf, 0, 240 * 160 / 16);
181 //vox_sky_grad(vox, COLOR_HORIZON, COLOR_ZENITH);
182 //vox_sky_solid(vox, COLOR_ZENITH);
185 #define MAXBANK 0x100
188 static void gamescr_vblank(void)
190 static int bank, bankdir, theta, scale;
193 theta = -(bank << 3);
194 scale = MAXBANK + (abs(bank) >> 3);
195 sa = SIN(theta) / scale;
196 ca = COS(theta) / scale;
198 REG_BG2X = -ca * 120 - sa * 80 + (120 << 8);
199 REG_BG2Y = sa * 120 - ca * 80 + (80 << 8);
206 if((input & (BN_LEFT | BN_RIGHT)) == 0) {
208 bank -= bankdir << 4;
210 } else if(input & BN_LEFT) {
212 if(bank > -MAXBANK) bank -= 16;
213 } else if(input & BN_RIGHT) {
215 if(bank < MAXBANK) bank += 16;
220 static uint16_t skygrad[] __attribute__((section(".data"))) = {
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,
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
244 static void hblank(void)
246 int vcount = REG_VCOUNT;
247 gba_bgpal[255] = skygrad[vcount];