*.zip
pushdata
link.map
+gbajam22
dep = $(src:.c=.d)
bin = gbajam22
-opt = -O0 -fno-strict-aliasing
+opt = -O0 -fno-strict-aliasing -fcommon
dbg = -g
inc = -I. -Isrc -Isrc/gba
warn = -pedantic -Wall
ifeq ($(sys), mingw)
libs = -lopengl32 -lwinmm
else
- libs = -lGL
+ libs = -lGL -lX11 -lXext
endif
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include "gbaregs.h"
+#include "intr.h"
+#include "debug.h"
+#include "gba.h"
+#include "util.h"
+
+uint16_t vblperf_color[] = {
+ /* grn blue cyan yellow orng red purple d.green purple ... */
+ /* 60 30 20 15 12 10 8.5 7.5 ... */
+ 0x3e0, 0xf863, 0xffc0, 0x3ff, 0x1ff, 0x001f, 0xf81f, 0x1e0, 0xf81f, 0xf81f, 0xf81f
+};
+
+void vblperf_setcolor(int palidx)
+{
+ vblperf_palptr = gba_bgpal + palidx;
+}
+
+
+#ifdef BUILD_GBA
+
+uint32_t panic_regs[16];
+void get_panic_regs(void);
+
+void panic(void *pc, const char *fmt, ...)
+{
+ int y;
+ va_list ap;
+ uint32_t *reg;
+
+ get_panic_regs();
+
+ intr_disable();
+ REG_DISPCNT = 4 | DISPCNT_BG2;
+
+ set_bg_color(0, 31, 0, 0);
+ set_bg_color(0xff, 31, 31, 31);
+
+ fillblock_16byte((void*)VRAM_LFB_FB0_ADDR, 0, 240 * 160 / 16);
+
+ fillblock_16byte((unsigned char*)VRAM_LFB_FB0_ADDR + 240 * 3, 0xffffffff, 240 / 16);
+ dbg_drawstr(44, 0, " Panic at %p ", pc);
+
+ va_start(ap, fmt);
+ y = dbg_vdrawstr(0, 12, fmt, ap) + 8;
+ va_end(ap);
+
+ fillblock_16byte((unsigned char*)VRAM_LFB_FB0_ADDR + 240 * (y + 4), 0xffffffff, 240 / 16);
+ y += 8;
+
+ reg = panic_regs;
+ y = dbg_drawstr(0, y, " r0 %08x r1 %08x\n r2 %08x r3 %08x\n r4 %08x r5 %08x\n r6 %08x r7 %08x\n",
+ reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6], reg[7]);
+ y = dbg_drawstr(0, y, " r8 %08x r9 %08x\nr10 %08x r11 %08x\n ip %08x sp %08x\n lr %08x pc %08x\n",
+ reg[8], reg[9], reg[10], reg[11], reg[12], reg[13], reg[14], reg[15]);
+
+ /* stop any sound/music playback */
+ REG_SOUNDCNT_H = SCNT_DSA_CLRFIFO | SCNT_DSB_CLRFIFO;
+ REG_TMCNT_H(1) &= ~TMCNT_EN;
+ REG_DMA1CNT_H = 0;
+ REG_DMA2CNT_H = 0;
+
+ for(;;);
+}
+
+#else /* non-GBA build */
+
+void panic(void *pc, const char *fmt, ...)
+{
+ va_list ap;
+
+ fputs("~~~ PANIC ~~~\n", stderr);
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fputc('\n', stderr);
+
+ abort();
+}
+
+#endif
+
+void dbg_drawglyph(int x, int y, int c)
+{
+ int i;
+ uint16_t pp;
+ unsigned char row;
+ uint16_t *ptr = (uint16_t*)VRAM_LFB_FB0_ADDR + (y << 7) - (y << 3) + (x >> 1);
+ unsigned char *fnt = font_8x8 + ((c & 0xff) << 3);
+
+ for(i=0; i<8; i++) {
+ row = *fnt++;
+ pp = row & 0x80 ? 0xff : 0;
+ *ptr++ = pp | (row & 0x40 ? 0xff00 : 0);
+ pp = row & 0x20 ? 0xff : 0;
+ *ptr++ = pp | (row & 0x10 ? 0xff00 : 0);
+ pp = row & 0x08 ? 0xff : 0;
+ *ptr++ = pp | (row & 0x04 ? 0xff00 : 0);
+ pp = row & 0x02 ? 0xff : 0;
+ *ptr++ = pp | (row & 0x01 ? 0xff00 : 0);
+ ptr += 120 - 4;
+ }
+}
+
+int dbg_vdrawstr(int x, int y, const char *fmt, va_list ap)
+{
+ int startx, c;
+ char buf[128];
+ char *ptr = buf;
+
+ vsnprintf(buf, sizeof buf, fmt, ap);
+
+ startx = x;
+ while(*ptr) {
+ if(y >= 160) break;
+
+ c = *ptr++;
+ switch(c) {
+ case '\n':
+ y += 8;
+ case '\r':
+ x = startx;
+ break;
+
+ default:
+ dbg_drawglyph(x, y, c);
+ x += 8;
+ if(x >= 240 - 8) {
+ while(*ptr && isspace(*ptr)) ptr++;
+ x = 0;
+ y += 8;
+ }
+ }
+ }
+
+ return y;
+}
+
+int dbg_drawstr(int x, int y, const char *fmt, ...)
+{
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = dbg_vdrawstr(x, y, fmt, ap);
+ va_end(ap);
+ return res;
+}
+
+#ifdef BUILD_GBA
+
+#ifdef EMUBUILD
+#define REG_DBG_ENABLE REG16(0xfff780)
+#define REG_DBG_FLAGS REG16(0xfff700)
+#define REG_DBG_STR REG8(0xfff600)
+
+/*__attribute__((target("arm")))*/
+void emuprint(const char *fmt, ...)
+{
+ static int opened;
+ char buf[128];
+ va_list ap;
+
+ if(!opened) {
+ REG_DBG_ENABLE = 0xc0de;
+ if(REG_DBG_ENABLE != 0x1dea) {
+ return;
+ }
+ opened = 1;
+ }
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof buf, fmt, ap);
+ va_end(ap);
+
+ strcpy((char*)0x4fff600, buf);
+ REG_DBG_FLAGS = 0x104; /* debug message */
+
+ /*
+ asm volatile(
+ "mov r0, %0\n\t"
+ "swi 0xff0000\n\t" :
+ : "r" (buf)
+ : "r0"
+ );
+ */
+}
+#else
+void emuprint(const char *fmt, ...)
+{
+}
+#endif
+
+#else /* non-GBA build */
+
+void emuprint(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stdout, fmt, ap);
+ va_end(ap);
+ fputc('\n', stdout);
+}
+
+#endif
--- /dev/null
+#include <string.h>
+#include "gba.h"
+#include "game.h"
+
+struct screen *init_menu_screen(void);
+struct screen *init_game_screen(void);
+
+struct screen *curscr;
+
+#define MAX_SCR 4
+static struct screen *scrlist[MAX_SCR];
+static int num_scr;
+
+int init_screens(void)
+{
+ if(!(scrlist[num_scr++] = init_menu_screen())) {
+ return -1;
+ }
+ if(!(scrlist[num_scr++] = init_game_screen())) {
+ return -1;
+ }
+ return 0;
+}
+
+int change_screen(struct screen *scr)
+{
+ if(!scr) return -1;
+
+ mask(INTR_VBLANK);
+
+ if(scr->start && scr->start() == -1) {
+ return -1;
+ }
+ if(curscr && curscr->stop) {
+ curscr->stop();
+ }
+ curscr = scr;
+
+ unmask(INTR_VBLANK);
+ return 0;
+}
+
+struct screen *find_screen(const char *name)
+{
+ int i;
+ for(i=0; i<num_scr; i++) {
+ if(strcmp(scrlist[i]->name, name) == 0) {
+ return scrlist[i];
+ }
+ }
+ return 0;
+}
#ifndef GAME_H_
#define GAME_H_
-void (*screen_vblank)(void);
+struct screen {
+ char *name;
+ int (*start)(void);
+ void (*stop)(void);
+ void (*frame)(void);
+ void (*vblank)(void);
+};
-void menuscr(void);
-void gamescr(void);
+extern struct screen *curscr;
+
+int init_screens(void);
+int change_screen(struct screen *scr);
+struct screen *find_screen(const char *name);
#endif /* GAME_H_ */
#include "xgl.h"
#include "polyfill.h"
+static int gamescr_start(void);
+static void gamescr_stop(void);
+static void gamescr_frame(void);
+static void gamescr_vblank(void);
+
static void update(void);
static void draw(void);
-#ifdef BUILD_GBA
-static void vblank(void);
-#endif
+
+static struct screen gamescr = {
+ "game",
+ gamescr_start,
+ gamescr_stop,
+ gamescr_frame,
+ gamescr_vblank
+};
static int nframes, num_vbl, backbuf;
static uint16_t *vram[] = { gba_vram_lfb0, gba_vram_lfb1 };
static struct player player;
-void gamescr(void)
+struct screen *init_game_screen(void)
+{
+ return &gamescr;
+}
+
+static int gamescr_start(void)
{
int i;
- unsigned char *fb;
uint16_t *cmap;
gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ | DISPCNT_FB1);
select_input(BN_DPAD | BN_A | BN_B);
- /* TODO emulate interrupts on non-GBA builds */
-#ifdef BUILD_GBA
- mask(INTR_VBLANK);
- screen_vblank = vblank;
- unmask(INTR_VBLANK);
-#endif
-
nframes = 0;
- for(;;) {
- backbuf = ++nframes & 1;
- fb = (unsigned char*)vram[backbuf];
+ return 0;
+}
- polyfill_framebuffer(fb, 240, 160);
- fillblock_16byte(fb, 0, 240 * 160 / 16);
+static void gamescr_stop(void)
+{
+}
- update();
- draw();
+static void gamescr_frame(void)
+{
+ unsigned char *fb;
- vblperf_end();
- wait_vblank();
- present(backbuf);
- vblperf_begin();
- }
+ backbuf = ++nframes & 1;
+ fb = (unsigned char*)vram[backbuf];
+
+ polyfill_framebuffer(fb, 240, 160);
+ fillblock_16byte(fb, 0, 240 * 160 / 16);
+
+ update();
+ draw();
+
+ vblperf_end();
+ wait_vblank();
+ present(backbuf);
+ vblperf_begin();
}
static void update(void)
#ifdef BUILD_GBA
__attribute__((noinline, target("arm"), section(".iwram")))
-static void vblank(void)
+#endif
+static void gamescr_vblank(void)
{
num_vbl++;
}
-#endif
#include <stdint.h>
#include "gbaregs.h"
+#include "intr.h"
#ifdef BUILD_GBA
-#define gba_bgpal (uint16_t*)CRAM_BG_ADDR
-#define gba_objpal (uint16_t*)CRAM_OBJ_ADDR
+#define gba_bgpal ((uint16_t*)CRAM_BG_ADDR)
+#define gba_objpal ((uint16_t*)CRAM_OBJ_ADDR)
-#define gba_vram (uint16_t*)VRAM_START_ADDR
-#define gba_vram_lfb0 (uint16_t*)VRAM_LFB_FB0_ADDR
-#define gba_vram_lfb1 (uint16_t*)VRAM_LFB_FB1_ADDR
+#define gba_vram ((uint16_t*)VRAM_START_ADDR)
+#define gba_vram_lfb0 ((uint16_t*)VRAM_LFB_FB0_ADDR)
+#define gba_vram_lfb1 ((uint16_t*)VRAM_LFB_FB1_ADDR)
#else
extern uint16_t gba_bgpal[256], gba_objpal[256];
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include "gbaregs.h"
-#include "intr.h"
-#include "debug.h"
-#include "util.h"
-
-uint16_t vblperf_color[] = {
- /* grn blue cyan yellow orng red purple d.green purple ... */
- /* 60 30 20 15 12 10 8.5 7.5 ... */
- 0x3e0, 0xf863, 0xffc0, 0x3ff, 0x1ff, 0x001f, 0xf81f, 0x1e0, 0xf81f, 0xf81f, 0xf81f
-};
-
-void vblperf_setcolor(int palidx)
-{
- vblperf_palptr = (uint16_t*)CRAM_BG_ADDR + palidx;
-}
-
-
-uint32_t panic_regs[16];
-void get_panic_regs(void);
-
-void panic(void *pc, const char *fmt, ...)
-{
- int y;
- va_list ap;
- uint32_t *reg;
-
- get_panic_regs();
-
- intr_disable();
- REG_DISPCNT = 4 | DISPCNT_BG2;
-
- set_bg_color(0, 31, 0, 0);
- set_bg_color(0xff, 31, 31, 31);
-
- fillblock_16byte((void*)VRAM_LFB_FB0_ADDR, 0, 240 * 160 / 16);
-
- fillblock_16byte((unsigned char*)VRAM_LFB_FB0_ADDR + 240 * 3, 0xffffffff, 240 / 16);
- dbg_drawstr(44, 0, " Panic at %p ", pc);
-
- va_start(ap, fmt);
- y = dbg_vdrawstr(0, 12, fmt, ap) + 8;
- va_end(ap);
-
- fillblock_16byte((unsigned char*)VRAM_LFB_FB0_ADDR + 240 * (y + 4), 0xffffffff, 240 / 16);
- y += 8;
-
- reg = panic_regs;
- y = dbg_drawstr(0, y, " r0 %08x r1 %08x\n r2 %08x r3 %08x\n r4 %08x r5 %08x\n r6 %08x r7 %08x\n",
- reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6], reg[7]);
- y = dbg_drawstr(0, y, " r8 %08x r9 %08x\nr10 %08x r11 %08x\n ip %08x sp %08x\n lr %08x pc %08x\n",
- reg[8], reg[9], reg[10], reg[11], reg[12], reg[13], reg[14], reg[15]);
-
- /* stop any sound/music playback */
- REG_SOUNDCNT_H = SCNT_DSA_CLRFIFO | SCNT_DSB_CLRFIFO;
- REG_TMCNT_H(1) &= ~TMCNT_EN;
- REG_DMA1CNT_H = 0;
- REG_DMA2CNT_H = 0;
-
- for(;;);
-}
-
-void dbg_drawglyph(int x, int y, int c)
-{
- int i;
- uint16_t pp;
- unsigned char row;
- uint16_t *ptr = (uint16_t*)VRAM_LFB_FB0_ADDR + (y << 7) - (y << 3) + (x >> 1);
- unsigned char *fnt = font_8x8 + ((c & 0xff) << 3);
-
- for(i=0; i<8; i++) {
- row = *fnt++;
- pp = row & 0x80 ? 0xff : 0;
- *ptr++ = pp | (row & 0x40 ? 0xff00 : 0);
- pp = row & 0x20 ? 0xff : 0;
- *ptr++ = pp | (row & 0x10 ? 0xff00 : 0);
- pp = row & 0x08 ? 0xff : 0;
- *ptr++ = pp | (row & 0x04 ? 0xff00 : 0);
- pp = row & 0x02 ? 0xff : 0;
- *ptr++ = pp | (row & 0x01 ? 0xff00 : 0);
- ptr += 120 - 4;
- }
-}
-
-int dbg_vdrawstr(int x, int y, const char *fmt, va_list ap)
-{
- int startx, c;
- char buf[128];
- char *ptr = buf;
-
- vsnprintf(buf, sizeof buf, fmt, ap);
-
- startx = x;
- while(*ptr) {
- if(y >= 160) break;
-
- c = *ptr++;
- switch(c) {
- case '\n':
- y += 8;
- case '\r':
- x = startx;
- break;
-
- default:
- dbg_drawglyph(x, y, c);
- x += 8;
- if(x >= 240 - 8) {
- while(*ptr && isspace(*ptr)) ptr++;
- x = 0;
- y += 8;
- }
- }
- }
-
- return y;
-}
-
-int dbg_drawstr(int x, int y, const char *fmt, ...)
-{
- int res;
- va_list ap;
-
- va_start(ap, fmt);
- res = dbg_vdrawstr(x, y, fmt, ap);
- va_end(ap);
- return res;
-}
-
-#ifdef EMUBUILD
-#define REG_DBG_ENABLE REG16(0xfff780)
-#define REG_DBG_FLAGS REG16(0xfff700)
-#define REG_DBG_STR REG8(0xfff600)
-
-/*__attribute__((target("arm")))*/
-void emuprint(const char *fmt, ...)
-{
- static int opened;
- char buf[128];
- va_list ap;
-
- if(!opened) {
- REG_DBG_ENABLE = 0xc0de;
- if(REG_DBG_ENABLE != 0x1dea) {
- return;
- }
- opened = 1;
- }
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof buf, fmt, ap);
- va_end(ap);
-
- strcpy((char*)0x4fff600, buf);
- REG_DBG_FLAGS = 0x104; /* debug message */
-
- /*
- asm volatile(
- "mov r0, %0\n\t"
- "swi 0xff0000\n\t" :
- : "r" (buf)
- : "r0"
- );
- */
-}
-#else
-void emuprint(const char *fmt, ...)
-{
-}
-#endif
+++ /dev/null
-#ifndef INTR_H_
-#define INTR_H_
-
-#include "gbaregs.h"
-
-/* interrupts */
-enum {
- INTR_VBLANK,
- INTR_HBLANK,
- INTR_VCOUNT,
- INTR_TIMER0,
- INTR_TIMER1,
- INTR_TIMER2,
- INTR_TIMER3,
- INTR_COMM,
- INTR_DMA0,
- INTR_DMA1,
- INTR_DMA2,
- INTR_DMA3,
- INTR_KEY,
- INTR_GPAK
-};
-
-void intr_init(void);
-
-/* set/clear interrupts */
-#define intr_enable() \
- do { REG_IME |= 0x0001; } while(0)
-#define intr_disable() \
- do { REG_IME &= 0xfffe; } while(0)
-
-/* set an interrupt handler */
-void interrupt(int intr, void (*handler)(void));
-
-/* mask/unmask an interrupt */
-#define mask(intr) do {REG_IE &= ~(1 << (intr));} while(0)
-#define unmask(intr) do {REG_IE |= 1 << (intr);} while(0)
-
-#endif /* INTR_H_ */
#include "maxmod.h"
static void vblank(void);
-static void nopfunc(void);
int main(void)
{
mmStart(MOD_POPCORN, MM_PLAY_LOOP);
#endif
- screen_vblank = nopfunc;
-
intr_disable();
interrupt(INTR_VBLANK, vblank);
REG_DISPSTAT |= DISPSTAT_IEN_VBLANK;
unmask(INTR_VBLANK);
intr_enable();
- gamescr();
- for(;;);
+ if(init_screens() == -1) {
+ panic(get_pc(), "failed to initialize screens");
+ }
+
+ if(change_screen(find_screen("game")) == -1) {
+ panic(get_pc(), "failed to find game screen");
+ }
+
+ for(;;) {
+ curscr->frame();
+ }
return 0;
}
{
vblperf_count++;
- screen_vblank();
+ if(curscr && curscr->vblank) {
+ curscr->vblank();
+ }
#ifndef NOSOUND
mmVBlank();
mmFrame();
#endif
}
-
-static void nopfunc(void)
-{
-}
--- /dev/null
+#ifndef INTR_H_
+#define INTR_H_
+
+#include "gbaregs.h"
+
+/* interrupts */
+enum {
+ INTR_VBLANK,
+ INTR_HBLANK,
+ INTR_VCOUNT,
+ INTR_TIMER0,
+ INTR_TIMER1,
+ INTR_TIMER2,
+ INTR_TIMER3,
+ INTR_COMM,
+ INTR_DMA0,
+ INTR_DMA1,
+ INTR_DMA2,
+ INTR_DMA3,
+ INTR_KEY,
+ INTR_GPAK
+};
+
+void intr_init(void);
+
+/* set an interrupt handler */
+void interrupt(int intr, void (*handler)(void));
+
+#ifdef BUILD_GBA
+
+/* set/clear interrupts */
+#define intr_enable() \
+ do { REG_IME |= 0x0001; } while(0)
+#define intr_disable() \
+ do { REG_IME &= 0xfffe; } while(0)
+
+/* mask/unmask an interrupt */
+#define mask(intr) do {REG_IE &= ~(1 << (intr));} while(0)
+#define unmask(intr) do {REG_IE |= 1 << (intr);} while(0)
+
+#else /* non-GBA build */
+
+void intr_enable(void);
+void intr_disable(void);
+
+void mask(int intr);
+void unmask(int intr);
+
+#endif
+
+#endif /* INTR_H_ */
-#include "gbaregs.h"
+#include "game.h"
-void menuscr(void)
+static int menuscr_start(void);
+static void menuscr_stop(void);
+static void menuscr_frame(void);
+
+static struct screen menuscr = {
+ "menu",
+ menuscr_start,
+ menuscr_stop,
+ menuscr_frame,
+ 0
+};
+
+struct screen *init_menu_screen(void)
+{
+ return &menuscr;
+}
+
+static int menuscr_start(void)
+{
+ return 0;
+}
+
+static void menuscr_stop(void)
+{
+}
+
+static void menuscr_frame(void)
{
}
--- /dev/null
+#include <string.h>
+#include "intr.h"
+
+static void (*intrfunc[14])(void);
+static unsigned int intrmask;
+
+#define IE 0x8000
+
+void intr_init(void)
+{
+ memset(intrfunc, 0, sizeof intrfunc);
+}
+
+void interrupt(int intr, void (*handler)(void))
+{
+ intrfunc[intr] = handler;
+}
+
+void intr_enable(void)
+{
+ intrmask |= IE;
+}
+
+void intr_disable(void)
+{
+ intrmask &= ~IE;
+}
+
+void mask(int intr)
+{
+ intrmask &= ~(1 << intr);
+}
+
+void unmask(int intr)
+{
+ intrmask |= 1 << intr;
+}
#include "miniglut.h"
#include "game.h"
#include "gba.h"
+#include "input.h"
+#include "debug.h"
static void display(void);
+static void vblank(void);
static void idle(void);
static void reshape(int x, int y);
static void keydown(unsigned char key, int x, int y);
static unsigned long start_time;
static unsigned int modkeys;
+static uint16_t bnstate, bnmask;
+
static float win_aspect;
static unsigned int tex;
glLoadIdentity();
glScalef(240.0f / tex_xsz, 160.0f / tex_ysz, 1);
- gamescr();
+ intr_disable();
+ interrupt(INTR_VBLANK, vblank);
+ unmask(INTR_VBLANK);
+ intr_enable();
+
+ if(init_screens() == -1) {
+ fprintf(stderr, "failed to initialize screens");
+ return 1;
+ }
+
+ if(change_screen(find_screen("game")) == -1) {
+ fprintf(stderr, "failed to find game screen");
+ return 1;
+ }
+
+ glutMainLoop();
return 0;
}
-void blit_frame(void *pixels, int vsync)
+void select_input(uint16_t bmask)
+{
+ bnstate = 0;
+ bnmask = bmask;
+}
+
+uint16_t get_input(void)
+{
+ uint16_t s = bnstate;
+ bnstate = 0;
+ return s;
+}
+
+#define PACK_RGB32(r, g, b) \
+ ((((r) & 0xff) << 16) | (((g) & 0xff) << 8) | ((b) & 0xff) | 0xff000000)
+
+#define UNPACK_R16(c) (((c) >> 9) & 0xf8)
+#define UNPACK_G16(c) (((c) >> 3) & 0xf8)
+#define UNPACK_B16(c) (((c) << 3) & 0xf8)
+
+void present(int buf)
{
- int i, npix = fb_width * fb_height;
+ int i, npix = 240 * 160;
uint32_t *dptr = convbuf;
- uint16_t *sptr = pixels;
+ uint8_t *sptr = buf ? gba_vram_lfb1 : gba_vram_lfb0;
for(i=0; i<npix; i++) {
- int r = UNPACK_R16(*sptr);
- int g = UNPACK_G16(*sptr);
- int b = UNPACK_B16(*sptr);
+ int idx = *sptr++;
+ int r = UNPACK_R16(gba_bgpal[idx]);
+ int g = UNPACK_G16(gba_bgpal[idx]);
+ int b = UNPACK_B16(gba_bgpal[idx]);
*dptr++ = PACK_RGB32(b, g, r);
- sptr++;
}
glBindTexture(GL_TEXTURE_2D, tex);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, fb_width, fb_height, GL_RGBA,
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 240, 160, GL_RGBA,
GL_UNSIGNED_BYTE, convbuf);
glMatrixMode(GL_MODELVIEW);
assert(glGetError() == GL_NO_ERROR);
}
-int kb_isdown(int key)
+static void display(void)
{
- switch(key) {
- case KB_ANY:
- return num_pressed;
-
- case KB_ALT:
- return keystate[KB_LALT] + keystate[KB_RALT];
-
- case KB_CTRL:
- return keystate[KB_LCTRL] + keystate[KB_RCTRL];
- }
-
- if(isalpha(key)) {
- key = tolower(key);
+ if(curscr) {
+ curscr->frame();
}
- return keystate[key];
}
-static void display(void)
+static void vblank(void)
{
- inp_update();
+ vblperf_count++;
- time_msec = get_msec();
- draw();
+ if(curscr && curscr->vblank) {
+ curscr->vblank();
+ }
}
static void idle(void)
glViewport(0, 0, x, y);
}
+static int bnmap(int key)
+{
+ switch(key) {
+ case GLUT_KEY_LEFT:
+ return BN_LEFT;
+ case GLUT_KEY_RIGHT:
+ return BN_RIGHT;
+ case GLUT_KEY_UP:
+ return BN_UP;
+ case GLUT_KEY_DOWN:
+ return BN_DOWN;
+ case 'x':
+ return BN_A;
+ case 'z':
+ return BN_B;
+ case 'a':
+ return BN_LT;
+ break;
+ case 's':
+ return BN_RT;
+ case ' ':
+ return BN_SELECT;
+ case '\n':
+ return BN_START;
+ default:
+ break;
+ }
+ return -1;
+}
+
static void keydown(unsigned char key, int x, int y)
{
- modkeys = glutGetModifiers();
+ int bn = bnmap(key);
+ if(bn != -1) {
+ bnstate |= bn;
+ }
- keystate[key] = 1;
- //game_key(key, 1);
+ if(key == 27) {
+ exit(0);
+ }
}
static void keyup(unsigned char key, int x, int y)
{
- keystate[key] = 0;
- //game_key(key, 0);
+ int bn = bnmap(key);
+ if(bn != -1) {
+ bnstate &= ~bn;
+ }
}
static void skeydown(int key, int x, int y)
{
- key = translate_special(key);
- keystate[key] = 1;
- //game_key(key, 1);
+ int bn = bnmap(key);
+ if(bn != -1) {
+ bnstate |= bn;
+ }
}
static void skeyup(int key, int x, int y)
{
- key = translate_special(key);
- keystate[key] = 0;
- //game_key(key, 0);
-}
-
-static int translate_special(int skey)
-{
- switch(skey) {
- case 127:
- return 127;
-/* case GLUT_KEY_LEFT:
- return KB_LEFT;
- case GLUT_KEY_RIGHT:
- return KB_RIGHT;
- case GLUT_KEY_UP:
- return KB_UP;
- case GLUT_KEY_DOWN:
- return KB_DOWN;
- case GLUT_KEY_PAGE_UP:
- return KB_PGUP;
- case GLUT_KEY_PAGE_DOWN:
- return KB_PGDN;
- case GLUT_KEY_HOME:
- return KB_HOME;
- case GLUT_KEY_END:
- return KB_END;
- default:
- if(skey >= GLUT_KEY_F1 && skey <= GLUT_KEY_F12) {
- return KB_F1 + skey - GLUT_KEY_F1;
- }
- */
+ int bn = bnmap(key);
+ if(bn != -1) {
+ bnstate &= ~bn;
}
- return 0;
}
static unsigned int next_pow2(unsigned int x)
memcpy(res, s, len + 1);
return res;
}
+
+#ifndef BUILD_GBA
+/* utility functions which are implemented in assembly on GBA builds */
+
+void fillblock_16byte(void *dest, uint32_t val, int count)
+{
+ int i;
+ uint32_t *p = dest;
+
+ for(i=0; i<count; i++) {
+ p[0] = val;
+ p[1] = val;
+ p[2] = val;
+ p[3] = val;
+ p += 4;
+ }
+}
+
+void *get_pc(void)
+{
+ return 0; /* not useful on PC builds */
+}
+
+void *get_sp(void)
+{
+ return 0; /* not useful on PC builds */
+}
+#endif
#include <stdlib.h>
#include <stdint.h>
+#include "gba.h"
+
+#ifdef BUILD_GBA
#define wait_vblank() \
do { \
REG_DISPCNT = DISPCNT_BG2 | DISPCNT_OBJ | 4 | ((x) << 4); \
} while(0)
+#else /* non-GBA build */
+#define wait_vblank()
+
+void present(int buf); /* defined in src/pc/main.c */
+#endif
#define set_bg_color(idx, r, g, b) \
- do { \
- ((uint16_t*)CRAM_BG_ADDR)[idx] = (uint16_t)(r) | ((uint16_t)(g) << 5) | ((uint16_t)(b) << 10); \
- } while(0)
+ gba_bgpal[idx] = (uint16_t)(r) | ((uint16_t)(g) << 5) | ((uint16_t)(b) << 10)
extern int16_t sinlut[];