pc port works
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 6 Oct 2022 16:35:46 +0000 (19:35 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 6 Oct 2022 16:35:46 +0000 (19:35 +0300)
16 files changed:
.gitignore
Makefile.pc
src/debug.c [new file with mode: 0644]
src/game.c [new file with mode: 0644]
src/game.h
src/gamescr.c
src/gba.h
src/gba/debug.c [deleted file]
src/gba/intr.h [deleted file]
src/gba/main.c
src/intr.h [new file with mode: 0644]
src/menuscr.c
src/pc/intr.c [new file with mode: 0644]
src/pc/main.c
src/util.c
src/util.h

index 31ff1c8..1dd77b1 100644 (file)
@@ -18,3 +18,4 @@ data
 *.zip
 pushdata
 link.map
+gbajam22
index 14c7d41..9770eda 100644 (file)
@@ -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 (file)
index 0000000..2410574
--- /dev/null
@@ -0,0 +1,210 @@
+#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
diff --git a/src/game.c b/src/game.c
new file mode 100644 (file)
index 0000000..38136aa
--- /dev/null
@@ -0,0 +1,52 @@
+#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;
+}
index b290634..66928f8 100644 (file)
@@ -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_ */
index e71c6e1..7c027dc 100644 (file)
 #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
index 0ca2c3a..5061c68 100644 (file)
--- a/src/gba.h
+++ b/src/gba.h
@@ -3,14 +3,15 @@
 
 #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];
diff --git a/src/gba/debug.c b/src/gba/debug.c
deleted file mode 100644 (file)
index 9bdf5d1..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-#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
diff --git a/src/gba/intr.h b/src/gba/intr.h
deleted file mode 100644 (file)
index 859b9a7..0000000
+++ /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_ */
index 068f3d1..8417df1 100644 (file)
@@ -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 (file)
index 0000000..8201df7
--- /dev/null
@@ -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_ */
index dfbc8cb..2c82d70 100644 (file)
@@ -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 (file)
index 0000000..86b716a
--- /dev/null
@@ -0,0 +1,37 @@
+#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;
+}
index 91ce9da..df6a3f7 100644 (file)
@@ -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; 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);
@@ -136,31 +176,20 @@ void blit_frame(void *pixels, int vsync)
        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)
@@ -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)
index fa5b4b5..b6b62e6 100644 (file)
@@ -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<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
index 18c513e..3bbafbd 100644 (file)
@@ -3,6 +3,9 @@
 
 #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[];