From b0f9c6ecc15c2d4b5df77a7a963b742a6352ee1a Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Thu, 6 Oct 2022 19:35:46 +0300 Subject: [PATCH] pc port works --- .gitignore | 1 + Makefile.pc | 4 +- src/debug.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/game.c | 52 ++++++++++++++ src/game.h | 15 +++- src/gamescr.c | 68 +++++++++++------- src/gba.h | 11 +-- src/gba/debug.c | 173 --------------------------------------------- src/gba/intr.h | 39 ----------- src/gba/main.c | 24 ++++--- src/intr.h | 51 ++++++++++++++ src/menuscr.c | 30 +++++++- src/pc/intr.c | 37 ++++++++++ src/pc/main.c | 173 +++++++++++++++++++++++++++------------------ src/util.c | 28 ++++++++ src/util.h | 12 +++- 16 files changed, 597 insertions(+), 331 deletions(-) create mode 100644 src/debug.c create mode 100644 src/game.c delete mode 100644 src/gba/debug.c delete mode 100644 src/gba/intr.h create mode 100644 src/intr.h create mode 100644 src/pc/intr.c diff --git a/.gitignore b/.gitignore index 31ff1c8..1dd77b1 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ data *.zip pushdata link.map +gbajam22 diff --git a/Makefile.pc b/Makefile.pc index 14c7d41..9770eda 100644 --- a/Makefile.pc +++ b/Makefile.pc @@ -4,7 +4,7 @@ obj = $(src:.c=.o) $(ssrc:.s=.o) 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 @@ -18,7 +18,7 @@ sys = $(shell uname -s | sed 's/MINGW.*/mingw/') ifeq ($(sys), mingw) libs = -lopengl32 -lwinmm else - libs = -lGL + libs = -lGL -lX11 -lXext endif diff --git a/src/debug.c b/src/debug.c new file mode 100644 index 0000000..2410574 --- /dev/null +++ b/src/debug.c @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include +#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 diff --git a/src/game.c b/src/game.c new file mode 100644 index 0000000..38136aa --- /dev/null +++ b/src/game.c @@ -0,0 +1,52 @@ +#include +#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; iname, name) == 0) { + return scrlist[i]; + } + } + return 0; +} diff --git a/src/game.h b/src/game.h index b290634..66928f8 100644 --- a/src/game.h +++ b/src/game.h @@ -1,9 +1,18 @@ #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_ */ diff --git a/src/gamescr.c b/src/gamescr.c index e71c6e1..7c027dc 100644 --- a/src/gamescr.c +++ b/src/gamescr.c @@ -14,11 +14,21 @@ #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 }; @@ -58,10 +68,14 @@ static struct level *lvl; 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); @@ -85,29 +99,31 @@ void gamescr(void) 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) @@ -148,8 +164,8 @@ static void draw(void) #ifdef BUILD_GBA __attribute__((noinline, target("arm"), section(".iwram"))) -static void vblank(void) +#endif +static void gamescr_vblank(void) { num_vbl++; } -#endif diff --git a/src/gba.h b/src/gba.h index 0ca2c3a..5061c68 100644 --- a/src/gba.h +++ b/src/gba.h @@ -3,14 +3,15 @@ #include #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]; diff --git a/src/gba/debug.c b/src/gba/debug.c deleted file mode 100644 index 9bdf5d1..0000000 --- a/src/gba/debug.c +++ /dev/null @@ -1,173 +0,0 @@ -#include -#include -#include -#include -#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 diff --git a/src/gba/intr.h b/src/gba/intr.h deleted file mode 100644 index 859b9a7..0000000 --- a/src/gba/intr.h +++ /dev/null @@ -1,39 +0,0 @@ -#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_ */ diff --git a/src/gba/main.c b/src/gba/main.c index 068f3d1..8417df1 100644 --- a/src/gba/main.c +++ b/src/gba/main.c @@ -6,7 +6,6 @@ #include "maxmod.h" static void vblank(void); -static void nopfunc(void); int main(void) { @@ -28,17 +27,24 @@ 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; } @@ -46,14 +52,12 @@ static void vblank(void) { vblperf_count++; - screen_vblank(); + if(curscr && curscr->vblank) { + curscr->vblank(); + } #ifndef NOSOUND mmVBlank(); mmFrame(); #endif } - -static void nopfunc(void) -{ -} diff --git a/src/intr.h b/src/intr.h new file mode 100644 index 0000000..8201df7 --- /dev/null +++ b/src/intr.h @@ -0,0 +1,51 @@ +#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_ */ diff --git a/src/menuscr.c b/src/menuscr.c index dfbc8cb..2c82d70 100644 --- a/src/menuscr.c +++ b/src/menuscr.c @@ -1,5 +1,31 @@ -#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) { } diff --git a/src/pc/intr.c b/src/pc/intr.c new file mode 100644 index 0000000..86b716a --- /dev/null +++ b/src/pc/intr.c @@ -0,0 +1,37 @@ +#include +#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; +} diff --git a/src/pc/main.c b/src/pc/main.c index 91ce9da..df6a3f7 100644 --- a/src/pc/main.c +++ b/src/pc/main.c @@ -5,8 +5,11 @@ #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); @@ -24,6 +27,8 @@ static unsigned char keystate[256]; static unsigned long start_time; static unsigned int modkeys; +static uint16_t bnstate, bnmask; + static float win_aspect; static unsigned int tex; @@ -89,26 +94,61 @@ int main(int argc, char **argv) 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; iframe(); } - 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) @@ -174,62 +203,70 @@ static void reshape(int x, int y) 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) diff --git a/src/util.c b/src/util.c index fa5b4b5..b6b62e6 100644 --- a/src/util.c +++ b/src/util.c @@ -82,3 +82,31 @@ char *strdup_nf_impl(const char *s, const char *file, int line) 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 #include +#include "gba.h" + +#ifdef BUILD_GBA #define wait_vblank() \ do { \ @@ -15,11 +18,14 @@ 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[]; -- 1.7.10.4