include zlib/Makefile
-OBJDRIVER = ${B}minimal.o ${B}squidgehack.o ${B}asmutils.o ${B}gp2x.o ${B}main.o ${B}throttle.o \
- ${B}unix-netplay.o ${B}gp2x-sound.o ${B}gp2x-video.o ${B}lnx-joystick.o \
+OBJDRIVER = ${B}minimal.o ${B}cpuctrl.o ${B}squidgehack.o ${B}asmutils.o ${B}gp2x.o ${B}main.o ${B}throttle.o \
+ ${B}unix-netplay.o ${B}gp2x-sound.o ${B}gp2x-video.o ${B}lnx-joystick.o ${B}usbjoy.o ${B}menu.o ${B}fonts.o \
drivers/common/cheat.o drivers/common/config.o drivers/common/args.o drivers/common/vidblit.o ${UNZIPOBJS} ppu.o movie.o
-LDRIVER += -L /mnt/sd/lib -L/mnt/sd/gp2x/usr/lib -lm -lz -static -Wl,-Map=fceu.map
+LDRIVER += -L /mnt/sd/lib -L/mnt/sd/gp2x/usr/lib -lm -lz -static -Wl,-Map=fceu.map
ifeq ($(asm_6502),1)
TFLAGS += -DASM_6502
smb 95-96
bm 86-87
kage 82-83
+grad 72-73
#include "../../types.h"
#include "args.h"
-void ParseEA(int x, int argc, char *argv[], ARGPSTRUCT *argsps)
+static int ParseEA(int x, int argc, char *argv[], ARGPSTRUCT *argsps)
{
- int y=0;
+ int y=0,ret=0;
do
{
if(!argsps[y].name)
{
- ParseEA(x,argc,argv,(void *)argsps[y].var);
+ ret = ParseEA(x,argc,argv,(void *)argsps[y].var);
y++;
continue;
}
if(argsps[y].subs)
{
if((x+1)>=argc)
- break;
+ return 0;
if(argsps[y].substype&0x8000)
{
*(int *)argsps[y].subs&=~(argsps[y].substype&(~0x8000));
free(*(char **)argsps[y].subs);
if(!( *(char **)argsps[y].subs=malloc(strlen(argv[x+1])+1) ))
break;
- }
+ }
strcpy(*(char **)argsps[y].subs,argv[x+1]);
break;
}
+ ret=2;
}
- if(argsps[y].var)
+ else if(argsps[y].var)
+ {
*argsps[y].var=1;
+ ret=1;
+ }
}
y++;
} while(argsps[y].var || argsps[y].subs);
+ return ret;
}
-void ParseArguments(int argc, char *argv[], ARGPSTRUCT *argsps)
+/* returns 1 if last arg was usccessfully parsed */
+int ParseArguments(int argc, char *argv[], ARGPSTRUCT *argsps)
{
- int x;
+ int x, ret=0;
for(x=0;x<argc;x++)
- ParseEA(x,argc,argv,argsps);
+ {
+ ret = ParseEA(x,argc,argv,argsps);
+ if (ret == 2) x++;
+ }
+
+ return ret;
}
int substype;
} ARGPSTRUCT;
-void ParseArguments(int argc, char *argv[], ARGPSTRUCT *argsps);
+int ParseArguments(int argc, char *argv[], ARGPSTRUCT *argsps);
void flushcache(unsigned int beginning_addr, unsigned int end_addr, unsigned int flags);\r
void block_or(void *src, size_t n, int pat);\r
void block_andor(void *src, size_t n, int andpat, int orpat);\r
+void spend_cycles(int c); // utility\r
\r
bx lr
+.global spend_cycles @ c
+
+spend_cycles:
+ mov r0, r0, lsr #2 @ 4 cycles/iteration
+ sub r0, r0, #2 @ entry/exit/init
+.sc_loop:
+ subs r0, r0, #1
+ bpl .sc_loop
+
+ bx lr
+
+
/* buggy and slow, probably because function call overhead
@ renderer helper, based on bitbank's method
--- /dev/null
+/* cpuctrl for GP2X
+ Copyright (C) 2005 Hermes/PS2Reality
+ the gamma-routine was provided by theoddbot
+ parts (c) Rlyehs Work & (C) 2006 god_at_hell
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+*/
+
+
+#include <sys/mman.h>
+#include <math.h>
+#include "cpuctrl.h"
+
+
+/* system registers */
+static struct
+{
+ unsigned short SYSCLKENREG,SYSCSETREG,FPLLVSETREG,DUALINT920,DUALINT940,DUALCTRL940,MEMTIMEX0,MEMTIMEX1;
+}
+system_reg;
+
+static unsigned short dispclockdiv;
+
+static volatile unsigned short *MEM_REG;
+
+#define SYS_CLK_FREQ 7372800
+
+
+void cpuctrl_init(void)
+{
+ extern volatile unsigned short *gp2x_memregs; /* from minimal library rlyeh */
+ MEM_REG=&gp2x_memregs[0];
+ system_reg.SYSCSETREG=MEM_REG[0x91c>>1];
+ system_reg.FPLLVSETREG=MEM_REG[0x912>>1];
+ system_reg.SYSCLKENREG=MEM_REG[0x904>>1];
+ system_reg.DUALINT920=MEM_REG[0x3B40>>1];
+ system_reg.DUALINT940=MEM_REG[0x3B42>>1];
+ system_reg.DUALCTRL940=MEM_REG[0x3B48>>1];
+ system_reg.MEMTIMEX0=MEM_REG[0x3802>>1];
+ system_reg.MEMTIMEX1=MEM_REG[0x3804>>1];
+ dispclockdiv=MEM_REG[0x924>>1];
+}
+
+
+void cpuctrl_deinit(void)
+{
+ MEM_REG[0x91c>>1]=system_reg.SYSCSETREG;
+ MEM_REG[0x910>>1]=system_reg.FPLLVSETREG;
+ MEM_REG[0x3B40>>1]=system_reg.DUALINT920;
+ MEM_REG[0x3B42>>1]=system_reg.DUALINT940;
+ MEM_REG[0x3B48>>1]=system_reg.DUALCTRL940;
+ MEM_REG[0x904>>1]=system_reg.SYSCLKENREG;
+ MEM_REG[0x924>>1]=dispclockdiv;
+ MEM_REG[0x3802>>1]=system_reg.MEMTIMEX0;
+ MEM_REG[0x3804>>1]=system_reg.MEMTIMEX1 /*| 0x9000*/;
+}
+
+
+void set_display_clock_div(unsigned div)
+{
+ div=((div & 63) | 64)<<8;
+ MEM_REG[0x924>>1]=(MEM_REG[0x924>>1] & ~(255<<8)) | div;
+}
+
+
+void set_FCLK(unsigned MHZ)
+{
+ unsigned v;
+ unsigned mdiv,pdiv=3,scale=0;
+ MHZ*=1000000;
+ mdiv=(MHZ*pdiv)/SYS_CLK_FREQ;
+ mdiv=((mdiv-8)<<8) & 0xff00;
+ pdiv=((pdiv-2)<<2) & 0xfc;
+ scale&=3;
+ v=mdiv | pdiv | scale;
+ MEM_REG[0x910>>1]=v;
+}
+
+
+void set_920_Div(unsigned short div)
+{
+ unsigned short v;
+ v = MEM_REG[0x91c>>1] & (~0x3);
+ MEM_REG[0x91c>>1] = (div & 0x7) | v;
+}
+
+
+void set_DCLK_Div( unsigned short div )
+{
+ unsigned short v;
+ v = (unsigned short)( MEM_REG[0x91c>>1] & (~(0x7 << 6)) );
+ MEM_REG[0x91c>>1] = ((div & 0x7) << 6) | v;
+}
+
+/*
+void Disable_940(void)
+{
+ MEM_REG[0x3B42>>1];
+ MEM_REG[0x3B42>>1]=0;
+ MEM_REG[0x3B46>>1]=0xffff;
+ MEM_REG[0x3B48>>1]|= (1 << 7);
+ MEM_REG[0x904>>1]&=0xfffe;
+}
+*/
+
+void set_RAM_Timings(int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD)
+{
+ tRC -= 1; tRAS -= 1; tWR -= 1; tMRD -= 1; tRFC -= 1; tRP -= 1; tRCD -= 1; // ???
+ MEM_REG[0x3802>>1] = ((tMRD & 0xF) << 12) | ((tRFC & 0xF) << 8) | ((tRP & 0xF) << 4) | (tRCD & 0xF);
+ MEM_REG[0x3804>>1] = /*0x9000 |*/ ((tRC & 0xF) << 8) | ((tRAS & 0xF) << 4) | (tWR & 0xF);
+}
+
+
+/*
+void gp2x_video_wait_vsync(void)
+{
+ MEM_REG[0x2846>>1]=(MEM_REG[0x2846>>1] | 0x20) & ~2;
+ while(!(MEM_REG[0x2846>>1] & 2));
+}
+*/
+
+void set_gamma(int g100)
+{
+ float gamma = (float) g100 / 100;
+ int i;
+ //printf ("set gamma = %f\r\n",gamma);
+ gamma = 1/gamma;
+
+ //enable gamma
+ MEM_REG[0x2880>>1]&=~(1<<12);
+
+ MEM_REG[0x295C>>1]=0;
+ for(i=0; i<256; i++)
+ {
+ unsigned char g;
+ unsigned short s;
+ g =(unsigned char)(255.0*pow(i/255.0,gamma));
+ s = (g<<8) | g;
+ MEM_REG[0x295E>>1]= s;
+ MEM_REG[0x295E>>1]= g;
+ }
+}
+
--- /dev/null
+#ifndef __CPUCTRL_H__
+#define __CPUCTRL_H__
+
+extern void cpuctrl_init(void); /* call this at first */
+extern void save_system_regs(void); /* save some registers */
+extern void cpuctrl_deinit(void);
+extern void set_display_clock_div(unsigned div);
+extern void set_FCLK(unsigned MHZ); /* adjust the clock frequency (in Mhz units) */
+extern void set_920_Div(unsigned short div); /* 0 to 7 divider (freq=FCLK/(1+div)) */
+extern void set_DCLK_Div(unsigned short div); /* 0 to 7 divider (freq=FCLK/(1+div)) */
+//extern void Disable_940(void); /* 940t down */
+//extern void gp2x_video_wait_vsync(void);
+extern void set_RAM_Timings(int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD);
+extern void set_gamma(int g100);
+
+#endif
int InitSound(void);
void WriteSound(int16 *Buffer, int Count);
+
void KillSound(void);
void SilenceSound(int s); /* DOS and SDL */
--- /dev/null
+unsigned char fontdata8x8[64*16] =
+{
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x3C,0x42,0x99,0xBD,0xBD,0x99,0x42,0x3C,0x3C,0x42,0x81,0x81,0x81,0x81,0x42,0x3C,
+ 0xFE,0x82,0x8A,0xD2,0xA2,0x82,0xFE,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00,
+ 0x80,0xC0,0xF0,0xFC,0xF0,0xC0,0x80,0x00,0x01,0x03,0x0F,0x3F,0x0F,0x03,0x01,0x00,
+ 0x18,0x3C,0x7E,0x18,0x7E,0x3C,0x18,0x00,0xEE,0xEE,0xEE,0xCC,0x00,0xCC,0xCC,0x00,
+ 0x00,0x00,0x30,0x68,0x78,0x30,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00,
+ 0x3C,0x66,0x7A,0x7A,0x7E,0x7E,0x3C,0x00,0x0E,0x3E,0x3A,0x22,0x26,0x6E,0xE4,0x40,
+ 0x18,0x3C,0x7E,0x3C,0x3C,0x3C,0x3C,0x00,0x3C,0x3C,0x3C,0x3C,0x7E,0x3C,0x18,0x00,
+ 0x08,0x7C,0x7E,0x7E,0x7C,0x08,0x00,0x00,0x10,0x3E,0x7E,0x7E,0x3E,0x10,0x00,0x00,
+ 0x58,0x2A,0xDC,0xC8,0xDC,0x2A,0x58,0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00,0x00,
+ 0x00,0x10,0x10,0x38,0x38,0x7C,0xFE,0x00,0xFE,0x7C,0x38,0x38,0x10,0x10,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x18,0x00,0x18,0x18,0x00,
+ 0x6C,0x6C,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7C,0x28,0x7C,0x28,0x00,0x00,
+ 0x10,0x38,0x60,0x38,0x0C,0x78,0x10,0x00,0x40,0xA4,0x48,0x10,0x24,0x4A,0x04,0x00,
+ 0x18,0x34,0x18,0x3A,0x6C,0x66,0x3A,0x00,0x18,0x18,0x20,0x00,0x00,0x00,0x00,0x00,
+ 0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x00,0x0C,0x06,0x06,0x06,0x06,0x06,0x0C,0x00,
+ 0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x00,0x00,
+ 0x38,0x4C,0xC6,0xC6,0xC6,0x64,0x38,0x00,0x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00,
+ 0x7C,0xC6,0x0E,0x3C,0x78,0xE0,0xFE,0x00,0x7E,0x0C,0x18,0x3C,0x06,0xC6,0x7C,0x00,
+ 0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x00,0xFC,0xC0,0xFC,0x06,0x06,0xC6,0x7C,0x00,
+ 0x3C,0x60,0xC0,0xFC,0xC6,0xC6,0x7C,0x00,0xFE,0xC6,0x0C,0x18,0x30,0x30,0x30,0x00,
+ 0x78,0xC4,0xE4,0x78,0x86,0x86,0x7C,0x00,0x7C,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
+ 0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x18,0x30,
+ 0x1C,0x38,0x70,0xE0,0x70,0x38,0x1C,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,
+ 0x70,0x38,0x1C,0x0E,0x1C,0x38,0x70,0x00,0x7C,0xC6,0xC6,0x1C,0x18,0x00,0x18,0x00,
+ 0x3C,0x42,0x99,0xA1,0xA5,0x99,0x42,0x3C,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x00,
+ 0xFC,0xC6,0xC6,0xFC,0xC6,0xC6,0xFC,0x00,0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00,
+ 0xF8,0xCC,0xC6,0xC6,0xC6,0xCC,0xF8,0x00,0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xFE,0x00,
+ 0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xC0,0x00,0x3E,0x60,0xC0,0xCE,0xC6,0x66,0x3E,0x00,
+ 0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,
+ 0x06,0x06,0x06,0x06,0xC6,0xC6,0x7C,0x00,0xC6,0xCC,0xD8,0xF0,0xF8,0xDC,0xCE,0x00,
+ 0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00,
+ 0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
+ 0xFC,0xC6,0xC6,0xC6,0xFC,0xC0,0xC0,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xCC,0x7A,0x00,
+ 0xFC,0xC6,0xC6,0xCE,0xF8,0xDC,0xCE,0x00,0x78,0xCC,0xC0,0x7C,0x06,0xC6,0x7C,0x00,
+ 0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
+ 0xC6,0xC6,0xC6,0xEE,0x7C,0x38,0x10,0x00,0xC6,0xC6,0xD6,0xFE,0xFE,0xEE,0xC6,0x00,
+ 0xC6,0xEE,0x3C,0x38,0x7C,0xEE,0xC6,0x00,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00,
+ 0xFE,0x0E,0x1C,0x38,0x70,0xE0,0xFE,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,
+ 0x60,0x60,0x30,0x18,0x0C,0x06,0x06,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,
+ 0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
+ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x3C,0x00,
+ 0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00,
+ 0x06,0x3E,0x66,0x66,0x66,0x66,0x3E,0x00,0x00,0x3C,0x66,0x66,0x7E,0x60,0x3C,0x00,
+ 0x1C,0x30,0x78,0x30,0x30,0x30,0x30,0x00,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x3C,
+ 0x60,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x00,
+ 0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x38,0x60,0x60,0x66,0x6C,0x78,0x6C,0x66,0x00,
+ 0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0xEC,0xFE,0xFE,0xFE,0xD6,0xC6,0x00,
+ 0x00,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00,
+ 0x00,0x7C,0x66,0x66,0x66,0x7C,0x60,0x60,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x06,
+ 0x00,0x7E,0x70,0x60,0x60,0x60,0x60,0x00,0x00,0x3C,0x60,0x3C,0x06,0x66,0x3C,0x00,
+ 0x30,0x78,0x30,0x30,0x30,0x30,0x1C,0x00,0x00,0x66,0x66,0x66,0x66,0x6E,0x3E,0x00,
+ 0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0xC6,0xD6,0xFE,0xFE,0x7C,0x6C,0x00,
+ 0x00,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C,
+ 0x00,0x7E,0x0C,0x18,0x30,0x60,0x7E,0x00,0x0E,0x18,0x0C,0x38,0x0C,0x18,0x0E,0x00,
+ 0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x70,0x18,0x30,0x1C,0x30,0x18,0x70,0x00,
+ 0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x10,0x28,0x10,0x54,0xAA,0x44,0x00,0x00,
+};
+
+
+/* The font is generated from Xorg clR5x8.bdf */
+/*
+COMMENT Copyright 1989 Dale Schumacher, dal@syntel.mn.org
+COMMENT 399 Beacon Ave.
+COMMENT St. Paul, MN 55104-3527
+COMMENT
+COMMENT Permission to use, copy, modify, and distribute this software and
+COMMENT its documentation for any purpose and without fee is hereby
+COMMENT granted, provided that the above copyright notice appear in all
+COMMENT copies and that both that copyright notice and this permission
+COMMENT notice appear in supporting documentation, and that the name of
+COMMENT Dale Schumacher not be used in advertising or publicity pertaining to
+COMMENT distribution of the software without specific, written prior
+COMMENT permission. Dale Schumacher makes no representations about the
+COMMENT suitability of this software for any purpose. It is provided "as
+COMMENT is" without express or implied warranty.
+COMMENT
+*/
+unsigned char fontdata6x8[256][8] = {
+{ 0x7c>>2, 0x44>>2, 0x7c>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0xff>>2, 0x7c>>2, },
+{ 0x00>>2, 0x00>>2, 0x10>>2, 0x28>>2, 0x44>>2, 0x7c>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x78>>2, 0x44>>2, 0x78>>2, 0x44>>2, 0x78>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x44>>2, 0x40>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x40>>2, 0x78>>2, 0x40>>2, 0x7c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x40>>2, 0x78>>2, 0x40>>2, 0x40>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x40>>2, 0x4c>>2, 0x44>>2, 0x3c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x44>>2, 0x7c>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x1c>>2, 0x04>>2, 0x04>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x48>>2, 0x50>>2, 0x60>>2, 0x50>>2, 0x48>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x7c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x6c>>2, 0x54>>2, 0x54>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x64>>2, 0x54>>2, 0x4c>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x78>>2, 0x44>>2, 0x78>>2, 0x40>>2, 0x40>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x0c>>2, },
+{ 0x00>>2, 0x00>>2, 0x78>>2, 0x44>>2, 0x78>>2, 0x50>>2, 0x4c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x40>>2, 0x38>>2, 0x04>>2, 0x78>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x44>>2, 0x28>>2, 0x28>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x54>>2, 0x54>>2, 0x6c>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x28>>2, 0x10>>2, 0x28>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x28>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x08>>2, 0x10>>2, 0x20>>2, 0x7c>>2, 0x00>>2, },
+{ 0xe0>>2, 0x80>>2, 0xe0>>2, 0x8c>>2, 0xf0>>2, 0x10>>2, 0x10>>2, 0x0c>>2, },
+{ 0x00>>2, 0x10>>2, 0x38>>2, 0x7c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x7c>>2, 0x38>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x18>>2, 0xfc>>2, 0x18>>2, 0x10>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x20>>2, 0x60>>2, 0xfc>>2, 0x60>>2, 0x20>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, 0x10>>2, 0x00>>2, },
+{ 0x28>>2, 0x28>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x28>>2, 0x7c>>2, 0x28>>2, 0x7c>>2, 0x28>>2, 0x00>>2, 0x00>>2, },
+{ 0x10>>2, 0x3c>>2, 0x50>>2, 0x38>>2, 0x14>>2, 0x78>>2, 0x10>>2, 0x00>>2, },
+{ 0x60>>2, 0x64>>2, 0x08>>2, 0x10>>2, 0x20>>2, 0x4c>>2, 0x0c>>2, 0x00>>2, },
+{ 0x38>>2, 0x40>>2, 0x40>>2, 0x20>>2, 0x54>>2, 0x48>>2, 0x34>>2, 0x00>>2, },
+{ 0x10>>2, 0x20>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x04>>2, 0x08>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x08>>2, 0x04>>2, 0x00>>2, },
+{ 0x40>>2, 0x20>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x20>>2, 0x40>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x54>>2, 0x38>>2, 0x54>>2, 0x10>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x10>>2, 0x7c>>2, 0x10>>2, 0x10>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x10>>2, 0x10>>2, 0x20>>2, },
+{ 0x00>>2, 0x00>>2, 0x00>>2, 0x7c>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x04>>2, 0x04>>2, 0x08>>2, 0x08>>2, 0x10>>2, 0x10>>2, 0x20>>2, 0x20>>2, },
+{ 0x38>>2, 0x44>>2, 0x4c>>2, 0x54>>2, 0x64>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x10>>2, 0x30>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x04>>2, 0x08>>2, 0x10>>2, 0x20>>2, 0x7c>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x04>>2, 0x18>>2, 0x04>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x18>>2, 0x18>>2, 0x28>>2, 0x28>>2, 0x7c>>2, 0x08>>2, 0x1c>>2, 0x00>>2, },
+{ 0x7c>>2, 0x40>>2, 0x78>>2, 0x04>>2, 0x04>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x18>>2, 0x20>>2, 0x40>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x7c>>2, 0x44>>2, 0x04>>2, 0x08>>2, 0x08>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x04>>2, 0x08>>2, 0x30>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x10>>2, 0x00>>2, 0x00>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x10>>2, 0x00>>2, 0x00>>2, 0x10>>2, 0x10>>2, 0x20>>2, },
+{ 0x00>>2, 0x0c>>2, 0x30>>2, 0xc0>>2, 0x30>>2, 0x0c>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x00>>2, 0x7c>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0xc0>>2, 0x30>>2, 0x0c>>2, 0x30>>2, 0xc0>>2, 0x00>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x04>>2, 0x08>>2, 0x10>>2, 0x00>>2, 0x10>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x5c>>2, 0x5c>>2, 0x58>>2, 0x40>>2, 0x38>>2, 0x00>>2, },
+{ 0x10>>2, 0x28>>2, 0x44>>2, 0x44>>2, 0x7c>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x78>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x70>>2, 0x48>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x48>>2, 0x70>>2, 0x00>>2, },
+{ 0x7c>>2, 0x40>>2, 0x40>>2, 0x78>>2, 0x40>>2, 0x40>>2, 0x7c>>2, 0x00>>2, },
+{ 0x7c>>2, 0x40>>2, 0x40>>2, 0x78>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x40>>2, 0x4c>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x44>>2, 0x7c>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x7c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x7c>>2, 0x00>>2, },
+{ 0x1c>>2, 0x04>>2, 0x04>>2, 0x04>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x44>>2, 0x48>>2, 0x50>>2, 0x60>>2, 0x50>>2, 0x48>>2, 0x44>>2, 0x00>>2, },
+{ 0x40>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x7c>>2, 0x00>>2, },
+{ 0x44>>2, 0x6c>>2, 0x54>>2, 0x54>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x44>>2, 0x64>>2, 0x64>>2, 0x54>>2, 0x4c>>2, 0x4c>>2, 0x44>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x78>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x0c>>2, },
+{ 0x78>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x50>>2, 0x48>>2, 0x44>>2, 0x00>>2, },
+{ 0x38>>2, 0x44>>2, 0x40>>2, 0x38>>2, 0x04>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x7c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x44>>2, 0x28>>2, 0x28>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x44>>2, 0x54>>2, 0x54>>2, 0x6c>>2, 0x44>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x28>>2, 0x10>>2, 0x28>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x44>>2, 0x44>>2, 0x28>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x7c>>2, 0x04>>2, 0x08>>2, 0x10>>2, 0x20>>2, 0x40>>2, 0x7c>>2, 0x00>>2, },
+{ 0x1c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x1c>>2, 0x00>>2, },
+{ 0x20>>2, 0x20>>2, 0x10>>2, 0x10>>2, 0x08>>2, 0x08>>2, 0x04>>2, 0x04>>2, },
+{ 0x70>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x70>>2, 0x00>>2, },
+{ 0x10>>2, 0x28>>2, 0x44>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0xfc>>2, 0x00>>2, },
+{ 0x10>>2, 0x08>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x44>>2, 0x44>>2, 0x4c>>2, 0x34>>2, 0x00>>2, },
+{ 0x40>>2, 0x40>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x3c>>2, 0x00>>2, },
+{ 0x04>>2, 0x04>>2, 0x3c>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x44>>2, 0x7c>>2, 0x40>>2, 0x38>>2, 0x00>>2, },
+{ 0x1c>>2, 0x20>>2, 0x78>>2, 0x20>>2, 0x20>>2, 0x20>>2, 0x20>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x04>>2, 0x38>>2, },
+{ 0x40>>2, 0x40>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x10>>2, 0x00>>2, 0x30>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x38>>2, 0x00>>2, },
+{ 0x08>>2, 0x00>>2, 0x38>>2, 0x08>>2, 0x08>>2, 0x08>>2, 0x08>>2, 0x70>>2, },
+{ 0x40>>2, 0x40>>2, 0x48>>2, 0x50>>2, 0x60>>2, 0x50>>2, 0x48>>2, 0x00>>2, },
+{ 0x30>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x68>>2, 0x54>>2, 0x54>>2, 0x54>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x58>>2, 0x64>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x38>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x38>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x78>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x78>>2, 0x40>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x04>>2, },
+{ 0x00>>2, 0x00>>2, 0x58>>2, 0x60>>2, 0x40>>2, 0x40>>2, 0x40>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x3c>>2, 0x40>>2, 0x38>>2, 0x04>>2, 0x78>>2, 0x00>>2, },
+{ 0x10>>2, 0x10>>2, 0x7c>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x0c>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x4c>>2, 0x34>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x6c>>2, 0x28>>2, 0x28>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x54>>2, 0x54>>2, 0x54>>2, 0x28>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x28>>2, 0x10>>2, 0x28>>2, 0x44>>2, 0x00>>2, },
+{ 0x00>>2, 0x00>>2, 0x44>>2, 0x44>>2, 0x44>>2, 0x3c>>2, 0x04>>2, 0x38>>2, },
+{ 0x00>>2, 0x00>>2, 0x7c>>2, 0x08>>2, 0x10>>2, 0x20>>2, 0x7c>>2, 0x00>>2, },
+{ 0x04>>2, 0x08>>2, 0x08>>2, 0x10>>2, 0x08>>2, 0x08>>2, 0x04>>2, 0x00>>2, },
+{ 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x10>>2, 0x00>>2, },
+{ 0x40>>2, 0x20>>2, 0x20>>2, 0x10>>2, 0x20>>2, 0x20>>2, 0x40>>2, 0x00>>2, },
+{ 0x20>>2, 0x54>>2, 0x08>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, 0x00>>2, },
+{ 0x00>>2, 0x10>>2, 0x10>>2, 0x28>>2, 0x28>>2, 0x44>>2, 0x7c>>2, 0x00>>2, },
+};
+
--- /dev/null
+
+extern unsigned char fontdata8x8[64*16];
+extern unsigned char fontdata6x8[256-32][8];
+
*/
#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <linux/soundcard.h>
+#include "../../driver.h"
#include "gp2x.h"
#include "minimal.h"
#include "throttle.h"
extern int soundvol;
-extern unsigned long gp2x_dev[8];
-// always have this call
-INLINE void gp2x_sound_frame(void *blah, void *buff, int samples)
-{
-}
void WriteSound(int16 *Buffer, int Count)
{
- write(gp2x_dev[3], Buffer, Count<<1);
+ gp2x_sound_write(Buffer, Count<<1);
SpeedThrottle();
}
-void* gp2x_write_sound(void* blah)
-{
- return NULL;
-}
-
void SilenceSound(int n)
{
soundvol=0;
#include "../../video.h"
+#include "main.h"
#include "gp2x.h"
#include "minimal.h"
+#include "fonts.h"
extern int showfps;
static char fps_str[32];
static int framesEmulated, framesRendered;
+int gp2x_palette[256];
+
int scaled_display=0;
int paletterefresh;
#define FPS_COLOR 1
-static unsigned char fontdata8x8[] =
-{
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x3C,0x42,0x99,0xBD,0xBD,0x99,0x42,0x3C,0x3C,0x42,0x81,0x81,0x81,0x81,0x42,0x3C,
- 0xFE,0x82,0x8A,0xD2,0xA2,0x82,0xFE,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00,
- 0x80,0xC0,0xF0,0xFC,0xF0,0xC0,0x80,0x00,0x01,0x03,0x0F,0x3F,0x0F,0x03,0x01,0x00,
- 0x18,0x3C,0x7E,0x18,0x7E,0x3C,0x18,0x00,0xEE,0xEE,0xEE,0xCC,0x00,0xCC,0xCC,0x00,
- 0x00,0x00,0x30,0x68,0x78,0x30,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00,
- 0x3C,0x66,0x7A,0x7A,0x7E,0x7E,0x3C,0x00,0x0E,0x3E,0x3A,0x22,0x26,0x6E,0xE4,0x40,
- 0x18,0x3C,0x7E,0x3C,0x3C,0x3C,0x3C,0x00,0x3C,0x3C,0x3C,0x3C,0x7E,0x3C,0x18,0x00,
- 0x08,0x7C,0x7E,0x7E,0x7C,0x08,0x00,0x00,0x10,0x3E,0x7E,0x7E,0x3E,0x10,0x00,0x00,
- 0x58,0x2A,0xDC,0xC8,0xDC,0x2A,0x58,0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00,0x00,
- 0x00,0x10,0x10,0x38,0x38,0x7C,0xFE,0x00,0xFE,0x7C,0x38,0x38,0x10,0x10,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x18,0x00,0x18,0x18,0x00,
- 0x6C,0x6C,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7C,0x28,0x7C,0x28,0x00,0x00,
- 0x10,0x38,0x60,0x38,0x0C,0x78,0x10,0x00,0x40,0xA4,0x48,0x10,0x24,0x4A,0x04,0x00,
- 0x18,0x34,0x18,0x3A,0x6C,0x66,0x3A,0x00,0x18,0x18,0x20,0x00,0x00,0x00,0x00,0x00,
- 0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x00,0x0C,0x06,0x06,0x06,0x06,0x06,0x0C,0x00,
- 0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x00,0x00,
- 0x38,0x4C,0xC6,0xC6,0xC6,0x64,0x38,0x00,0x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00,
- 0x7C,0xC6,0x0E,0x3C,0x78,0xE0,0xFE,0x00,0x7E,0x0C,0x18,0x3C,0x06,0xC6,0x7C,0x00,
- 0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x00,0xFC,0xC0,0xFC,0x06,0x06,0xC6,0x7C,0x00,
- 0x3C,0x60,0xC0,0xFC,0xC6,0xC6,0x7C,0x00,0xFE,0xC6,0x0C,0x18,0x30,0x30,0x30,0x00,
- 0x78,0xC4,0xE4,0x78,0x86,0x86,0x7C,0x00,0x7C,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
- 0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x18,0x30,
- 0x1C,0x38,0x70,0xE0,0x70,0x38,0x1C,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,
- 0x70,0x38,0x1C,0x0E,0x1C,0x38,0x70,0x00,0x7C,0xC6,0xC6,0x1C,0x18,0x00,0x18,0x00,
- 0x3C,0x42,0x99,0xA1,0xA5,0x99,0x42,0x3C,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x00,
- 0xFC,0xC6,0xC6,0xFC,0xC6,0xC6,0xFC,0x00,0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00,
- 0xF8,0xCC,0xC6,0xC6,0xC6,0xCC,0xF8,0x00,0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xFE,0x00,
- 0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xC0,0x00,0x3E,0x60,0xC0,0xCE,0xC6,0x66,0x3E,0x00,
- 0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,
- 0x06,0x06,0x06,0x06,0xC6,0xC6,0x7C,0x00,0xC6,0xCC,0xD8,0xF0,0xF8,0xDC,0xCE,0x00,
- 0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00,
- 0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
- 0xFC,0xC6,0xC6,0xC6,0xFC,0xC0,0xC0,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xCC,0x7A,0x00,
- 0xFC,0xC6,0xC6,0xCE,0xF8,0xDC,0xCE,0x00,0x78,0xCC,0xC0,0x7C,0x06,0xC6,0x7C,0x00,
- 0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
- 0xC6,0xC6,0xC6,0xEE,0x7C,0x38,0x10,0x00,0xC6,0xC6,0xD6,0xFE,0xFE,0xEE,0xC6,0x00,
- 0xC6,0xEE,0x3C,0x38,0x7C,0xEE,0xC6,0x00,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00,
- 0xFE,0x0E,0x1C,0x38,0x70,0xE0,0xFE,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,
- 0x60,0x60,0x30,0x18,0x0C,0x06,0x06,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,
- 0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
- 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x3C,0x00,
- 0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00,
- 0x06,0x3E,0x66,0x66,0x66,0x66,0x3E,0x00,0x00,0x3C,0x66,0x66,0x7E,0x60,0x3C,0x00,
- 0x1C,0x30,0x78,0x30,0x30,0x30,0x30,0x00,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x3C,
- 0x60,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x00,
- 0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x38,0x60,0x60,0x66,0x6C,0x78,0x6C,0x66,0x00,
- 0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0xEC,0xFE,0xFE,0xFE,0xD6,0xC6,0x00,
- 0x00,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00,
- 0x00,0x7C,0x66,0x66,0x66,0x7C,0x60,0x60,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x06,
- 0x00,0x7E,0x70,0x60,0x60,0x60,0x60,0x00,0x00,0x3C,0x60,0x3C,0x06,0x66,0x3C,0x00,
- 0x30,0x78,0x30,0x30,0x30,0x30,0x1C,0x00,0x00,0x66,0x66,0x66,0x66,0x6E,0x3E,0x00,
- 0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0xC6,0xD6,0xFE,0xFE,0x7C,0x6C,0x00,
- 0x00,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C,
- 0x00,0x7E,0x0C,0x18,0x30,0x60,0x7E,0x00,0x0E,0x18,0x0C,0x38,0x0C,0x18,0x0E,0x00,
- 0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x70,0x18,0x30,0x1C,0x30,0x18,0x70,0x00,
- 0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x10,0x28,0x10,0x54,0xAA,0x44,0x00,0x00,
-};
-
static void gp2x_text(unsigned char *screen, int x, int y, char *text, int color, int flip)
{
int i,l,slen;
int c=4;
while (c--)
{
- memset (gp2x_screen8, 0, 320*240);
+ memset(gp2x_screen, 0, 320*240);
gp2x_video_flip();
}
- XBuf = gp2x_screen8;
+ XBuf = gp2x_screen;
}
srendline=0;
erendline=239;
- XBuf = gp2x_screen8;
+ XBuf = gp2x_screen;
return 1;
}
void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
{
- gp2x_video_color8(index, r, g, b);
- gp2x_video_setpalette();
+ gp2x_palette[index] = (r << 16) | (g << 8) | b;
+ gp2x_video_setpalette(gp2x_palette, index + 1);
paletterefresh = 1;
}
void FCEUD_GetPalette(uint8 index, uint8 * r, uint8 * g, uint8 * b)
{
- *r = (uint8) gp2x_palette[(index << 1) + 1];
- *g = (uint8) (gp2x_palette[(index << 1) + 0] >> 8);
- *b = (uint8) gp2x_palette[(index << 1) + 0];
+ int pix = gp2x_palette[index];
+ *r = (uint8) (pix >> 16);
+ *g = (uint8) (pix >> 8);
+ *b = (uint8) pix;
}
framesRendered++;
- printFps(gp2x_screen8);
+ printFps(gp2x_screen);
gp2x_video_flip();
- XBuf = gp2x_screen8;
+ XBuf = gp2x_screen;
}
#include <stdlib.h>
#include <string.h>
+#include "../../driver.h"
+#include "../common/config.h"
+#include "../common/args.h"
#include "gp2x.h"
#include "gp2x-video.h"
#ifdef NETWORK
#include "unix-netplay.h"
#endif
+
#include "minimal.h"
+#include "cpuctrl.h"
+#include "squidgehack.h"
int CLImain(int argc, char *argv[]);
-extern void SetVideoScaling(int, int, int);
//#define SOUND_RATE 44100
#define SOUND_RATE 22050
-#define GP2X_PORT_VERSION "0.3"
+#define GP2X_PORT_VERSION "0.4"
DSETTINGS Settings;
CFGSTRUCT DriverConfig[]={
- AC(_xscale),
- AC(_yscale),
- AC(_xscalefs),
- AC(_yscalefs),
- AC(_efx),
- AC(_efxfs),
- AC(_sound),
- #ifdef DSPSOUND
- AC(_f8bit),
- #else
- AC(_ebufsize),
- AC(_lbufsize),
- #endif
- AC(_fullscreen),
- AC(_xres),
- AC(_yres),
- ACA(joyBMap),
- ACA(joyAMap),
- ACA(joy),
- //ACS(_fshack),
+ AC(Settings.sound),
+ ACA(Settings.joyBMap),
+ ACA(Settings.joyAMap),
+ ACA(Settings.joy),
+ AC(Settings.showfps),
+ AC(Settings.scaling),
+ AC(Settings.frameskip),
+ AC(Settings.sstate_confirm),
+ AC(Settings.region_force),
+ AC(Settings.cpuclock),
+ AC(Settings.mmuhack),
+ AC(Settings.ramtimings),
+ // TODO
ENDCFGSTRUCT
};
-//-fshack x Set the environment variable SDL_VIDEODRIVER to \"x\" when
-// entering full screen mode and x is not \"0\".
char *DriverUsage=
-"-xres x Set horizontal resolution to x for full screen mode.\n\
--yres x Set vertical resolution to x for full screen mode.\n\
--xscale(fs) x Multiply width by x.\n\
--yscale(fs) x Multiply height by x.\n\
--efx(fs) x Enable scanlines effect if x is non zero. yscale must be >=2\n\
- and preferably a multiple of 2.\n\
--fs x Select full screen mode if x is non zero.\n\
--joyx y Use joystick y as virtual joystick x.\n\
+"-joyx y Use joystick y as virtual joystick x.\n\
-sound x Sound.\n\
0 = Disabled.\n\
Otherwise, x = playback rate.\n\
+-showfps x Display fps counter if x is nonzero\n\
+-mmuhack x Enable squidge's MMU hack if x is nonzero (GP2X).\n\
+-ramtimings x Enable RAM overclocking if x is nonzero (GP2X).\n\
"
-#ifdef DSPSOUND
-"-f8bit x Force 8-bit sound.\n\
- 0 = Disabled.\n\
- 1 = Enabled.\n\
-"
-#else
-"-lbufsize x Internal FCE Ultra sound buffer size. Size = 2^x samples.\n\
--ebufsize x External SDL sound buffer size. Size = 2^x samples.\n\
-"
-#endif
+#ifdef NETWORK
"-connect s Connect to server 's' for TCP/IP network play.\n\
-server Be a host/server for TCP/IP network play.\n\
--netport x Use TCP/IP port x for network play.";
+-netport x Use TCP/IP port x for network play."
+#endif
+;
#ifdef NETWORK
static int docheckie[2]={0,0};
#endif
ARGPSTRUCT DriverArgs[]={
- {"-joy1",0,&joy[0],0},{"-joy2",0,&joy[1],0},
- {"-joy3",0,&joy[2],0},{"-joy4",0,&joy[3],0},
- {"-xscale",0,&_xscale,0},
- {"-yscale",0,&_yscale,0},
- {"-efx",0,&_efx,0},
- {"-xscalefs",0,&_xscalefs,0},
- {"-yscalefs",0,&_yscalefs,0},
- {"-efxfs",0,&_efxfs,0},
- {"-xres",0,&_xres,0},
- {"-yres",0,&_yres,0},
- {"-fs",0,&_fullscreen,0},
- //{"-fshack",0,&_fshack,0x4001},
- {"-sound",0,&_sound,0},
- #ifdef DSPSOUND
- {"-f8bit",0,&_f8bit,0},
- #else
- {"-lbufsize",0,&_lbufsize,0},
- {"-ebufsize",0,&_ebufsize,0},
- #endif
+ {"-joy1",0,&Settings.joy[0],0},{"-joy2",0,&Settings.joy[1],0},
+ {"-joy3",0,&Settings.joy[2],0},{"-joy4",0,&Settings.joy[3],0},
+ {"-sound",0,&Settings.sound,0},
+ {"-showfps",0,&Settings.showfps,0},
+ {"-mmuhack",0,&Settings.mmuhack,0},
+ {"-ramtimings",0,&Settings.ramtimings,0},
+ {"-menu",0,&ext_menu,0x4001},
+ {"-menustate",0,&ext_state,0x4001},
#ifdef NETWORK
{"-connect",&docheckie[0],&netplayhost,0x4001},
{"-server",&docheckie[1],0,0},
-
-
void GetBaseDirectory(char *BaseDirectory)
{
- char *ol;
-
- ol="/mnt/sd/roms/nes";
- BaseDirectory[0]=0;
- if(ol)
- {
- strncpy(BaseDirectory,ol,2047);
- BaseDirectory[2047]=0;
- strcat(BaseDirectory,"/fceultra");
- }
+ strcpy(BaseDirectory, "fceultra");
}
static void SetDefaults(void)
{
- _xres=320;
- _yres=240;
- _fullscreen=0;
- _sound=SOUND_RATE; // 48000 wrong
- #ifdef DSPSOUND
- _f8bit=0;
- #else
- _lbufsize=10;
- _ebufsize=8;
- #endif
- _xscale=_yscale=_xscalefs=_yscalefs=1;
- _efx=_efxfs=0;
- //_fshack=_fshacksave=0;
- memset(joy,0,sizeof(joy));
+ memset(&Settings,0,sizeof(Settings));
+ Settings.cpuclock = 150;
+ Settings.frameskip = -1; // auto
+ Settings.mmuhack = 1;
+ Settings.sound=SOUND_RATE;
}
void DoDriverArgs(void)
{
int x;
- #ifdef BROKEN
- if(_fshack)
- {
- if(_fshack[0]=='0')
- if(_fshack[1]==0)
- {
- free(_fshack);
- _fshack=0;
- }
- }
- #endif
-
#ifdef NETWORK
if(docheckie[0])
netplay=2;
#endif
for(x=0;x<4;x++)
- if(!joy[x])
+ if(!Settings.joy[x])
{
- memset(joyBMap[x],0,sizeof(joyBMap[0]));
- memset(joyAMap[x],0,sizeof(joyAMap[0]));
+ memset(Settings.joyBMap[x],0,sizeof(Settings.joyBMap[0]));
+ memset(Settings.joyAMap[x],0,sizeof(Settings.joyAMap[0]));
}
}
+
int InitMouse(void)
{
return(0);
}
+
void KillMouse(void){}
+
void GetMouseData(uint32 *d)
{
}
return NULL;
}
-#include "unix-basedir.h"
-extern int showfps;
-extern int swapbuttons;
+extern int swapbuttons; // TODO: rm
char **g_argv;
+
+// TODO: cleanup
int main(int argc, char *argv[])
{
+ int ret;
g_argv = argv;
puts("Starting GPFCE - Port version " GP2X_PORT_VERSION " (" __DATE__ ")");
puts("Ported by Zheng Zhu");
puts("Additional optimization/misc work by notaz\n");
- // stereo
- //gp2x_init (1000, 8, SOUND_RATE, 16, 1, 60);
-
- // mono 44khz
- //gp2x_init (1000, 8, SOUND_RATE<<1, 16, 0, 60);
- // mono 22khz
- gp2x_init (1000, 8, SOUND_RATE, 16, 0, 60);
+ gp2x_init();
+ cpuctrl_init();
// unscale the screen, in case this is bad.
- SetVideoScaling(320, 320, 240);
+ gp2x_video_changemode(8);
+ gp2x_video_RGB_setscaling(0, 320, 240);
SetDefaults();
- int ret=CLImain(argc,argv);
+
+ ret = CLImain(argc,argv);
// unscale the screen, in case this is bad.
- SetVideoScaling(320, 320, 240);
+ gp2x_video_RGB_setscaling(0, 320, 240);
+ cpuctrl_deinit();
gp2x_deinit();
- // make sure sound thread has exited cleanly
- printf("Exiting main(). terminated");
- if (showfps && swapbuttons)
- {
- execl("./selector","./selector","./gpfce_showfps_swapbuttons_config",NULL);
- }
- else if (showfps)
- {
- execl("./selector","./selector","./gpfce_showfps_config",NULL);
- }
- else if (swapbuttons)
- {
- execl("./selector","./selector","./gpfce_swapbuttons_config",NULL);
- }
- else
- {
- execl("./selector","./selector","./gpfce_config",NULL);
- }
+
return(ret?0:-1);
}
+
+int mmuhack_status = 0;
+
+/* optional GP2X stuff to be done after config is loaded */
+void gp2x_opt_setup(void)
+{
+ if (Settings.mmuhack) {
+ int ret = mmuhack();
+ printf("squidge hack code finished and returned %i\n", ret); fflush(stdout);
+ mmuhack_status = ret;
+ }
+ if (Settings.ramtimings) {
+ printf("setting RAM timings.. "); fflush(stdout);
+ // craigix: --trc 6 --tras 4 --twr 1 --tmrd 1 --trfc 1 --trp 2 --trcd 2
+ set_RAM_Timings(6, 4, 1, 1, 1, 2, 2);
+ printf("done.\n"); fflush(stdout);
+ }
+}
+
-#include "../../driver.h"
-#include "../common/args.h"
-#include "../common/config.h"
-#include "main.h"
-
typedef struct {
- int xres;
- int yres;
- int xscale,yscale;
- int xscalefs,yscalefs;
- int efx,efxfs;
- int fullscreen;
int sound;
- #ifdef DSPSOUND
- int f8bit;
- #else
- int lbufsize,ebufsize;
- #endif
int joy[4];
int joyAMap[4][2];
int joyBMap[4][4];
- char *fshack;
- char *fshacksave;
+ // gp2x specific
+ int showfps;
+ int scaling; // unscaled=0, hw_hor, hw_hor_vert, sw_hor
+ int frameskip; // -1 ~ auto, >=0 ~ count
+ int sstate_confirm;
+ int region_force; // 0 ~ off, 1 ~ PAL, 2 ~ NTSC
+ int cpuclock;
+ int mmuhack;
+ int ramtimings;
} DSETTINGS;
extern DSETTINGS Settings;
-#define _xres Settings.xres
-#define _yres Settings.yres
-#define _fullscreen Settings.fullscreen
-#define _sound Settings.sound
-#define _f8bit Settings.f8bit
-#define _xscale Settings.xscale
-#define _yscale Settings.yscale
-#define _xscalefs Settings.xscalefs
-#define _yscalefs Settings.yscalefs
-#define _efx Settings.efx
-#define _efxfs Settings.efxfs
-#define _ebufsize Settings.ebufsize
-#define _lbufsize Settings.lbufsize
-#define _fshack Settings.fshack
-#define _fshacksave Settings.fshacksave
+void gp2x_opt_setup(void);
-#define joyAMap Settings.joyAMap
-#define joyBMap Settings.joyBMap
-#define joy Settings.joy
#include "minimal.h"
+extern uint8 Exit; // exit emu loop
extern int swapbuttons;
extern int scaled_display;
extern int FSkip_setting;
-extern void SetVideoScaling(int pixels,int width,int height);
-
/* UsrInputType[] is user-specified. InputType[] is current
void FCEUD_UpdateInput(void)
{
long lastpad2=lastpad;
- unsigned long pad=gp2x_joystick_read();
+ unsigned long pad=gp2x_joystick_read(1); // TODO: USB joys and stuff
uint32 JS=0;
#define down(b) (pad & GP2X_##b)
//FCEUI_SetSoundVolume(soundvol);
setsoundvol(soundvol);
}
+ else if (down(VOL_DOWN) && down(VOL_UP))
+ {
+ Exit = 1;
+ }
if (shift)
{
if (scaled_display)
{
- SetVideoScaling(320, 256, 240);
+ gp2x_video_RGB_setscaling(0, 256, 240);
}
else
{
- SetVideoScaling(320, 320, 240);
+ gp2x_video_RGB_setscaling(0, 320, 240);
}
goto no_pad;
#include "main.h"
#include "throttle.h"
+#include "menu.h"
+#include "gp2x.h"
#include "../common/config.h"
#include "../common/args.h"
#include "../../fce.h"
#include "../../ines.h"
+// internals
+extern char lastLoadedGameName[2048];
+extern uint8 Exit; // exit emu loop flag
+void CloseGame(void);
+
+FCEUGI *fceugi = NULL;
static int ntsccol=0,ntschue=-1,ntsctint=-1;
int soundvol=70;
int inited=0;
int showfps=0;
int srendlinev[2]={0,0};
-//int srendlinev[2]={0,0};
int erendlinev[2]={239,239};
-//int erendlinev[2]={231,239};
int srendline,erendline;
AC(eoptions),
ACA(srendlinev),
ACA(erendlinev),
+ ACA(lastLoadedGameName),
ADDCFGSTRUCT(DriverConfig),
ENDCFGSTRUCT
};
exit(1);
}
-static void DoArgs(int argc, char *argv[])
+static int DoArgs(int argc, char *argv[])
{
static char *cortab[5]={"none","gamepad","zapper","powerpad","arkanoid"};
static int cortabi[5]={SI_NONE,SI_GAMEPAD,
static int fccortabi[5]={SIFC_NONE,SIFC_ARKANOID,SIFC_SHADOW,
SIFC_4PLAYER,SIFC_FKB};
- int x;
+ int x, ret;
static char *inputa[2]={0,0};
static char *fcexp=0;
static int docheckie[4];
};
memset(docheckie,0,sizeof(docheckie));
- ParseArguments(argc, argv, FCEUArgs);
+ ret=ParseArguments(argc, argv, FCEUArgs);
if(cpalette)
{
if(cpalette[0]=='0')
}
}
}
+ return ret;
}
#include "usage.h"
int CLImain(int argc, char *argv[])
{
- FCEUGI *tmp;
- int ret;
-
- if(argc<=1)
+ int last_arg_parsed;
+ /* TODO if(argc<=1)
{
ShowUsage(argv[0]);
return 1;
- }
+ }*/
if(!DriverInitialize())
{
return 1;
}
- if(!(ret=FCEUI_Initialize()))
+ if(!FCEUI_Initialize())
return(1);
GetBaseDirectory(BaseDirectory);
FCEUI_SetBaseDirectory(BaseDirectory);
+ lastLoadedGameName[0] = 0;
CreateDirs();
LoadConfig();
- DoArgs(argc-2,&argv[1]);
+ gp2x_opt_setup();
+ last_arg_parsed=DoArgs(argc-1,&argv[1]);
if(cpalette)
LoadCPalette();
if(InitSound())
inited|=1;
- if(!(tmp=FCEUI_LoadGame(argv[argc-1])))
- {
- ret=0;
- goto dk;
- }
- ParseGI(tmp);
- //RefreshThrottleFPS();
- InitOtherInput();
-
- // additional print for gpfce
+ if (argc > 1 && !last_arg_parsed)
{
- int MapperNo;
- iNES_HEADER *head = iNESGetHead();
- MapperNo = (head->ROM_type>>4);
- MapperNo|=(head->ROM_type2&0xF0);
- FCEU_DispMessage("%s, Mapper: %d%s%s", PAL?"PAL":"NTSC", MapperNo, (head->ROM_type&2)?", BB":"", (head->ROM_type&4)?", T":"");
+ strncpy(lastLoadedGameName, argv[argc-1], sizeof(lastLoadedGameName));
+ lastLoadedGameName[sizeof(lastLoadedGameName)-1] = 0;
+ Exit = 0;
+ }
+ else
+ {
+ lastLoadedGameName[0] = 0;
+ Exit = 1;
}
- FCEUI_Emulate();
+ while (1)
+ {
+ if(!Exit)
+ {
+ if (fceugi)
+ CloseGame();
+ fceugi=FCEUI_LoadGame(lastLoadedGameName);
+ if (fceugi)
+ {
+ ParseGI(fceugi);
+ //RefreshThrottleFPS();
+ InitOtherInput();
+
+ // additional print for gpfce
+ // TODO: handlers for other formats then iNES
+ {
+ int MapperNo;
+ iNES_HEADER *head = iNESGetHead();
+ MapperNo = (head->ROM_type>>4);
+ MapperNo|=(head->ROM_type2&0xF0);
+ FCEU_DispMessage("%s, Mapper: %d%s%s", PAL?"PAL":"NTSC", MapperNo, (head->ROM_type&2)?", BB":"", (head->ROM_type&4)?", T":"");
+ }
+ }
+ else
+ strcpy(menuErrorMsg, "failed to load ROM");
+ }
+ if(Exit || !fceugi)
+ {
+ int ret;
+ ret = gp2x_menu_do();
+ if (ret == 1) break; // exit emu
+ if (ret == 2) { // reload ROM
+ Exit = 0;
+ continue;
+ }
+ }
+
+ gp2x_video_changemode(Settings.scaling == 3 ? 15 : 8);
+ gp2x_video_RGB_setscaling(0, 320, 240);
+ gp2x_start_sound(22050, 16, 0);
+ FCEUI_Emulate();
+ }
- dk:
DriverKill();
- return(ret?0:1);
+ return 0;
}
static int DriverInitialize(void)
#define EO_NOTHROTTLE 64
extern int srendline,erendline,srendlinev[2],erendlinev[2];
extern int NoWaiting;
+
+extern FCEUGI *fceugi;
--- /dev/null
+// (c) Copyright 2006,2007 notaz, All rights reserved.\r
+// Free for non-commercial use.\r
+\r
+// For commercial use, separate licencing terms must be obtained.\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <unistd.h>\r
+#include <dirent.h>\r
+\r
+#include "minimal.h"\r
+#include "usbjoy.h"\r
+#include "asmutils.h"\r
+#include "menu.h"\r
+#include "main.h"\r
+#include "fonts.h"\r
+#include "gp2x.h"\r
+\r
+#ifndef _DIRENT_HAVE_D_TYPE\r
+#error "need d_type for file browser\r
+#endif\r
+\r
+extern char lastLoadedGameName[PATH_MAX];\r
+extern int mmuhack_status;\r
+//extern int state_slot; // TODO\r
+extern uint8 Exit; // exit emu loop flag\r
+\r
+static char *gp2xKeyNames[] = {\r
+ "UP", "01???", "LEFT", "03???", "DOWN", "05???", "RIGHT", "07???",\r
+ "START", "SELECT", "L", "R", "A", "B", "X", "Y",\r
+ "10???", "11???", "12???","13???", "14???","15???", "VOL DOWN", "VOL UP",\r
+ "18???", "19???", "1a???","PUSH", "1c???","1d???", "1e???", "1f???"\r
+};\r
+\r
+char menuErrorMsg[40] = {0, };\r
+\r
+// TODO\r
+void gp2x_fceu_copy_bg(void)\r
+{\r
+ memset(gp2x_screen, 0, 320*240*2);\r
+}\r
+\r
+// draws white text to current bbp15 screen\r
+static void gp2x_text_out15_(int x, int y, const char *text)\r
+{\r
+ int i,l;\r
+ unsigned short *screen = gp2x_screen;\r
+\r
+ screen = screen + x + y*320;\r
+\r
+ for (i = 0; i < strlen(text); i++)\r
+ {\r
+ for (l=0;l<8;l++)\r
+ {\r
+ if(fontdata8x8[((text[i])*8)+l]&0x80) screen[l*320+0]=0xffff;\r
+ if(fontdata8x8[((text[i])*8)+l]&0x40) screen[l*320+1]=0xffff;\r
+ if(fontdata8x8[((text[i])*8)+l]&0x20) screen[l*320+2]=0xffff;\r
+ if(fontdata8x8[((text[i])*8)+l]&0x10) screen[l*320+3]=0xffff;\r
+ if(fontdata8x8[((text[i])*8)+l]&0x08) screen[l*320+4]=0xffff;\r
+ if(fontdata8x8[((text[i])*8)+l]&0x04) screen[l*320+5]=0xffff;\r
+ if(fontdata8x8[((text[i])*8)+l]&0x02) screen[l*320+6]=0xffff;\r
+ if(fontdata8x8[((text[i])*8)+l]&0x01) screen[l*320+7]=0xffff;\r
+ }\r
+ screen += 8;\r
+ }\r
+}\r
+\r
+void gp2x_text_out15(int x, int y, const char *texto, ...)\r
+{\r
+ va_list args;\r
+ char buffer[512];\r
+\r
+ va_start(args,texto);\r
+ vsprintf(buffer,texto,args);\r
+ va_end(args);\r
+\r
+ gp2x_text_out15_(x,y,buffer);\r
+}\r
+\r
+\r
+void gp2x_text_out15_lim(int x, int y, const char *texto, int max)\r
+{\r
+ char buffer[320/8+1];\r
+\r
+ strncpy(buffer, texto, 320/8);\r
+ if (max > 320/8) max = 320/8;\r
+ if (max < 0) max = 0;\r
+ buffer[max] = 0;\r
+\r
+ gp2x_text_out15(x,y,buffer);\r
+}\r
+\r
+static void gp2x_smalltext16(int x, int y, const char *texto)\r
+{\r
+ int i;\r
+ unsigned char *src;\r
+ unsigned short *dst;\r
+\r
+ for (i = 0;; i++, x += 6)\r
+ {\r
+ unsigned char c = (unsigned char) texto[i];\r
+ int h = 8;\r
+\r
+ if (!c) break;\r
+\r
+ src = fontdata6x8[c];\r
+ dst = (unsigned short *)gp2x_screen + x + y*320;\r
+\r
+ while (h--)\r
+ {\r
+ int w = 0x20;\r
+ while (w)\r
+ {\r
+ if( *src & w ) *dst = 0xffff;\r
+ dst++;\r
+ w>>=1;\r
+ }\r
+ src++;\r
+\r
+ dst += 320-6;\r
+ }\r
+ }\r
+}\r
+\r
+static void gp2x_smalltext8_lim(int x, int y, const char *texto, int max)\r
+{\r
+ char buffer[320/6+1];\r
+\r
+ strncpy(buffer, texto, 320/6);\r
+ if (max > 320/6) max = 320/6;\r
+ if (max < 0) max = 0;\r
+ buffer[max] = 0;\r
+\r
+ gp2x_smalltext16(x, y, buffer);\r
+}\r
+\r
+\r
+static unsigned long inp_prev = 0;\r
+static int inp_prevjoy = 0;\r
+\r
+static unsigned long wait_for_input(unsigned long interesting)\r
+{\r
+ unsigned long ret;\r
+ static int repeats = 0, wait = 50*1000;\r
+ int release = 0, i;\r
+\r
+ if (repeats == 2 || repeats == 4) wait /= 2;\r
+ if (repeats == 6) wait = 15 * 1000;\r
+\r
+ for (i = 0; i < 6 && inp_prev == gp2x_joystick_read(1); i++) {\r
+ if (i == 0) repeats++;\r
+ if (wait >= 30*1000) usleep(wait); // usleep sleeps for ~30ms minimum\r
+ else spend_cycles(wait * Settings.cpuclock);\r
+ }\r
+\r
+ while ( !((ret = gp2x_joystick_read(1)) & interesting) ) {\r
+ usleep(50000);\r
+ release = 1;\r
+ }\r
+\r
+ if (release || ret != inp_prev) {\r
+ repeats = 0;\r
+ wait = 50*1000;\r
+ }\r
+ inp_prev = ret;\r
+ inp_prevjoy = 0;\r
+\r
+ // we don't need diagonals in menus\r
+ if ((ret&GP2X_UP) && (ret&GP2X_LEFT)) ret &= ~GP2X_LEFT;\r
+ if ((ret&GP2X_UP) && (ret&GP2X_RIGHT)) ret &= ~GP2X_RIGHT;\r
+ if ((ret&GP2X_DOWN) && (ret&GP2X_LEFT)) ret &= ~GP2X_LEFT;\r
+ if ((ret&GP2X_DOWN) && (ret&GP2X_RIGHT)) ret &= ~GP2X_RIGHT;\r
+\r
+ return ret;\r
+}\r
+\r
+static unsigned long input2_read(unsigned long interesting, int *joy)\r
+{\r
+ unsigned long ret;\r
+ int i;\r
+\r
+ do\r
+ {\r
+ *joy = 0;\r
+ if ((ret = gp2x_joystick_read(0) & interesting)) break;\r
+ gp2x_usbjoy_update();\r
+ for (i = 0; i < num_of_joys; i++) {\r
+ ret = gp2x_usbjoy_check2(i);\r
+ if (ret) { *joy = i + 1; break; }\r
+ }\r
+ if (ret) break;\r
+ }\r
+ while(0);\r
+\r
+ return ret;\r
+}\r
+\r
+// similar to wait_for_input(), but returns joy num\r
+static unsigned long wait_for_input_usbjoy(unsigned long interesting, int *joy)\r
+{\r
+ unsigned long ret;\r
+ const int wait = 300*1000;\r
+ int i;\r
+\r
+ if (inp_prevjoy == 0) inp_prev &= interesting;\r
+ for (i = 0; i < 6; i++) {\r
+ ret = input2_read(interesting, joy);\r
+ if (*joy != inp_prevjoy || ret != inp_prev) break;\r
+ usleep(wait/6);\r
+ }\r
+\r
+ while ( !(ret = input2_read(interesting, joy)) ) {\r
+ usleep(50000);\r
+ }\r
+\r
+ inp_prev = ret;\r
+ inp_prevjoy = *joy;\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+\r
+// -------------- ROM selector --------------\r
+\r
+static void draw_dirlist(char *curdir, struct dirent **namelist, int n, int sel)\r
+{\r
+ int start, i, pos;\r
+\r
+ start = 12 - sel;\r
+ n--; // exclude current dir (".")\r
+\r
+ //memset(gp2x_screen, 0, 320*240);\r
+ gp2x_fceu_copy_bg();\r
+\r
+ if(start - 2 >= 0)\r
+ gp2x_smalltext8_lim(14, (start - 2)*10, curdir, 53-2);\r
+ for (i = 0; i < n; i++) {\r
+ pos = start + i;\r
+ if (pos < 0) continue;\r
+ if (pos > 23) break;\r
+ if (namelist[i+1]->d_type == DT_DIR) {\r
+ gp2x_smalltext8_lim(14, pos*10, "/", 1);\r
+ gp2x_smalltext8_lim(14+6, pos*10, namelist[i+1]->d_name, 53-3);\r
+ } else {\r
+ gp2x_smalltext8_lim(14, pos*10, namelist[i+1]->d_name, 53-2);\r
+ }\r
+ }\r
+ gp2x_text_out15(5, 120, ">");\r
+ gp2x_video_flip();\r
+}\r
+\r
+static int scandir_cmp(const void *p1, const void *p2)\r
+{\r
+ struct dirent **d1 = (struct dirent **)p1, **d2 = (struct dirent **)p2;\r
+ if ((*d1)->d_type == (*d2)->d_type) return alphasort(d1, d2);\r
+ if ((*d1)->d_type == DT_DIR) return -1; // put before\r
+ if ((*d2)->d_type == DT_DIR) return 1;\r
+ return alphasort(d1, d2);\r
+}\r
+\r
+static char *filter_exts[] = {\r
+ // TODO\r
+ ".mp3", ".MP3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html",\r
+ ".jpg", ".gpe", ".cue"\r
+};\r
+\r
+static int scandir_filter(const struct dirent *ent)\r
+{\r
+ const char *p;\r
+ int i;\r
+\r
+ if (ent == NULL || ent->d_name == NULL) return 0;\r
+ if (strlen(ent->d_name) < 5) return 1;\r
+\r
+ p = ent->d_name + strlen(ent->d_name) - 4;\r
+\r
+ for (i = 0; i < sizeof(filter_exts)/sizeof(filter_exts[0]); i++)\r
+ {\r
+ if (strcmp(p, filter_exts[i]) == 0) return 0;\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r
+static char *romsel_loop(char *curr_path)\r
+{\r
+ struct dirent **namelist;\r
+ DIR *dir;\r
+ int n, sel = 0;\r
+ unsigned long inp = 0;\r
+ char *ret = NULL, *fname = NULL;\r
+\r
+ // is this a dir or a full path?\r
+ if ((dir = opendir(curr_path))) {\r
+ closedir(dir);\r
+ } else {\r
+ char *p;\r
+ for (p = curr_path + strlen(curr_path) - 1; p > curr_path && *p != '/'; p--);\r
+ *p = 0;\r
+ fname = p+1;\r
+ }\r
+\r
+ n = scandir(curr_path, &namelist, scandir_filter, scandir_cmp);\r
+ if (n < 0) {\r
+ // try root\r
+ n = scandir("/", &namelist, scandir_filter, scandir_cmp);\r
+ if (n < 0) {\r
+ // oops, we failed\r
+ printf("dir: %s\n", curr_path);\r
+ perror("scandir");\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ // try to find sel\r
+ if (fname != NULL) {\r
+ int i;\r
+ for (i = 1; i < n; i++) {\r
+ if (strcmp(namelist[i]->d_name, fname) == 0) {\r
+ sel = i - 1;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ for (;;)\r
+ {\r
+ draw_dirlist(curr_path, namelist, n, sel);\r
+ inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_LEFT|GP2X_RIGHT|GP2X_L|GP2X_R|GP2X_B|GP2X_X);\r
+ if(inp & GP2X_UP ) { sel--; if (sel < 0) sel = n-2; }\r
+ if(inp & GP2X_DOWN) { sel++; if (sel > n-2) sel = 0; }\r
+ if(inp & GP2X_LEFT) { sel-=10; if (sel < 0) sel = 0; }\r
+ if(inp & GP2X_L) { sel-=24; if (sel < 0) sel = 0; }\r
+ if(inp & GP2X_RIGHT) { sel+=10; if (sel > n-2) sel = n-2; }\r
+ if(inp & GP2X_R) { sel+=24; if (sel > n-2) sel = n-2; }\r
+ if(inp & GP2X_B) { // enter dir/select\r
+ again:\r
+ if (namelist[sel+1]->d_type == DT_REG) {\r
+ strcpy(lastLoadedGameName, curr_path);\r
+ strcat(lastLoadedGameName, "/");\r
+ strcat(lastLoadedGameName, namelist[sel+1]->d_name);\r
+ ret = lastLoadedGameName;\r
+ break;\r
+ } else if (namelist[sel+1]->d_type == DT_DIR) {\r
+ int newlen = strlen(curr_path) + strlen(namelist[sel+1]->d_name) + 2;\r
+ char *p, *newdir = malloc(newlen);\r
+ if (strcmp(namelist[sel+1]->d_name, "..") == 0) {\r
+ char *start = curr_path;\r
+ p = start + strlen(start) - 1;\r
+ while (*p == '/' && p > start) p--;\r
+ while (*p != '/' && p > start) p--;\r
+ if (p <= start) strcpy(newdir, "/");\r
+ else { strncpy(newdir, start, p-start); newdir[p-start] = 0; }\r
+ } else {\r
+ strcpy(newdir, curr_path);\r
+ p = newdir + strlen(newdir) - 1;\r
+ while (*p == '/' && p >= newdir) *p-- = 0;\r
+ strcat(newdir, "/");\r
+ strcat(newdir, namelist[sel+1]->d_name);\r
+ }\r
+ ret = romsel_loop(newdir);\r
+ free(newdir);\r
+ break;\r
+ } else {\r
+ // unknown file type, happens on NTFS mounts. Try to guess.\r
+ FILE *tstf; int tmp;\r
+ strcpy(lastLoadedGameName, curr_path);\r
+ strcat(lastLoadedGameName, "/");\r
+ strcat(lastLoadedGameName, namelist[sel+1]->d_name);\r
+ tstf = fopen(lastLoadedGameName, "rb");\r
+ if (tstf != NULL)\r
+ {\r
+ if (fread(&tmp, 1, 1, tstf) > 0 || ferror(tstf) == 0)\r
+ namelist[sel+1]->d_type = DT_REG;\r
+ else namelist[sel+1]->d_type = DT_DIR;\r
+ fclose(tstf);\r
+ goto again;\r
+ }\r
+ }\r
+ }\r
+ if(inp & GP2X_X) break; // cancel\r
+ }\r
+\r
+ if (n > 0) {\r
+ while(n--) free(namelist[n]);\r
+ free(namelist);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+// ------------ patch/gg menu ------------\r
+\r
+#if 0 // TODO?\r
+static void draw_patchlist(int sel)\r
+{\r
+ int start, i, pos;\r
+\r
+ start = 12 - sel;\r
+\r
+ gp2x_fceu_copy_bg();\r
+\r
+ for (i = 0; i < PicoPatchCount; i++) {\r
+ pos = start + i;\r
+ if (pos < 0) continue;\r
+ if (pos > 23) break;\r
+ gp2x_smalltext8_lim(14, pos*10, PicoPatches[i].active ? "ON " : "OFF", 3);\r
+ gp2x_smalltext8_lim(14+6*4, pos*10, PicoPatches[i].name, 53-6);\r
+ }\r
+ pos = start + i;\r
+ if (pos < 24) gp2x_smalltext8_lim(14, pos*10, "done", 4);\r
+\r
+ gp2x_text_out15(5, 120, ">");\r
+ gp2x_video_flip();\r
+}\r
+\r
+\r
+void patches_menu_loop(void)\r
+{\r
+ int menu_sel = 0;\r
+ unsigned long inp = 0;\r
+\r
+ for(;;)\r
+ {\r
+ draw_patchlist(menu_sel);\r
+ inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_LEFT|GP2X_RIGHT|GP2X_L|GP2X_R|GP2X_B|GP2X_X);\r
+ if(inp & GP2X_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = PicoPatchCount; }\r
+ if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > PicoPatchCount) menu_sel = 0; }\r
+ if(inp &(GP2X_LEFT|GP2X_L)) { menu_sel-=10; if (menu_sel < 0) menu_sel = 0; }\r
+ if(inp &(GP2X_RIGHT|GP2X_R)) { menu_sel+=10; if (menu_sel > PicoPatchCount) menu_sel = PicoPatchCount; }\r
+ if(inp & GP2X_B) { // action\r
+ if (menu_sel < PicoPatchCount)\r
+ PicoPatches[menu_sel].active = !PicoPatches[menu_sel].active;\r
+ else return;\r
+ }\r
+ if(inp & GP2X_X) return;\r
+ }\r
+\r
+}\r
+\r
+// ------------ savestate loader ------------\r
+\r
+static void menu_prepare_bg(void);\r
+\r
+static int state_slot_flags = 0;\r
+\r
+static void state_check_slots(void)\r
+{\r
+ int slot;\r
+\r
+ state_slot_flags = 0;\r
+\r
+ for (slot = 0; slot < 10; slot++)\r
+ {\r
+ if (emu_check_save_file(slot))\r
+ {\r
+ state_slot_flags |= 1 << slot;\r
+ }\r
+ }\r
+}\r
+\r
+static void draw_savestate_bg(int slot)\r
+{\r
+ struct PicoVideo tmp_pv;\r
+ unsigned short tmp_cram[0x40];\r
+ unsigned short tmp_vsram[0x40];\r
+ void *tmp_vram, *file;\r
+ char *fname;\r
+\r
+ fname = emu_GetSaveFName(1, 0, slot);\r
+ if (!fname) return;\r
+\r
+ tmp_vram = malloc(sizeof(Pico.vram));\r
+ if (tmp_vram == NULL) return;\r
+\r
+ memcpy(tmp_vram, Pico.vram, sizeof(Pico.vram));\r
+ memcpy(tmp_cram, Pico.cram, sizeof(Pico.cram));\r
+ memcpy(tmp_vsram, Pico.vsram, sizeof(Pico.vsram));\r
+ memcpy(&tmp_pv, &Pico.video, sizeof(Pico.video));\r
+\r
+ if (strcmp(fname + strlen(fname) - 3, ".gz") == 0) {\r
+ file = gzopen(fname, "rb");\r
+ emu_set_save_cbs(1);\r
+ } else {\r
+ file = fopen(fname, "rb");\r
+ emu_set_save_cbs(0);\r
+ }\r
+\r
+ if (file) {\r
+ if (PicoMCD & 1) {\r
+ PicoCdLoadStateGfx(file);\r
+ } else {\r
+ areaSeek(file, 0x10020, SEEK_SET); // skip header and RAM in state file\r
+ areaRead(Pico.vram, 1, sizeof(Pico.vram), file);\r
+ areaSeek(file, 0x2000, SEEK_CUR);\r
+ areaRead(Pico.cram, 1, sizeof(Pico.cram), file);\r
+ areaRead(Pico.vsram, 1, sizeof(Pico.vsram), file);\r
+ areaSeek(file, 0x221a0, SEEK_SET);\r
+ areaRead(&Pico.video, 1, sizeof(Pico.video), file);\r
+ }\r
+ areaClose(file);\r
+ }\r
+\r
+ emu_forced_frame();\r
+ gp2x_memcpy_buffers((1<<2), gp2x_screen, 0, 320*240*2);\r
+ menu_prepare_bg();\r
+\r
+ memcpy(Pico.vram, tmp_vram, sizeof(Pico.vram));\r
+ memcpy(Pico.cram, tmp_cram, sizeof(Pico.cram));\r
+ memcpy(Pico.vsram, tmp_vsram, sizeof(Pico.vsram));\r
+ memcpy(&Pico.video, &tmp_pv, sizeof(Pico.video));\r
+ free(tmp_vram);\r
+}\r
+\r
+static void draw_savestate_menu(int menu_sel, int is_loading)\r
+{\r
+ int tl_x = 25, tl_y = 60, y, i;\r
+\r
+ if (state_slot_flags & (1 << menu_sel))\r
+ draw_savestate_bg(menu_sel);\r
+ gp2x_fceu_copy_bg();\r
+\r
+ gp2x_text_out15(tl_x, 30, is_loading ? "Load state" : "Save state");\r
+\r
+ /* draw all 10 slots */\r
+ y = tl_y;\r
+ for (i = 0; i < 10; i++, y+=10)\r
+ {\r
+ gp2x_text_out15(tl_x, y, "SLOT %i (%s)", i, (state_slot_flags & (1 << i)) ? "USED" : "free");\r
+ }\r
+ gp2x_text_out15(tl_x, y, "back");\r
+\r
+ // draw cursor\r
+ gp2x_text_out15(tl_x - 16, tl_y + menu_sel*10, ">");\r
+\r
+ gp2x_video_flip();\r
+}\r
+\r
+static int savestate_menu_loop(int is_loading)\r
+{\r
+ int menu_sel = 10, menu_sel_max = 10;\r
+ unsigned long inp = 0;\r
+\r
+ state_check_slots();\r
+\r
+ for(;;)\r
+ {\r
+ draw_savestate_menu(menu_sel, is_loading);\r
+ inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_B|GP2X_X);\r
+ if(inp & GP2X_UP ) {\r
+ do {\r
+ menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max;\r
+ } while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);\r
+ }\r
+ if(inp & GP2X_DOWN) {\r
+ do {\r
+ menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0;\r
+ } while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);\r
+ }\r
+ if(inp & GP2X_B) { // save/load\r
+ if (menu_sel < 10) {\r
+ state_slot = menu_sel;\r
+ if (emu_SaveLoadGame(is_loading, 0)) {\r
+ strcpy(menuErrorMsg, is_loading ? "Load failed" : "Save failed");\r
+ return 1;\r
+ }\r
+ return 0;\r
+ } else return 1;\r
+ }\r
+ if(inp & GP2X_X) return 1;\r
+ }\r
+}\r
+\r
+// -------------- key config --------------\r
+\r
+static char *usb_joy_key_name(int joy, int num)\r
+{\r
+ static char name[16];\r
+ switch (num)\r
+ {\r
+ case 0: sprintf(name, "Joy%i UP", joy); break;\r
+ case 1: sprintf(name, "Joy%i DOWN", joy); break;\r
+ case 2: sprintf(name, "Joy%i LEFT", joy); break;\r
+ case 3: sprintf(name, "Joy%i RIGHT", joy); break;\r
+ default:sprintf(name, "Joy%i b%i", joy, num-3); break;\r
+ }\r
+ return name;\r
+}\r
+\r
+static void draw_key_config(int curr_act, int is_p2)\r
+{\r
+ char strkeys[32*5];\r
+ int joy, i;\r
+\r
+ strkeys[0] = 0;\r
+ for (i = 0; i < 32; i++)\r
+ {\r
+ if (currentConfig.KeyBinds[i] & (1 << curr_act))\r
+ {\r
+ if (curr_act < 16 && (currentConfig.KeyBinds[i] & (1 << 16)) != (is_p2 << 16)) continue;\r
+ if (strkeys[0]) { strcat(strkeys, " + "); strcat(strkeys, gp2xKeyNames[i]); break; }\r
+ else strcpy(strkeys, gp2xKeyNames[i]);\r
+ }\r
+ }\r
+ for (joy = 0; joy < num_of_joys; joy++)\r
+ {\r
+ for (i = 0; i < 32; i++)\r
+ {\r
+ if (currentConfig.JoyBinds[joy][i] & (1 << curr_act))\r
+ {\r
+ if (curr_act < 16 && (currentConfig.JoyBinds[joy][i] & (1 << 16)) != (is_p2 << 16)) continue;\r
+ if (strkeys[0]) {\r
+ strcat(strkeys, ", "); strcat(strkeys, usb_joy_key_name(joy + 1, i));\r
+ break;\r
+ }\r
+ else strcpy(strkeys, usb_joy_key_name(joy + 1, i));\r
+ }\r
+ }\r
+ }\r
+\r
+ //memset(gp2x_screen, 0, 320*240);\r
+ gp2x_fceu_copy_bg();\r
+ gp2x_text_out15(60, 40, "Action: %s", actionNames[curr_act]);\r
+ gp2x_text_out15(60, 60, "Keys: %s", strkeys);\r
+\r
+ gp2x_text_out15(30, 180, "Use SELECT to change action");\r
+ gp2x_text_out15(30, 190, "Press a key to bind/unbind");\r
+ gp2x_text_out15(30, 200, "Select \"Done\" action and");\r
+ gp2x_text_out15(30, 210, " press any key to finish");\r
+ gp2x_video_flip();\r
+}\r
+\r
+static void key_config_loop(int is_p2)\r
+{\r
+ int curr_act = 0, joy = 0, i;\r
+ unsigned long inp = 0;\r
+\r
+ for (;;)\r
+ {\r
+ draw_key_config(curr_act, is_p2);\r
+ inp = wait_for_input_usbjoy(CONFIGURABLE_KEYS, &joy);\r
+ // printf("got %08lX from joy %i\n", inp, joy);\r
+ if (joy == 0) {\r
+ if (inp & GP2X_SELECT) {\r
+ curr_act++;\r
+ while (!actionNames[curr_act] && curr_act < 32) curr_act++;\r
+ if (curr_act > 31) curr_act = 0;\r
+ }\r
+ inp &= CONFIGURABLE_KEYS;\r
+ inp &= ~GP2X_SELECT;\r
+ }\r
+ if (curr_act == 31 && inp) break;\r
+ if (joy == 0) {\r
+ for (i = 0; i < 32; i++)\r
+ if (inp & (1 << i)) {\r
+ currentConfig.KeyBinds[i] ^= (1 << curr_act);\r
+ if (is_p2) currentConfig.KeyBinds[i] |= (1 << 16); // player 2 flag\r
+ else currentConfig.KeyBinds[i] &= ~(1 << 16);\r
+ }\r
+ } else {\r
+ for (i = 0; i < 32; i++)\r
+ if (inp & (1 << i)) {\r
+ currentConfig.JoyBinds[joy-1][i] ^= (1 << curr_act);\r
+ if (is_p2) currentConfig.JoyBinds[joy-1][i] |= (1 << 16);\r
+ else currentConfig.JoyBinds[joy-1][i] &= ~(1 << 16);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+static void draw_kc_sel(int menu_sel)\r
+{\r
+ int tl_x = 25+40, tl_y = 60, y, i;\r
+ char joyname[36];\r
+\r
+ y = tl_y;\r
+ //memset(gp2x_screen, 0, 320*240);\r
+ gp2x_fceu_copy_bg();\r
+ gp2x_text_out15(tl_x, y, "Player 1");\r
+ gp2x_text_out15(tl_x, (y+=10), "Player 2");\r
+ gp2x_text_out15(tl_x, (y+=10), "Done");\r
+\r
+ // draw cursor\r
+ gp2x_text_out15(tl_x - 16, tl_y + menu_sel*10, ">");\r
+\r
+ tl_x = 25;\r
+ gp2x_text_out15(tl_x, (y=110), "USB joys detected:");\r
+ if (num_of_joys > 0) {\r
+ for (i = 0; i < num_of_joys; i++) {\r
+ strncpy(joyname, joy_name(joys[i]), 33); joyname[33] = 0;\r
+ gp2x_text_out15(tl_x, (y+=10), "%i: %s", i+1, joyname);\r
+ }\r
+ } else {\r
+ gp2x_text_out15(tl_x, (y+=10), "none");\r
+ }\r
+\r
+\r
+ gp2x_video_flip();\r
+}\r
+\r
+static void kc_sel_loop(void)\r
+{\r
+ int menu_sel = 2, menu_sel_max = 2;\r
+ unsigned long inp = 0;\r
+\r
+ for(;;)\r
+ {\r
+ draw_kc_sel(menu_sel);\r
+ inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_B|GP2X_X);\r
+ if(inp & GP2X_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }\r
+ if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }\r
+ if(inp & GP2X_B) {\r
+ switch (menu_sel) {\r
+ case 0: key_config_loop(0); return;\r
+ case 1: key_config_loop(1); return;\r
+ default: return;\r
+ }\r
+ }\r
+ if(inp & GP2X_X) return;\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+\r
+// --------- advanced options ----------\r
+#if 0\r
+static void draw_amenu_options(int menu_sel)\r
+{\r
+ int tl_x = 25, tl_y = 60, y;\r
+ char *mms = mmuhack_status ? "active) " : "inactive)";\r
+\r
+ y = tl_y;\r
+ //memset(gp2x_screen, 0, 320*240);\r
+ gp2x_fceu_copy_bg();\r
+\r
+ gp2x_text_out15(tl_x, y, "Gamma correction %i.%02i", currentConfig.gamma / 100, currentConfig.gamma%100); // 0\r
+ gp2x_text_out15(tl_x, (y+=10), "Don't save last used ROM %s", (currentConfig.EmuOpt &0x020)?"ON":"OFF"); // 5\r
+ gp2x_text_out15(tl_x, (y+=10), "needs restart:");\r
+ gp2x_text_out15(tl_x, (y+=10), "craigix's RAM timings %s", (currentConfig.EmuOpt &0x100)?"ON":"OFF"); // 7\r
+ gp2x_text_out15(tl_x, (y+=10), "squidgehack (now %s %s", mms, (currentConfig.EmuOpt &0x010)?"ON":"OFF"); // 8\r
+ gp2x_text_out15(tl_x, (y+=10), "Done");\r
+\r
+ // draw cursor\r
+ gp2x_text_out15(tl_x - 16, tl_y + menu_sel*10, ">");\r
+\r
+ gp2x_video_flip();\r
+}\r
+\r
+static void amenu_loop_options(void)\r
+{\r
+ int menu_sel = 0, menu_sel_max = 9;\r
+ unsigned long inp = 0;\r
+\r
+ for(;;)\r
+ {\r
+ draw_amenu_options(menu_sel);\r
+ inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_LEFT|GP2X_RIGHT|GP2X_B|GP2X_X|GP2X_A);\r
+ if(inp & GP2X_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }\r
+ if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }\r
+ if((inp& GP2X_B)||(inp&GP2X_LEFT)||(inp&GP2X_RIGHT)) { // toggleable options\r
+ switch (menu_sel) {\r
+ case 1: break;\r
+ case 9: return;\r
+ }\r
+ }\r
+ if(inp & (GP2X_X|GP2X_A)) return;\r
+ if(inp & (GP2X_LEFT|GP2X_RIGHT)) { // multi choise\r
+ switch (menu_sel) {\r
+ case 0:\r
+ while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) {\r
+ currentConfig.gamma += (inp & GP2X_LEFT) ? -1 : 1;\r
+ if (currentConfig.gamma < 1) currentConfig.gamma = 1;\r
+ if (currentConfig.gamma > 300) currentConfig.gamma = 300;\r
+ draw_amenu_options(menu_sel);\r
+ usleep(18*1000);\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+}\r
+#endif\r
+\r
+// -------------- options --------------\r
+\r
+static void draw_menu_options(int menu_sel)\r
+{\r
+ int tl_x = 25, tl_y = 32, y;\r
+ char monostereo[8], strframeskip[8], *strscaling, *strssconfirm;\r
+\r
+ //strcpy(monostereo, (currentConfig.PicoOpt&0x08)?"stereo":"mono");\r
+ if (Settings.frameskip < 0)\r
+ strcpy(strframeskip, "Auto");\r
+ else sprintf(strframeskip, "%i", Settings.frameskip);\r
+ switch (Settings.scaling) {\r
+ default: strscaling = " OFF"; break;\r
+ case 1: strscaling = "hw horizontal"; break;\r
+ case 2: strscaling = "hw horiz. + vert."; break;\r
+ case 3: strscaling = "sw horizontal"; break;\r
+ }\r
+ switch (Settings.sstate_confirm) {\r
+ default: strssconfirm = "OFF"; break;\r
+ case 1: strssconfirm = "writes"; break;\r
+ case 2: strssconfirm = "loads"; break;\r
+ case 3: strssconfirm = "both"; break;\r
+ }\r
+\r
+ y = tl_y;\r
+ //memset(gp2x_screen, 0, 320*240);\r
+ gp2x_fceu_copy_bg();\r
+\r
+ gp2x_text_out15(tl_x, (y+=10), "Scaling: %s", strscaling); // 0\r
+ gp2x_text_out15(tl_x, (y+=10), "Show FPS %s", Settings.showfps?"ON":"OFF"); // 1\r
+ gp2x_text_out15(tl_x, (y+=10), "Frameskip %s", strframeskip); // 2\r
+ gp2x_text_out15(tl_x, (y+=10), "Enable sound %s", /*(currentConfig.EmuOpt &0x004)?"ON":*/"OFF"); // 3\r
+ gp2x_text_out15(tl_x, (y+=10), "Sound Quality: %5iHz %s", 0, "" /*currentConfig.PsndRate, monostereo*/); // 4\r
+ gp2x_text_out15(tl_x, (y+=10), "Region: %s",\r
+ Settings.region_force == 2 ? "NTSC" : Settings.region_force == 1 ? "PAL" : "OFF"); // 5\r
+ gp2x_text_out15(tl_x, (y+=10), "Use SRAM savestates %s", "OFF");\r
+ gp2x_text_out15(tl_x, (y+=10), "Confirm savestate %s", strssconfirm);\r
+ gp2x_text_out15(tl_x, (y+=10), "Save slot %i", 0/*state_slot*/); // 8\r
+ gp2x_text_out15(tl_x, (y+=10), "GP2X CPU clock %iMhz", Settings.cpuclock);\r
+ gp2x_text_out15(tl_x, (y+=10), "[advanced options]"); // 10\r
+ gp2x_text_out15(tl_x, (y+=10), "Save cfg as default");\r
+ if (fceugi)\r
+ gp2x_text_out15(tl_x, (y+=10), "Save cfg for current game only");\r
+\r
+ // draw cursor\r
+ gp2x_text_out15(tl_x - 16, tl_y + menu_sel*10, ">");\r
+\r
+ gp2x_video_flip();\r
+}\r
+\r
+/*\r
+static int sndrate_prevnext(int rate, int dir)\r
+{\r
+ int i, rates[] = { 8000, 11025, 16000, 22050, 44100 };\r
+\r
+ for (i = 0; i < 5; i++)\r
+ if (rates[i] == rate) break;\r
+\r
+ i += dir ? 1 : -1;\r
+ if (i > 4) return dir ? 44100 : 22050;\r
+ if (i < 0) return dir ? 11025 : 8000;\r
+ return rates[i];\r
+}\r
+*/\r
+static void int_incdec(int *p, int inc, int min, int max)\r
+{\r
+ *p += inc;\r
+ if (*p < min) *p = min;\r
+ else if (*p > max) *p = max;\r
+}\r
+\r
+static int menu_loop_options(void)\r
+{\r
+ int menu_sel = 0, menu_sel_max = 11;\r
+ unsigned long inp = 0;\r
+\r
+ if (fceugi) menu_sel_max++;\r
+\r
+ for(;;)\r
+ {\r
+ draw_menu_options(menu_sel);\r
+ inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_LEFT|GP2X_RIGHT|GP2X_B|GP2X_X|GP2X_A);\r
+ if(inp & GP2X_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }\r
+ if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }\r
+ if((inp& GP2X_B)||(inp&GP2X_LEFT)||(inp&GP2X_RIGHT)) { // toggleable options\r
+ switch (menu_sel) {\r
+ case 1: Settings.showfps = !Settings.showfps; break;\r
+ //case 6: Settings. = !Settings.showfps; break;\r
+ //case 16: amenu_loop_options(); break;\r
+ case 17: // done (update and write)\r
+ //if (emu_WriteConfig(0)) strcpy(menuErrorMsg, "config saved");\r
+ //else strcpy(menuErrorMsg, "failed to write config");\r
+ return 1;\r
+ case 18: // done (update and write for current game)\r
+ //if (emu_WriteConfig(1)) strcpy(menuErrorMsg, "config saved");\r
+ //else strcpy(menuErrorMsg, "failed to write config");\r
+ return 1;\r
+ }\r
+ }\r
+ if(inp & (GP2X_X|GP2X_A)) {\r
+ return 0; // done (update, no write)\r
+ }\r
+ if(inp & (GP2X_LEFT|GP2X_RIGHT)) { // multi choise\r
+ switch (menu_sel) {\r
+ case 0: int_incdec(&Settings.scaling, (inp & GP2X_LEFT) ? -1 : 1, 0, 3); break;\r
+ case 2: int_incdec(&Settings.frameskip, (inp & GP2X_LEFT) ? -1 : 1, -1, 32); break;\r
+/*\r
+ case 4:\r
+ if ((inp & GP2X_RIGHT) && currentConfig.PsndRate == 44100 && !(currentConfig.PicoOpt&0x08)) {\r
+ currentConfig.PsndRate = 8000; currentConfig.PicoOpt|= 0x08;\r
+ } else if ((inp & GP2X_LEFT) && currentConfig.PsndRate == 8000 && (currentConfig.PicoOpt&0x08)) {\r
+ currentConfig.PsndRate = 44100; currentConfig.PicoOpt&=~0x08;\r
+ } else currentConfig.PsndRate = sndrate_prevnext(currentConfig.PsndRate, inp & GP2X_RIGHT);\r
+ break;\r
+*/\r
+ case 5: int_incdec(&Settings.region_force, (inp & GP2X_LEFT) ? -1 : 1, 0, 2); break;\r
+ case 7: int_incdec(&Settings.sstate_confirm, (inp & GP2X_LEFT) ? -1 : 1, 0, 3); break;\r
+ //case 8: int_incdec(&Settings., (inp & GP2X_LEFT) ? -1 : 1, 0, 9); break;\r
+ case 14:\r
+ while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) {\r
+ Settings.cpuclock += (inp & GP2X_LEFT) ? -1 : 1;\r
+ if (Settings.cpuclock < 1) Settings.cpuclock = 1;\r
+ draw_menu_options(menu_sel);\r
+ usleep(50*1000);\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+// -------------- credits --------------\r
+\r
+static void draw_menu_credits(void)\r
+{\r
+ int tl_x = 15, tl_y = 70, y;\r
+ //memset(gp2x_screen, 0, 320*240);\r
+ gp2x_fceu_copy_bg();\r
+\r
+ // TODO\r
+\r
+ gp2x_video_flip();\r
+}\r
+\r
+\r
+// -------------- root menu --------------\r
+\r
+static void draw_menu_root(int menu_sel)\r
+{\r
+ int tl_x = 70, tl_y = 70, y;\r
+ gp2x_fceu_copy_bg();\r
+\r
+ y = tl_y;\r
+ if (fceugi) {\r
+ gp2x_text_out15(tl_x, y, "Resume game");\r
+ gp2x_text_out15(tl_x, (y+=10), "Save State");\r
+ gp2x_text_out15(tl_x, (y+=10), "Load State");\r
+ gp2x_text_out15(tl_x, (y+=10), "Reset game");\r
+ } else {\r
+ y += 30;\r
+ }\r
+ gp2x_text_out15(tl_x, (y+=10), "Load new ROM");\r
+ gp2x_text_out15(tl_x, (y+=10), "Change options");\r
+ gp2x_text_out15(tl_x, (y+=10), "Configure controls");\r
+ gp2x_text_out15(tl_x, (y+=10), "Credits");\r
+ gp2x_text_out15(tl_x, (y+=10), "Exit");\r
+// TODO\r
+// if (PicoPatches)\r
+// gp2x_text_out15(tl_x, (y+=10), "Patches / GameGenie");\r
+\r
+ // draw cursor\r
+ gp2x_text_out15(tl_x - 16, tl_y + menu_sel*10, ">");\r
+ // error\r
+ if (menuErrorMsg[0]) gp2x_text_out15(5, 226, menuErrorMsg);\r
+ gp2x_video_flip();\r
+}\r
+\r
+\r
+static int menu_loop_root(void)\r
+{\r
+ int ret, menu_sel = 4, menu_sel_max = 8, menu_sel_min = 4;\r
+ unsigned long inp = 0;\r
+ char curr_path[PATH_MAX], *selfname;\r
+ FILE *tstf;\r
+\r
+ if ( (tstf = fopen(lastLoadedGameName, "rb")) )\r
+ {\r
+ fclose(tstf);\r
+ strncpy(curr_path, lastLoadedGameName, sizeof(curr_path));\r
+ curr_path[sizeof(curr_path)-1] = 0;\r
+ }\r
+ else\r
+ {\r
+ getcwd(curr_path, PATH_MAX);\r
+ }\r
+\r
+ if (fceugi) menu_sel = menu_sel_min = 0;\r
+// TODO if (PicoPatches) menu_sel_max = 9;\r
+\r
+ /* make sure action buttons are not pressed on entering menu */\r
+ draw_menu_root(menu_sel);\r
+ while (gp2x_joystick_read(1) & (GP2X_B|GP2X_X|GP2X_SELECT)) usleep(50*1000);\r
+\r
+ for (;;)\r
+ {\r
+ draw_menu_root(menu_sel);\r
+ inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_B|GP2X_X);\r
+ if(inp & GP2X_UP ) { menu_sel--; if (menu_sel < menu_sel_min) menu_sel = menu_sel_max; }\r
+ if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = menu_sel_min; }\r
+ if(inp &(GP2X_SELECT|GP2X_X)){\r
+ if (fceugi) {\r
+ while (gp2x_joystick_read(1) & GP2X_X) usleep(50*1000); // wait until X is released\r
+ Exit = 0;\r
+ return 0;\r
+ }\r
+ }\r
+ if(inp & GP2X_B ) {\r
+ switch (menu_sel) {\r
+ case 0: // resume game\r
+ if (fceugi) {\r
+ while (gp2x_joystick_read(1) & GP2X_B) usleep(50*1000);\r
+ Exit = 0;\r
+ return 0;\r
+ }\r
+ break;\r
+ case 1: // save state\r
+ if (fceugi) {\r
+ /*if(savestate_menu_loop(0))\r
+ continue;*/\r
+ return 0;\r
+ }\r
+ break;\r
+ case 2: // load state\r
+ if (fceugi) {\r
+ /*if(savestate_menu_loop(1))\r
+ continue;*/\r
+ return 0;\r
+ }\r
+ break;\r
+ case 3: // reset game\r
+ if (fceugi) {\r
+ return 0;\r
+ }\r
+ break;\r
+ case 4: // select rom\r
+ selfname = romsel_loop(curr_path);\r
+ if (selfname) {\r
+ printf("selected file: %s\n", selfname);\r
+ return 2;\r
+ }\r
+ break;\r
+ case 5: // options\r
+ ret = menu_loop_options();\r
+ if (ret == 1) continue; // status update\r
+ break;\r
+ case 6: // controls\r
+ // TODO kc_sel_loop();\r
+ break;\r
+ case 7: // credits\r
+ draw_menu_credits();\r
+ usleep(500*1000);\r
+ inp = wait_for_input(GP2X_B|GP2X_X);\r
+ break;\r
+ case 8: // exit\r
+ return 1;\r
+ case 9: // patches/gg\r
+ break;\r
+ }\r
+ }\r
+ menuErrorMsg[0] = 0; // clear error msg\r
+ }\r
+}\r
+\r
+\r
+static void menu_prepare_bg(void)\r
+{\r
+ // TODO...\r
+}\r
+\r
+static void menu_gfx_prepare(void)\r
+{\r
+ menu_prepare_bg();\r
+\r
+ // switch bpp\r
+ gp2x_video_changemode(16);\r
+ gp2x_video_RGB_setscaling(0, 320, 240);\r
+ gp2x_video_flip();\r
+}\r
+\r
+\r
+int gp2x_menu_do(void)\r
+{\r
+ int ret;\r
+\r
+ menu_gfx_prepare();\r
+\r
+ ret = menu_loop_root();\r
+\r
+ menuErrorMsg[0] = 0;\r
+\r
+ return ret;\r
+}\r
+\r
+\r
--- /dev/null
+
+extern char menuErrorMsg[40];
+
+int gp2x_menu_do(void);
+
-/*
- GP2X minimal library v0.A by rlyeh, 2005. emulnation.info@rlyeh (swap it!)
-
- + GP2X 920t/940t CPUs library with a FIFO message system.
- + GP2X video library with double buffering.
- + GP2X sound library with double buffering.
- + GP2X blitter library.
- + GP2X timer library.
- + GP2X joystick library.
-
- Thanks to Squidge, Robster, snaff, Reesy and NK, for the help & previous work! :-)
-
-
- License
- =======
-
- Free for non-commercial projects (it would be nice receiving a mail from you).
- Other cases, ask me first.
-
- GamePark Holdings is not allowed to use this library and/or use parts from it.
-
-
- Known projects using the library or parts from it
- =================================================
-
- REminiscence-0.1.8 (rlyeh)
- Atari800 GP2X pre-release 3 (foft)
- XUMP (kedo)
- MAME2X (Franxis)
- DrMD for GP2X (Reesy)
-
-
- What's new
- ==========
-
- 0.A: 940t disabled all time unless required
- sound is paused by default now, use gp2x_sound_pause() to unlock it
-
- fixed functions:
- - gp2x_sound_play() ; increased the number of sampling buffers
- - gp2x_timer_read() ; it should work again. broken at some point before
- - gp2x_dualcore_launch_program_from_disk() ; it missed the code uploading call
-
- added functions:
- - gp2x_sound_pause()
- - gp2x_timer_delay()
- - gp2x_dualcore_pause()
-
- 0.9: initial FIFO message system for dual cpu cores.
- initial 48 Mb support.
- initial quadruple buffering in 8bbp mode.
-
- added functions:
- - gp2x_dualcore_exec() ; initial FIFO message system for dual cpu cores.
- - gp2x_dualcore_sync() ; initial FIFO message system for dual cpu cores.
-
- improved functions:
- - gp2x_video_flip() ; initial quadruple buffering in 8bbp mode.
-
- 0.8: initial dual cores cpu support.
- very basic blit functions by popular demand ;-)
- vsync & hsync waiting code (thanks Reesy)
-
- added functions:
- - gp2x_launch_program() ; initial dual cores cpu support.
- - gp2x_launch_program_from_disk() ; initial dual cores cpu support.
- - gp2x_launch_subprogram() ; initial dual cores cpu support.
- - gp2x_blitter_rect15() ; very basic blit function by popular demand ;-)
- - gp2x_blitter_rect8() ; very basic blit function by popular demand ;-)
- - gp2x_video_hsync() ; hsync waiting code (thanks Reesy)
- - gp2x_video_vsync() ; vsync waiting code (thanks Reesy)
-
- fixed functions:
- - gp2x_video_color8() ; bugfixed a stupid typo (thanks Franxis for the bug report)
-
- 0.7: added functions:
- - gp2x_sound_volume()
-
- fixed functions:
- - gp2x_deinit() ; fixed menu launch code when exiting.
-
- improved functions:
- - gp2x_timer_read() ; rewritten timer. it should be more accurate now.
- - gp2x_init() ; faster init code.
-
- 0.6: added functions:
- - gp2x_timer_read()
- - gp2x_sound_pause()
-
- fixed functions:
- - gp2x_video_setpalette() ; palette handling was incorrect. fixed.
-
- 0.5: improved functions:
- - gp2x_init() ; better and cleaner initalizing code.
- - gp2x_init() ; sound patched for real stereo output (by using NK's solution)
-
- 0.4: lots of cleanups.
- sound is threaded and double buffered now.
- 8 bpp video support.
-
- fixed functions:
- - gp2x_deinit() ; better and cleaner exiting code.
-
- 0.3: shorter library.
-
- fixed functions:
- - gp2x_joystick_read() ; improved joystick diagonal detection.
-
- 0.2: better code layout.
- public release.
-
- 0.1: beta release.
-*/
-
-#include "minimal.h"
-#include "squidgehack.h"
-#include "asmutils.h"
-
- unsigned char *gp2x_screen8 ,*gp2x_upperRAM;
- unsigned long gp2x_dev[8]={0,0,0,0,0,0,0,0}, gp2x_physvram[8], *gp2x_memregl, gp2x_volume, gp2x_ticks_per_second;
-volatile unsigned long gp2x_sound_pausei=1, gp2x_ticks=0, gp2x_sound=0, *gp2x_dualcore_ram=0;
- unsigned short *gp2x_memregs, *gp2x_screen15, *gp2x_logvram15[4], gp2x_sound_buffer[4+((44100/25)*2)*8]; //25 Hz gives our biggest supported sampling buffer
-volatile unsigned short gp2x_palette[512];
-
-extern void gp2x_sound_frame(void *blah, void *buff, int samples);
-
-// hack
-static int scaling_enabled = 0;
-
-void gp2x_video_flip(void)
-{
- unsigned long address=gp2x_physvram[gp2x_physvram[7]];
- if (scaling_enabled) address += 32;
-
- // since we are using the mmu hack, we must flush the cache first
- // (the params are most likely wrong, but they seem to work somehow)
- flushcache(address, address + 320*240, 0);
-
- if(++gp2x_physvram[7]==4) gp2x_physvram[7]=0;
- gp2x_screen15=gp2x_logvram15[gp2x_physvram[7]];
- gp2x_screen8=(unsigned char *)gp2x_screen15;
-
- gp2x_memregs[0x290E>>1]=(unsigned short)(address & 0xFFFF);
- gp2x_memregs[0x2910>>1]=(unsigned short)(address >> 16);
- gp2x_memregs[0x2912>>1]=(unsigned short)(address & 0xFFFF);
- gp2x_memregs[0x2914>>1]=(unsigned short)(address >> 16);
-}
-
-void gp2x_video_flip_single(void)
-{
- unsigned long address=gp2x_physvram[0];
-
- gp2x_screen15=gp2x_logvram15[0];
- gp2x_screen8=(unsigned char *)gp2x_screen15;
-
- gp2x_memregs[0x290E>>1]=(unsigned short)(address & 0xFFFF);
- gp2x_memregs[0x2910>>1]=(unsigned short)(address >> 16);
- gp2x_memregs[0x2912>>1]=(unsigned short)(address & 0xFFFF);
- gp2x_memregs[0x2914>>1]=(unsigned short)(address >> 16);
-}
-
-
-void gp2x_video_setgamma(unsigned short gamma) /*0..255*/
-{
- int i=256*3;
- gp2x_memregs[0x295C>>1]=0;
- while(i--) gp2x_memregs[0x295E>>1]=gamma;
-}
-
-void gp2x_video_setpalette(void)
-{
- unsigned short *g=(unsigned short *)gp2x_palette; int i=512;
- gp2x_memregs[0x2958>>1]=0;
- while(i--) gp2x_memregs[0x295A>>1]=*g++;
-}
-
-void gp2x_blitter_rect15(gp2x_rect *r)
-{
- int x, y; unsigned short *data=r->data15, *offset=&gp2x_screen15[r->x+r->y*320];
-
- y=r->h; if(r->solid)
- while(y--) { x=r->w; while(x--) *offset++=*data++; offset+=320-x; }
- else
- while(y--) { x=r->w; while(x--) { if(*data) *offset=*data; offset++, data++; }
- offset+=320-x; }
-}
-
-void gp2x_blitter_rect8(gp2x_rect *r)
-{
- int x, y; unsigned char *data=r->data8, *offset=&gp2x_screen8[r->x+r->y*320];
-
- y=r->h; if(r->solid)
- while(y--) { x=r->w; while(x--) *offset++=*data++; offset+=320-x; }
- else
- while(y--) { x=r->w; while(x--) { if(*data) *offset=*data; offset++, data++; }
- offset+=320-x; }
-}
-
-unsigned long gp2x_joystick_read(void)
-{
- unsigned long value=(gp2x_memregs[0x1198>>1] & 0x00FF);
-
- if(value==0xFD) value=0xFA;
- if(value==0xF7) value=0xEB;
- if(value==0xDF) value=0xAF;
- if(value==0x7F) value=0xBE;
-
- return ~((gp2x_memregs[0x1184>>1] & 0xFF00) | value | (gp2x_memregs[0x1186>>1] << 16));
-}
-
-void gp2x_sound_volume(int l, int r)
-{
- l=(((l*0x50)/100)<<8)|((r*0x50)/100); //0x5A, 0x60
- ioctl(gp2x_dev[4], SOUND_MIXER_WRITE_PCM, &l); //SOUND_MIXER_WRITE_VOLUME
-}
-
-void gp2x_timer_delay(unsigned long ticks)
-{
- unsigned long target=gp2x_memregl[0x0A00>>2]+ticks*gp2x_ticks_per_second;
- while(gp2x_memregl[0x0A00>>2]<target);
-}
-
-unsigned long gp2x_timer_read(void)
-{
- return gp2x_memregl[0x0A00>>2]/gp2x_ticks_per_second;
-}
-
-unsigned long gp2x_timer_read_ms(void)
-{
- return gp2x_memregl[0x0A00>>2];
-}
-
-
-void gp2x_sound_pause(int yes) { gp2x_sound_pausei=yes; }
-
-#if 0
-static void *gp2x_sound_play(void *blah)
-{
- int flip=0, flyp=gp2x_sound_buffer[1];
- struct timespec ts; ts.tv_sec=0, ts.tv_nsec=gp2x_sound_buffer[2];
-
- while(!gp2x_sound)
- {
- nanosleep(&ts, NULL);
-
-
- if(!gp2x_sound_pausei)
- {
- // [1] is sound buffer size at 22050, 16, stereo, it is 1468 (367*4)
- // [0] number of bytes?, at 22050,16,stereo, it is 367
- // first half of buffer
-
- // first one is 368
-
-
- gp2x_sound_frame(blah, (void *)(&gp2x_sound_buffer[4+flip]), gp2x_sound_buffer[0]);
- // write out to second half of buffer
- write(gp2x_dev[3], (void *)(&gp2x_sound_buffer[4+flyp]), gp2x_sound_buffer[1]);
-
- flip+=gp2x_sound_buffer[1];
- if(flip==gp2x_sound_buffer[1]*8) flip=0;
- flyp+=gp2x_sound_buffer[1];
- if(flyp==gp2x_sound_buffer[1]*8) flyp=0;
- }
- }
- return NULL;
-}
-#endif
-
-#if 0
-static void gp2x_initqueue(gp2x_queue *q, unsigned long queue_items, unsigned long *position920t, unsigned long *position940t)
-{
- q->head = q->tail = q->items = 0;
- q->max_items = queue_items;
- if(position920t) q->place920t=position920t; else q->place920t=(unsigned long *)malloc(sizeof(unsigned long) * queue_items);
- if(position940t) q->place940t=position940t;
- memset(q->place920t, 0, sizeof(unsigned long) * queue_items);
-}
-
-static void gp2x_enqueue(gp2x_queue *q, unsigned long data)
-{
- while(q->items==q->max_items); /*waiting for tail to decrease...*/
- q->place920t[q->head = (q->head < q->max_items ? q->head+1 : 0)] = data;
- q->items++;
-}
-
-/* UNUSED
- static unsigned long gp2x_dequeue(gp2x_queue *q)
-{
- while(!q->items); //waiting for head to increase...
- q->items--;
- return q->place920t[q->tail = (q->tail < q->max_items ? q->tail+1 : 0)];
-} */
-#endif
-
- void gp2x_dualcore_pause(int yes) { if(yes) gp2x_memregs[0x0904>>1] &= 0xFFFE; else gp2x_memregs[0x0904>>1] |= 1; }
-static void gp2x_940t_reset(int yes) { gp2x_memregs[0x3B48>>1] = ((yes&1) << 7) | (0x03); }
-static void gp2x_940t_pause(int yes) { gp2x_dualcore_pause(yes); }
-
-static void gp2x_dualcore_registers(int save)
-{
- static unsigned short regs[8];
-
- if(save)
- {
- regs[0]=gp2x_memregs[0x0904>>1]; regs[1]=gp2x_memregs[0x0912>>1];
- regs[2]=gp2x_memregs[0x091c>>1]; regs[3]=gp2x_memregs[0x3b40>>1];
- regs[4]=gp2x_memregs[0x3b42>>1]; regs[5]=gp2x_memregs[0x3b48>>1];
- regs[6]=gp2x_memregs[0x3b44>>1]; regs[7]=gp2x_memregs[0x3b46>>1];
-
- gp2x_940t_reset(1);
- gp2x_940t_pause(1);
- }
- else
- {
- gp2x_memregs[0x0904>>1]=regs[0]; gp2x_memregs[0x0912>>1]=regs[1];
- gp2x_memregs[0x091c>>1]=regs[2]; gp2x_memregs[0x3b40>>1]=regs[3];
- gp2x_memregs[0x3b42>>1]=regs[4]; gp2x_memregs[0x3b48>>1]=regs[5];
- gp2x_memregs[0x3b44>>1]=regs[6]; gp2x_memregs[0x3b46>>1]=regs[7];
- }
-}
-
-#if 0
-void gp2x_dualcore_sync(void)
-{
- gp2x_queue *q=(gp2x_queue *)gp2x_1stcore_data_ptr(GP2X_QUEUE_ARRAY_PTR);
- while(q->items);
-}
-
-void gp2x_dualcore_exec(unsigned long command) { gp2x_enqueue((gp2x_queue *)gp2x_1stcore_data_ptr(GP2X_QUEUE_ARRAY_PTR),command); }
-
-void gp2x_dualcore_launch_program(unsigned long *area, unsigned long size)
-{
- unsigned long i=0, *arm940t_ram=(unsigned long *)gp2x_dualcore_ram;
-
- gp2x_940t_reset(1);
-
- gp2x_memregs[0x3B40>>1] = 0; //disable interrupts
- gp2x_memregs[0x3B42>>1] = 0;
- gp2x_memregs[0x3B44>>1] = 0xffff;
- gp2x_memregs[0x3B46>>1] = 0xffff;
-
- gp2x_940t_pause(0);
-
- while(i < size) *arm940t_ram++=area[i++];
-
- gp2x_initqueue((gp2x_queue *)gp2x_1stcore_data_ptr(GP2X_QUEUE_ARRAY_PTR), GP2X_QUEUE_MAX_ITEMS, (unsigned long *)gp2x_1stcore_data_ptr(GP2X_QUEUE_DATA_PTR), (unsigned long *)gp2x_2ndcore_data_ptr(GP2X_QUEUE_DATA_PTR));
-
- gp2x_940t_reset(0);
-}
-
-void gp2x_dualcore_launch_program_from_disk(const char *file, unsigned long offset, unsigned long size)
-{
- FILE *in; void *data;
-
- if((in=fopen(file, "rb"))==NULL) return;
- if((data=malloc(size))==NULL) { fclose(in); return; }
- fseek(in, 0L, offset);
- fread(data, 1, size, in);
- gp2x_dualcore_launch_program((unsigned long *)data, size);
- free(data);
- fclose(in);
-}
-#endif
-
-void gp2x_init(int ticks_per_second, int bpp, int rate, int bits, int stereo, int Hz)
-{
- struct fb_fix_screeninfo fixed_info;
- static int first=1;
-
- // GP2X_DO_SOUND
- int gp2x_do_sound=1;
- int frag=0;
- int channels=1;
- int stereoLocal=0;
- int ret;
-
- gp2x_ticks_per_second=7372800/ticks_per_second;
-
- if(!gp2x_dev[0]) gp2x_dev[0] = open("/dev/fb0", O_RDWR);
- if(!gp2x_dev[1]) gp2x_dev[1] = open("/dev/fb1", O_RDWR);
- if(!gp2x_dev[2]) gp2x_dev[2] = open("/dev/mem", O_RDWR);
-
- ioctl(gp2x_dev[gp2x_physvram[7]=0], FBIOGET_FSCREENINFO, &fixed_info);
- gp2x_physvram[2]=gp2x_physvram[0]=fixed_info.smem_start;
- gp2x_screen15=gp2x_logvram15[2]=gp2x_logvram15[0]=
- (unsigned short *)mmap(0, 0x20000*2, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], gp2x_physvram[0]);
- gp2x_screen8=(unsigned char *)gp2x_screen15;
- printf("/dev/fb0 is @ %08lx / %p\n", gp2x_physvram[0], gp2x_screen15);
-
- ioctl(gp2x_dev[1], FBIOGET_FSCREENINFO, &fixed_info);
- gp2x_physvram[3]=gp2x_physvram[1]=fixed_info.smem_start;
- gp2x_logvram15[3]=gp2x_logvram15[1]=
- (unsigned short *)mmap(0, 0x20000*2, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], gp2x_physvram[1]);
- printf("/dev/fb1 is @ %08lx / %p\n", gp2x_physvram[1], gp2x_logvram15[1]);
-
- // apply the MMU hack
- ret = mmuhack();
- printf("squidge hack code finished and returned %s\n", ret ? "ok" : "fail");
-
- // don't run sound right now
- if ( gp2x_do_sound)
- {
- if(!gp2x_dev[3]) gp2x_dev[3] = open("/dev/dsp", O_WRONLY|O_ASYNC);
- if(!gp2x_dev[4]) gp2x_dev[4] = open("/dev/mixer", O_RDWR);
- }
-
-// gp2x_dualcore_ram=(unsigned long *)mmap(0, 0x1000000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0x03000000);
-/*gp2x_dualcore_ram=(unsigned long *)mmap(0, 0x2000000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0x02000000);*/
- gp2x_memregl=(unsigned long *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0xc0000000);
- gp2x_memregs=(unsigned short *)gp2x_memregl;
-
- if(first) { printf(MINILIB_VERSION "\n");
- gp2x_dualcore_registers(1);
- gp2x_sound_volume(100,100);
- gp2x_memregs[0x0F16>>1] = 0x830a; usleep(100000);
- gp2x_memregs[0x0F58>>1] = 0x100c; usleep(100000); }
-
- gp2x_memregs[0x28DA>>1]=(((bpp+1)/8)<<9)|0xAB; /*8/15/16/24bpp...*/
- gp2x_memregs[0x290C>>1]=320*((bpp+1)/8); /*line width in bytes*/
-
- memset(gp2x_screen15, 0, 320*240*2); gp2x_video_flip();
- memset(gp2x_screen15, 0, 320*240*2); gp2x_video_flip();
-
- //if(bpp==8) gp2x_physvram[2]+=320*240, gp2x_physvram[3]+=320*240,
- // gp2x_logvram15[2]+=320*240/2, gp2x_logvram15[3]+=320*240/2;
- if(bpp==8) gp2x_physvram[2]+=0x20000, gp2x_physvram[3]+=0x20000,
- gp2x_logvram15[2]+=0x20000/2, gp2x_logvram15[3]+=0x20000/2;
-
-
- if ( gp2x_do_sound)
- {
- ioctl(gp2x_dev[3], SNDCTL_DSP_SPEED, &rate);
- ioctl(gp2x_dev[3], SNDCTL_DSP_SETFMT, &bits);
-
- ioctl(gp2x_dev[3], SNDCTL_DSP_CHANNELS, &channels);
- ioctl(gp2x_dev[3], SNDCTL_DSP_STEREO, &stereoLocal);
-
- frag = 0x40000|13;
- ioctl(gp2x_dev[3], SNDCTL_DSP_SETFRAGMENT, &frag);
-
- {
- // calculate buffer size
- int frag = 0, bsize, buffers = 16;
- bsize = rate / 32;
- if (rate > 22050) { bsize*=4; buffers*=2; } // 44k mode seems to be very demanding
- while ((bsize>>=1)) frag++;
- frag |= buffers<<16; // 16 buffers
- ioctl(gp2x_dev[3], SNDCTL_DSP_SETFRAGMENT, &frag);
- printf("gp2x_set_sound: %i/%ibit/%s, %i buffers of %i bytes\n",
- rate, bits, stereo?"stereo":"mono", frag>>16, 1<<(frag&0xffff));
- }
-
- if(first)
- {
- first=0;
- }
- }
-}
-
-
-extern int fcloseall(void);
-void gp2x_deinit(void)
-{
- while((gp2x_sound++)<1000000); //wait arm920t threads to finish
-
- gp2x_dualcore_registers(0);
- mmuunhack();
-
- gp2x_memregs[0x28DA>>1]=0x4AB; //set video mode
- gp2x_memregs[0x290C>>1]=640;
-
- { int i; for(i=0;i<8;i++) if(gp2x_dev[i]) close(gp2x_dev[i]); } //close all devices
-
- fcloseall(); //close all files
-
-}
-
-
-void SetVideoScaling(int pixels,int width,int height)
-{
- float x, y;
- float xscale,yscale=0;
-
- int bpp=(gp2x_memregs[0x28DA>>1]>>9)&0x3; /* bytes per pixel */
-
- scaling_enabled = (width == 320) ? 0 : 1;
-
- if(gp2x_memregs[0x2800>>1]&0x100) /* TV-Out ON? */
- {
- xscale=489.0; /* X-Scale with TV-Out (PAL or NTSC) */
- if (gp2x_memregs[0x2818>>1] == 287) /* PAL? */
- yscale=(pixels*274.0)/320.0; /* Y-Scale with PAL */
- else if (gp2x_memregs[0x2818>>1] == 239) /* NTSC? */
- yscale=(pixels*331.0)/320.0; /* Y-Scale with NTSC */
- }
- else /* TV-Out OFF? */
- {
- xscale=1024.0; /* X-Scale for LCD */
- yscale=pixels; /* Y-Scale for LCD */
- }
-
- x=(xscale*width)/320.0;
- y=(yscale*bpp*height)/240.0;
- gp2x_memregs[0x2906>>1]=(unsigned short)x; /* scale horizontal */
- gp2x_memregl[0x2908>>2]=(unsigned long)y; /* scale vertical */
- gp2x_memregs[0x290C>>1]=pixels*bpp; /* Set Video Width */
-}
+/**\r
+ * This is a rewrite of a subset of rlyeh's minimal library.\r
+**/\r
+\r
+/*\r
+\r
+ GP2X minimal library v0.A by rlyeh, (c) 2005. emulnation.info@rlyeh (swap it!)\r
+\r
+ Thanks to Squidge, Robster, snaff, Reesy and NK, for the help & previous work! :-)\r
+\r
+ License\r
+ =======\r
+\r
+ Free for non-commercial projects (it would be nice receiving a mail from you).\r
+ Other cases, ask me first.\r
+\r
+ GamePark Holdings is not allowed to use this library and/or use parts from it.\r
+\r
+*/\r
+\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <sys/mman.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <sys/ioctl.h>\r
+#include <sys/soundcard.h>\r
+#include <fcntl.h>\r
+#include <errno.h>\r
+\r
+#include "minimal.h"\r
+#include "usbjoy.h"\r
+#include "asmutils.h"\r
+\r
+volatile unsigned short *gp2x_memregs;\r
+//static\r
+volatile unsigned long *gp2x_memregl;\r
+static void *gp2x_screens[4];\r
+static int screensel = 0;\r
+//static\r
+int memdev = 0;\r
+static int sounddev = 0, mixerdev = 0;\r
+\r
+void *gp2x_screen;\r
+\r
+#define FRAMEBUFF_WHOLESIZE (0x30000*4) // 320*240*2 + some more\r
+#define FRAMEBUFF_ADDR0 (0x4000000-FRAMEBUFF_WHOLESIZE)\r
+#define FRAMEBUFF_ADDR1 (FRAMEBUFF_ADDR0+0x30000)\r
+#define FRAMEBUFF_ADDR2 (FRAMEBUFF_ADDR1+0x30000)\r
+#define FRAMEBUFF_ADDR3 (FRAMEBUFF_ADDR2+0x30000)\r
+\r
+static const int gp2x_screenaddrs[4] = { FRAMEBUFF_ADDR0, FRAMEBUFF_ADDR1, FRAMEBUFF_ADDR2, FRAMEBUFF_ADDR3 };\r
+static int gp2x_screenaddrs_use[4];\r
+static unsigned short gp2x_screenaddr_old[4];\r
+\r
+\r
+// hack to simplify thing for fceu\r
+static int scaling_enabled = 0;\r
+\r
+/* video stuff */\r
+void gp2x_video_flip(void)\r
+{\r
+ unsigned short lsw, msw;\r
+ int addr = gp2x_screenaddrs_use[screensel&3];\r
+\r
+ if (scaling_enabled) addr += 32;\r
+\r
+ // since we are using the mmu hack, we must flush the cache first\r
+ // (the params are most likely wrong, but they seem to work somehow)\r
+ flushcache(addr, addr + 320*240*2, 0);\r
+\r
+ lsw = (unsigned short) addr;\r
+ msw = (unsigned short)(addr >> 16);\r
+\r
+ gp2x_memregs[0x2910>>1] = msw;\r
+ gp2x_memregs[0x2914>>1] = msw;\r
+ gp2x_memregs[0x290E>>1] = lsw;\r
+ gp2x_memregs[0x2912>>1] = lsw;\r
+\r
+ // jump to other buffer:\r
+ gp2x_screen = gp2x_screens[++screensel&3];\r
+}\r
+\r
+/* doulblebuffered flip */\r
+void gp2x_video_flip2(void)\r
+{\r
+ unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&1] >> 16);\r
+\r
+ gp2x_memregs[0x2910>>1] = msw;\r
+ gp2x_memregs[0x2914>>1] = msw;\r
+ gp2x_memregs[0x290E>>1] = 0;\r
+ gp2x_memregs[0x2912>>1] = 0;\r
+\r
+ // jump to other buffer:\r
+ gp2x_screen = gp2x_screens[++screensel&1];\r
+}\r
+\r
+\r
+void gp2x_video_changemode2(int bpp)\r
+{\r
+ gp2x_memregs[0x28DA>>1]=(((bpp+1)/8)<<9)|0xAB; /*8/15/16/24bpp...*/\r
+ gp2x_memregs[0x290C>>1]=320*((bpp+1)/8); /*line width in bytes*/\r
+}\r
+\r
+\r
+void gp2x_video_changemode(int bpp)\r
+{\r
+ gp2x_video_changemode2(bpp);\r
+\r
+ gp2x_memset_all_buffers(0, 0, 320*240*2);\r
+ gp2x_video_flip();\r
+}\r
+\r
+\r
+void gp2x_video_setpalette(int *pal, int len)\r
+{\r
+ unsigned short *g=(unsigned short *)pal;\r
+ volatile unsigned short *memreg = &gp2x_memregs[0x295A>>1];\r
+ gp2x_memregs[0x2958>>1] = 0;\r
+\r
+ len *= 2;\r
+ while(len--) *memreg=*g++;\r
+}\r
+\r
+\r
+// TV Compatible function //\r
+void gp2x_video_RGB_setscaling(int ln_offs, int W, int H)\r
+{\r
+ float escalaw, escalah;\r
+ int bpp = (gp2x_memregs[0x28DA>>1]>>9)&0x3;\r
+ unsigned short scalw;\r
+\r
+ // fceu hack\r
+ scaling_enabled = (W == 320) ? 0 : 1;\r
+\r
+ // set offset\r
+ gp2x_screenaddrs_use[0] = gp2x_screenaddrs[0] + ln_offs * 320 * bpp;\r
+ gp2x_screenaddrs_use[1] = gp2x_screenaddrs[1] + ln_offs * 320 * bpp;\r
+ gp2x_screenaddrs_use[2] = gp2x_screenaddrs[2] + ln_offs * 320 * bpp;\r
+ gp2x_screenaddrs_use[3] = gp2x_screenaddrs[3] + ln_offs * 320 * bpp;\r
+\r
+ escalaw = 1024.0; // RGB Horiz LCD\r
+ escalah = 320.0; // RGB Vert LCD\r
+\r
+ if(gp2x_memregs[0x2800>>1]&0x100) //TV-Out\r
+ {\r
+ escalaw=489.0; // RGB Horiz TV (PAL, NTSC)\r
+ if (gp2x_memregs[0x2818>>1] == 287) //PAL\r
+ escalah=274.0; // RGB Vert TV PAL\r
+ else if (gp2x_memregs[0x2818>>1] == 239) //NTSC\r
+ escalah=331.0; // RGB Vert TV NTSC\r
+ }\r
+\r
+ // scale horizontal\r
+ scalw = (unsigned short)((float)escalaw *(W/320.0));\r
+ /* if there is no horizontal scaling, vertical doesn't work. Here is a nasty wrokaround... */\r
+ if (H != 240 && W == 320) scalw--;\r
+ gp2x_memregs[0x2906>>1]=scalw;\r
+ // scale vertical\r
+ gp2x_memregl[0x2908>>2]=(unsigned long)((float)escalah *bpp *(H/240.0));\r
+}\r
+\r
+\r
+void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len)\r
+{\r
+ if (buffers & (1<<0)) memcpy((char *)gp2x_screens[0] + offset, data, len);\r
+ if (buffers & (1<<1)) memcpy((char *)gp2x_screens[1] + offset, data, len);\r
+ if (buffers & (1<<2)) memcpy((char *)gp2x_screens[2] + offset, data, len);\r
+ if (buffers & (1<<3)) memcpy((char *)gp2x_screens[3] + offset, data, len);\r
+}\r
+\r
+\r
+void gp2x_memcpy_all_buffers(void *data, int offset, int len)\r
+{\r
+ gp2x_memcpy_buffers(0xf, data, offset, len);\r
+}\r
+\r
+\r
+void gp2x_memset_all_buffers(int offset, int byte, int len)\r
+{\r
+ memset((char *)gp2x_screens[0] + offset, byte, len);\r
+ memset((char *)gp2x_screens[1] + offset, byte, len);\r
+ memset((char *)gp2x_screens[2] + offset, byte, len);\r
+ memset((char *)gp2x_screens[3] + offset, byte, len);\r
+}\r
+\r
+\r
+unsigned long gp2x_joystick_read(int allow_usb_joy)\r
+{\r
+ int i;\r
+ unsigned long value=(gp2x_memregs[0x1198>>1] & 0x00FF);\r
+ if(value==0xFD) value=0xFA;\r
+ if(value==0xF7) value=0xEB;\r
+ if(value==0xDF) value=0xAF;\r
+ if(value==0x7F) value=0xBE;\r
+ value = ~((gp2x_memregs[0x1184>>1] & 0xFF00) | value | (gp2x_memregs[0x1186>>1] << 16));\r
+\r
+ if (allow_usb_joy && num_of_joys > 0) {\r
+ // check the usb joy as well..\r
+ gp2x_usbjoy_update();\r
+ for (i = 0; i < num_of_joys; i++)\r
+ value |= gp2x_usbjoy_check(i);\r
+ }\r
+\r
+ return value;\r
+}\r
+\r
+static int s_oldrate = 0, s_oldbits = 0, s_oldstereo = 0;\r
+\r
+void gp2x_start_sound(int rate, int bits, int stereo)\r
+{\r
+ int frag = 0, bsize, buffers;\r
+\r
+ // if no settings change, we don't need to do anything\r
+ if (rate == s_oldrate && s_oldbits == bits && s_oldstereo == stereo) return;\r
+\r
+ if (sounddev > 0) close(sounddev);\r
+ sounddev = open("/dev/dsp", O_WRONLY|O_ASYNC);\r
+ if (sounddev == -1)\r
+ printf("open(\"/dev/dsp\") failed with %i\n", errno);\r
+\r
+ ioctl(sounddev, SNDCTL_DSP_SPEED, &rate);\r
+ ioctl(sounddev, SNDCTL_DSP_SETFMT, &bits);\r
+ ioctl(sounddev, SNDCTL_DSP_STEREO, &stereo);\r
+ // calculate buffer size\r
+ buffers = 16;\r
+ bsize = rate / 32;\r
+ if (rate > 22050) { bsize*=4; buffers*=2; } // 44k mode seems to be very demanding\r
+ while ((bsize>>=1)) frag++;\r
+ frag |= buffers<<16; // 16 buffers\r
+ ioctl(sounddev, SNDCTL_DSP_SETFRAGMENT, &frag);\r
+ printf("gp2x_set_sound: %i/%ibit/%s, %i buffers of %i bytes\n",\r
+ rate, bits, stereo?"stereo":"mono", frag>>16, 1<<(frag&0xffff));\r
+\r
+ s_oldrate = rate; s_oldbits = bits; s_oldstereo = stereo;\r
+ usleep(100000);\r
+}\r
+\r
+\r
+void gp2x_sound_write(void *buff, int len)\r
+{\r
+ write(sounddev, buff, len);\r
+}\r
+\r
+void gp2x_sound_sync(void)\r
+{\r
+ ioctl(sounddev, SOUND_PCM_SYNC, 0);\r
+}\r
+\r
+void gp2x_sound_volume(int l, int r)\r
+{\r
+ l=l<0?0:l; l=l>255?255:l; r=r<0?0:r; r=r>255?255:r;\r
+ l<<=8; l|=r;\r
+ ioctl(mixerdev, SOUND_MIXER_WRITE_PCM, &l); /*SOUND_MIXER_WRITE_VOLUME*/\r
+}\r
+\r
+\r
+/* common */\r
+void gp2x_init(void)\r
+{\r
+ printf("entering init()\n"); fflush(stdout);\r
+\r
+ memdev = open("/dev/mem", O_RDWR);\r
+ if (memdev == -1)\r
+ {\r
+ printf("open(\"/dev/mem\") failed with %i\n", errno);\r
+ exit(1);\r
+ }\r
+\r
+ gp2x_memregs = mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);\r
+ printf("memregs are @ %p\n", gp2x_memregs);\r
+ if(gp2x_memregs == MAP_FAILED)\r
+ {\r
+ printf("mmap(memregs) failed with %i\n", errno);\r
+ exit(1);\r
+ }\r
+ gp2x_memregl = (unsigned long *) gp2x_memregs;\r
+\r
+ gp2x_screens[0] = mmap(0, FRAMEBUFF_WHOLESIZE, PROT_WRITE, MAP_SHARED, memdev, FRAMEBUFF_ADDR0);\r
+ if(gp2x_screens[0] == MAP_FAILED)\r
+ {\r
+ printf("mmap(gp2x_screen) failed with %i\n", errno);\r
+ exit(1);\r
+ }\r
+ printf("framebuffers point to %p\n", gp2x_screens[0]);\r
+ gp2x_screens[1] = (char *) gp2x_screens[0]+0x30000;\r
+ gp2x_screens[2] = (char *) gp2x_screens[1]+0x30000;\r
+ gp2x_screens[3] = (char *) gp2x_screens[2]+0x30000;\r
+\r
+ gp2x_screen = gp2x_screens[0];\r
+ screensel = 0;\r
+\r
+ gp2x_screenaddr_old[0] = gp2x_memregs[0x290E>>1];\r
+ gp2x_screenaddr_old[1] = gp2x_memregs[0x2910>>1];\r
+ gp2x_screenaddr_old[2] = gp2x_memregs[0x2912>>1];\r
+ gp2x_screenaddr_old[3] = gp2x_memregs[0x2914>>1];\r
+\r
+ memcpy(gp2x_screenaddrs_use, gp2x_screenaddrs, sizeof(gp2x_screenaddrs));\r
+ gp2x_memset_all_buffers(0, 0, 320*240*2);\r
+\r
+ // snd\r
+ mixerdev = open("/dev/mixer", O_RDWR);\r
+ if (mixerdev == -1)\r
+ printf("open(\"/dev/mixer\") failed with %i\n", errno);\r
+\r
+ /* init usb joys -GnoStiC */\r
+ gp2x_usbjoy_init();\r
+\r
+ printf("exitting init()\n"); fflush(stdout);\r
+}\r
+\r
+char *ext_menu = 0, *ext_state = 0;\r
+\r
+void gp2x_deinit(void)\r
+{\r
+ gp2x_video_changemode(15);\r
+ gp2x_memregs[0x290E>>1] = gp2x_screenaddr_old[0];\r
+ gp2x_memregs[0x2910>>1] = gp2x_screenaddr_old[1];\r
+ gp2x_memregs[0x2912>>1] = gp2x_screenaddr_old[2];\r
+ gp2x_memregs[0x2914>>1] = gp2x_screenaddr_old[3];\r
+\r
+ munmap(gp2x_screens[0], FRAMEBUFF_WHOLESIZE);\r
+ munmap((void *)gp2x_memregs, 0x10000);\r
+ close(memdev);\r
+ close(mixerdev);\r
+ if (sounddev > 0) close(sounddev);\r
+\r
+ gp2x_usbjoy_deinit();\r
+\r
+ printf("all done, running ");\r
+\r
+ // Zaq121's alternative frontend support from MAME\r
+ if(ext_menu && ext_state) {\r
+ printf("%s -state %s\n", ext_menu, ext_state);\r
+ execl(ext_menu, ext_menu, "-state", ext_state, NULL);\r
+ } else if(ext_menu) {\r
+ printf("%s\n", ext_menu);\r
+ execl(ext_menu, ext_menu, NULL);\r
+ } else {\r
+ printf("gp2xmenu\n");\r
+ chdir("/usr/gp2x");\r
+ execl("gp2xmenu", "gp2xmenu", NULL);\r
+ }\r
+}\r
+\r
+\r
-/*\r
\r
- GP2X minimal library v0.A by rlyeh, (c) 2005. emulnation.info@rlyeh (swap it!)\r
+#ifndef __GP2X_H__\r
+#define __GP2X_H__\r
\r
- Thanks to Squidge, Robster, snaff, Reesy and NK, for the help & previous work! :-)\r
\r
- License\r
- =======\r
+void gp2x_init(void);\r
+void gp2x_deinit(void);\r
\r
- Free for non-commercial projects (it would be nice receiving a mail from you).\r
- Other cases, ask me first.\r
+/* video */\r
+void gp2x_video_flip(void);\r
+void gp2x_video_changemode(int bpp);\r
+void gp2x_video_changemode2(int bpp);\r
+void gp2x_video_setpalette(int *pal, int len);\r
+void gp2x_video_RGB_setscaling(int ln_offs, int W, int H);\r
+void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len);\r
+void gp2x_memcpy_all_buffers(void *data, int offset, int len);\r
+void gp2x_memset_all_buffers(int offset, int byte, int len);\r
\r
- GamePark Holdings is not allowed to use this library and/or use parts from it.\r
+/* sound */\r
+void gp2x_start_sound(int rate, int bits, int stereo);\r
+void gp2x_sound_write(void *buff, int len);\r
+void gp2x_sound_volume(int l, int r);\r
\r
-*/\r
+/* joy */\r
+unsigned long gp2x_joystick_read(int allow_usb_joy);\r
\r
-#include <fcntl.h>\r
-#include <linux/fb.h>\r
-#include <signal.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <sys/mman.h>\r
-//#include <sys/ioctl.h>\r
-#include <sys/soundcard.h>\r
-#include <linux/soundcard.h>\r
\r
-#include <sys/time.h>\r
-#include <unistd.h>\r
-#include <sys/ioctl.h>\r
+extern void *gp2x_screen;\r
+extern int memdev;\r
+extern char *ext_menu, *ext_state;\r
\r
-#ifndef __MINIMAL_H__\r
-#define __MINIMAL_H__\r
-\r
-#define MINILIB_VERSION "GP2X minimal library v0.A by rlyeh, (c) 2005."\r
-\r
-typedef struct gp2x_queue { volatile unsigned long head, tail, items, max_items; unsigned long *place920t, *place940t; } gp2x_queue;\r
-typedef struct gp2x_rect { int x,y,w,h,solid; unsigned short *data15; unsigned char *data8; } gp2x_rect;\r
-\r
-extern void gp2x_timer_delay(unsigned long ticks);\r
-extern void gp2x_sound_pause(int yes);\r
-extern void gp2x_dualcore_pause(int yes);\r
-extern void gp2x_blitter_rect15(gp2x_rect *r);\r
-extern void gp2x_blitter_rect8(gp2x_rect *r);\r
-\r
-\r
-\r
-//extern void gp2x_sound_frame (void *blah, void *bufferg, int samples);\r
\r
enum { GP2X_UP=0x1, GP2X_LEFT=0x4, GP2X_DOWN=0x10, GP2X_RIGHT=0x40,\r
GP2X_START=1<<8, GP2X_SELECT=1<<9, GP2X_L=1<<10, GP2X_R=1<<11,\r
GP2X_A=1<<12, GP2X_B=1<<13, GP2X_X=1<<14, GP2X_Y=1<<15,\r
- GP2X_VOL_UP=1<<23, GP2X_VOL_DOWN=1<<22, GP2X_PUSH=1<<27 };\r
-\r
-\r
-#define GP2X_QUEUE_MAX_ITEMS 16\r
-#define GP2X_QUEUE_ARRAY_PTR ((0x1000-(sizeof(gp2x_queue)<<2)))\r
-#define GP2X_QUEUE_DATA_PTR (GP2X_QUEUE_ARRAY_PTR-(GP2X_QUEUE_MAX_ITEMS<<2))\r
-\r
-#define gp2x_2ndcore_code(v) (*(volatile unsigned long *)(v))\r
-#define gp2x_1stcore_code(v) gp2x_dualcore_ram[(v)>>2]\r
-#define gp2x_2ndcore_data(v) gp2x_2ndcore_code((v)+0x100000)\r
-#define gp2x_1stcore_data(v) gp2x_1stcore_code((v)+0x100000)\r
-#define gp2x_dualcore_data(v) gp2x_1stcore_data(v)\r
-\r
-#define gp2x_2ndcore_code_ptr(v) ((volatile unsigned long *)(v))\r
-#define gp2x_1stcore_code_ptr(v) (&gp2x_dualcore_ram[(v)>>2])\r
-#define gp2x_2ndcore_data_ptr(v) gp2x_2ndcore_code_ptr((v)+0x100000)\r
-#define gp2x_1stcore_data_ptr(v) gp2x_1stcore_code_ptr((v)+0x100000)\r
-\r
-#define gp2x_video_wait_vsync() while(gp2x_memregs[0x1182>>1]&(1<<4));\r
-#define gp2x_video_wait_hsync() while(gp2x_memregs[0x1182>>1]&(1<<5));\r
-\r
-#define gp2x_video_color8(C,R,G,B) do gp2x_palette[((C)<<1)+0]=((G)<<8)|(B),gp2x_palette[((C)<<1)+1]=(R); while(0)\r
-#define gp2x_video_color15(R,G,B,A) ((((R)&0xF8)<<8)|(((G)&0xF8)<<3)|(((B)&0xF8)>>3)|((A)<<5))\r
-\r
-\r
-extern volatile unsigned short gp2x_palette[512];\r
-extern unsigned short *gp2x_screen15;\r
-extern unsigned char *gp2x_screen8;\r
-extern volatile unsigned long *gp2x_dualcore_ram;\r
-\r
-extern void gp2x_init(int tickspersecond, int bpp, int rate, int bits, int stereo, int hz);\r
-extern void gp2x_deinit(void);\r
-\r
-extern void gp2x_video_flip(void);\r
-extern void gp2x_video_flip_single(void);\r
-extern void gp2x_video_setpalette(void);\r
-\r
-extern unsigned long gp2x_joystick_read(void);\r
-\r
-extern void gp2x_sound_volume(int left, int right);\r
-\r
-extern unsigned long gp2x_timer_read(void);\r
-extern unsigned long gp2x_timer_read_ms(void);\r
-\r
-extern void gp2x_dualcore_enable(int on);\r
-extern void gp2x_dualcore_sync(void);\r
-extern void gp2x_dualcore_exec(unsigned long command);\r
-extern void gp2x_dualcore_launch_program(unsigned long *area, unsigned long size);\r
-extern void gp2x_dualcore_launch_program_from_disk(const char *file, unsigned long offset, unsigned long size);\r
-\r
-#define gp2x_dualcore_declare_subprogram(name) extern void gp2x_dualcore_launch_## name ##_subprogram(void);\r
-#define gp2x_dualcore_launch_subprogram(name) gp2x_dualcore_launch_## name ##_subprogram()\r
+ GP2X_VOL_UP=1<<23, GP2X_VOL_DOWN=1<<22, GP2X_PUSH=1<<27 };\r
\r
#endif\r
-\r
+++ /dev/null
-/*\r
-\r
- GP2X minimal library v0.A by rlyeh, (c) 2005. emulnation.info@rlyeh (swap it!)\r
-\r
- Thanks to Squidge, Robster, snaff, Reesy and NK, for the help & previous work! :-)\r
-\r
- License\r
- =======\r
-\r
- Free for non-commercial projects (it would be nice receiving a mail from you).\r
- Other cases, ask me first.\r
-\r
- GamePark Holdings is not allowed to use this library and/or use parts from it.\r
-\r
-*/\r
-\r
-#include "minimal.h"\r
-\r
-#ifndef __MINIMAL_H_STUB_940T__\r
-#define __MINIMAL_H_STUB_940T__\r
-\r
-#undef gp2x_dualcore_data\r
-#define gp2x_dualcore_data(v) gp2x_2ndcore_data(v)\r
-\r
-#define main gp2x_2ndcore_run\r
-\r
-static void gp2x_2ndcore_start(void) __attribute__((naked));\r
-\r
-static void gp2x_2ndcore_start(void)\r
-{\r
- unsigned long gp2x_dequeue(gp2x_queue *q)\r
- {\r
- unsigned long data;\r
-\r
- while(!q->items); //waiting for head to increase...\r
-\r
- data=q->place940t[q->tail = (q->tail < q->max_items ? q->tail+1 : 0)];\r
- q->items--;\r
-\r
- return data;\r
- }\r
-\r
-#define gp2x_dualcore_name_subprogram(name) \\r
-/* 00000020 <_start>: */ \\r
-/* 0:*/ asm volatile (".word 0xe59ff02c"); /* ldr pc, [pc, #44] ; 34 <ioffset> */ \\r
-/* 4:*/ asm volatile (".word 0xe59ff028"); /* ldr pc, [pc, #40] ; 34 <ioffset> */ \\r
-/* 8:*/ asm volatile (".word 0xe59ff024"); /* ldr pc, [pc, #36] ; 34 <ioffset> */ \\r
-/* c:*/ asm volatile (".word 0xe59ff020"); /* ldr pc, [pc, #32] ; 34 <ioffset> */ \\r
-/* 10:*/ asm volatile (".word 0xe59ff01c"); /* ldr pc, [pc, #28] ; 34 <ioffset> */ \\r
-/* 14:*/ asm volatile (".word 0xe59ff018"); /* ldr pc, [pc, #24] ; 34 <ioffset> */ \\r
-/* 18:*/ asm volatile (".word 0xe59ff014"); /* ldr pc, [pc, #20] ; 34 <ioffset> */ \\r
-/* 1c:*/ asm volatile (".word 0xe59ff010"); /* ldr pc, [pc, #16] ; 34 <ioffset> */ \\r
-/* 00000020 <_init>: */ \\r
-/* 20:*/ asm volatile (".word 0xe59fd010"); /* ldr sp, [pc, #16] ; 38 <stack> */ \\r
-/* 24:*/ asm volatile (".word 0xe59fc010"); /* ldr ip, [pc, #16] ; 3c <deadbeef> */ \\r
-/* 28:*/ asm volatile (".word 0xe59fb010"); /* ldr fp, [pc, #16] ; 40 <leetface> */ \\r
-/* 2c:*/ asm volatile (".word 0xe92d1800"); /* stmdb sp!, {fp, ip} */ \\r
-/* 30:*/ asm volatile (".word 0xea000004"); /* b 48 <realinit> */ \\r
-/* 00000034 <ioffset>: */ \\r
-/* 34:*/ asm volatile (".word 0x00000020"); /* */ \\r
-/* 00000038 <stack>: */ \\r
-/* 38:*/ asm volatile (".word 0x000ffffc"); /* */ \\r
-/* 0000003c <deadbeef>: */ \\r
-/* 3c:*/ asm volatile (".word 0xdeadbeef"); /* */ \\r
-/* 00000040 <leetface>: */ \\r
-/* 40:*/ asm volatile (".word 0x1ee7face"); /* */ \\r
-/* 00000044 <area1>: */ \\r
-/* 44:*/ asm volatile (".word 0x00100019"); /* */ \\r
-/* 00000048 <realinit>: */ \\r
-/* our main code starts here... */ \\r
-/* 48:*/ asm volatile (".word 0xe3a0003f"); /* mov r0, #63 ; 0x3f */ \\r
-/* 4c:*/ asm volatile (".word 0xee060f10"); /* mcr 15, 0, r0, cr6, cr0, {0} */ \\r
-/* 50:*/ asm volatile (".word 0xee060f30"); /* mcr 15, 0, r0, cr6, cr0, {1} */ \\r
-/* 54:*/ asm volatile (".word 0xe51f0018"); /* ldr r0, [pc, #-24] ; 44 <area1> */ \\r
-/* 58:*/ asm volatile (".word 0xee060f11"); /* mcr 15, 0, r0, cr6, cr1, {0} */ \\r
-/* 5c:*/ asm volatile (".word 0xee060f31"); /* mcr 15, 0, r0, cr6, cr1, {1} */ \\r
-/* 60:*/ asm volatile (".word 0xe3a00001"); /* mov r0, #1 ; 0x1 */ \\r
-/* 64:*/ asm volatile (".word 0xee020f10"); /* mcr 15, 0, r0, cr2, cr0, {0} */ \\r
-/* 68:*/ asm volatile (".word 0xee020f30"); /* mcr 15, 0, r0, cr2, cr0, {1} */ \\r
-/* 6c:*/ asm volatile (".word 0xee030f10"); /* mcr 15, 0, r0, cr3, cr0, {0} */ \\r
-/* 70:*/ asm volatile (".word 0xe3a0000f"); /* mov r0, #15 ; 0xf */ \\r
-/* 74:*/ asm volatile (".word 0xee050f10"); /* mcr 15, 0, r0, cr5, cr0, {0} */ \\r
-/* 78:*/ asm volatile (".word 0xee050f30"); /* mcr 15, 0, r0, cr5, cr0, {1} */ \\r
-/* 7c:*/ asm volatile (".word 0xee110f10"); /* mrc 15, 0, r0, cr1, cr0, {0} */ \\r
-/* 80:*/ asm volatile (".word 0xe3800001"); /* orr r0, r0, #1 ; 0x1 */ \\r
-/* 84:*/ asm volatile (".word 0xe3800004"); /* orr r0, r0, #4 ; 0x4 */ \\r
-/* 88:*/ asm volatile (".word 0xe3800a01"); /* orr r0, r0, #4096 ; 0x1000 */ \\r
-/* 8c:*/ asm volatile (".word 0xe3800103"); /* orr r0, r0, #-1073741824 ; 0xc0000000 */ \\r
-/* 90:*/ asm volatile (".word 0xee010f10"); /* mcr 15, 0, r0, cr1, cr0, {0} */ \\r
- while(1) gp2x_2ndcore_run(gp2x_dequeue((gp2x_queue *)gp2x_2ndcore_data_ptr(GP2X_QUEUE_ARRAY_PTR))); \\r
-} \\r
-void gp2x_dualcore_launch_##name##_subprogram(void) { gp2x_dualcore_launch_program((unsigned long *)&gp2x_2ndcore_start, ((int)&gp2x_dualcore_launch_##name##_subprogram)-((int)&gp2x_2ndcore_start)); }\r
-\r
-#endif\r
-\r
-\r
#include <sys/time.h>
#include "main.h"
+#include "gp2x.h"
#include "throttle.h"
#if 0
#else
extern uint8 PAL;
-extern int FSkip, FSkip_setting;
+extern int FSkip;
static int usec_aim = 0, usec_done = 0;
static int skip_count = 0;
usec_done += tv_now.tv_usec - tv_prev.tv_usec;
#ifdef FRAMESKIP
- if (FSkip_setting >= 0)
+ if (Settings.frameskip >= 0)
{
- if (skip_count >= FSkip_setting)
+ if (skip_count >= Settings.frameskip)
skip_count = 0;
else {
skip_count++;
else if (usec_done > usec_aim + 1024*4)
{
/* auto frameskip */
- if (usec_done - usec_aim > 150000)
+ if (usec_done - usec_aim > 1024*32)
usec_done = usec_aim = 1; // too much behind, try to recover..
- FSkip = 1;
+ else
+ FSkip = 1;
tv_prev = tv_now;
return;
}
--- /dev/null
+/* Title: USB Joystick library
+ Version 0.2
+ Written by Puck2099 (puck2099@gmail.com), (c) 2006.
+ <http://www.gp32wip.com>
+
+ If you use this library or a part of it, please, let it know.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <stdlib.h>
+#include <stdio.h> /* For the definition of NULL */
+#include <sys/types.h> // For Device open
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h> // For Device read
+
+#include <string.h>
+#include <limits.h> /* For the definition of PATH_MAX */
+#include <linux/joystick.h>
+
+#include "usbjoy.h"
+
+
+/*
+ Function: joy_open
+
+ Opens a USB joystick and fills its information.
+
+ Parameters:
+
+ joynumber - Joystick's identifier (0 reserved for GP2X's builtin Joystick).
+
+ Returns:
+
+ Filled usbjoy structure.
+
+*/
+struct usbjoy *joy_open(int joynumber)
+{
+ int fd;
+ char path [128];
+ struct usbjoy * joy = NULL;
+ struct js_event event;
+ static char insmod_done = 0;
+
+ // notaz: on my system I get unresolved input_* symbols, so have to 'insmod input' too
+ // also we should insmod only once, not on every joy_open() call.
+ if (!insmod_done) {
+ system ("insmod input");
+ system ("insmod joydev"); // Loads joydev module
+ insmod_done = 1;
+ }
+
+ if (joynumber == 0) {
+ }
+ else if (joynumber > 0) {
+ sprintf (path, "/dev/input/js%d", joynumber-1);
+ fd = open(path, O_RDONLY, 0);
+ if (fd > 0) {
+ joy = (struct usbjoy *) malloc(sizeof(*joy));
+ if (joy == NULL) { close(fd); return NULL; }
+ memset(joy, 0, sizeof(*joy));
+
+ // Set the joystick to non-blocking read mode
+ fcntl(fd, F_SETFL, O_NONBLOCK);
+
+ // notaz: maybe we should flush init events now.
+ // My pad returns axis as active when I plug it in, which is kind of annoying.
+ while (read(fd, &event, sizeof(event)) > 0);
+
+ // Joystick's file descriptor
+ joy->fd = fd;
+
+ // Joystick's name
+ ioctl(joy->fd, JSIOCGNAME(128*sizeof(char)), joy->name);
+
+ // Joystick's device
+ strcpy(joy->device, path);
+
+ // Joystick's buttons
+ ioctl(joy->fd, JSIOCGBUTTONS, &joy->numbuttons);
+
+ // Joystick's axes
+ ioctl(joy->fd, JSIOCGAXES, &joy->numaxes);
+
+ // Joystick's type (derived from name)
+ if (strncasecmp(joy->name, "logitech", strlen("logitech")) == 0)
+ joy->type = JOY_TYPE_LOGITECH;
+ else joy->type = JOY_TYPE_GENERIC;
+ } else {
+ // printf ("ERROR: No Joystick found\n");
+ }
+ }
+ return joy;
+}
+
+/*
+ Function: joy_name
+
+ Returns Joystick's name.
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ Joystick's name or NULL if <usbjoy> struct is empty.
+*/
+char * joy_name (struct usbjoy * joy) {
+ if (joy != NULL) return joy->name;
+ else return NULL;
+}
+
+
+/*
+ Function: joy_device
+
+ Returns Joystick's device.
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ Joystick's device or NULL if <usbjoy> struct is empty.
+*/
+char * joy_device (struct usbjoy * joy) {
+ if (joy != NULL) return joy->device;
+ else return NULL;
+}
+
+
+/*
+ Function: joy_buttons
+
+ Returns Joystick's buttons number.
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ Joystick's buttons or 0 if <usbjoy> struct is empty.
+*/
+int joy_buttons (struct usbjoy * joy) {
+ if (joy != NULL) return joy->numbuttons;
+ else return 0;
+}
+
+
+/*
+ Function: joy_axes
+
+ Returns Joystick's axes number.
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ Joystick's axes or 0 if <usbjoy> struct is empty.
+*/
+int joy_axes (struct usbjoy * joy) {
+ if (joy != NULL) return joy->numaxes;
+ else return 0;
+}
+
+
+/*
+ Function: joy_update
+
+ Updates Joystick's internal information (<statebuttons> and <stateaxes> fields).
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ 0 - No events registered (no need to update).
+ 1 - Events registered (a button or axe has been pushed).
+ -1 - Error: <usbjoy> struct is empty.
+*/
+int joy_update (struct usbjoy * joy) {
+ struct js_event events[0xff];
+ int i, len;
+ int event = 0;
+ if (joy != NULL) {
+ if ((len=read(joy->fd, events, (sizeof events))) >0) {
+ len /= sizeof(events[0]);
+ for ( i=0; i<len; ++i ) {
+ switch (events[i].type & ~JS_EVENT_INIT) {
+ case JS_EVENT_AXIS:
+ if (events[i].number == 0) {
+ if (events[i].value == 0) joy->stateaxes[JOYLEFT] = joy->stateaxes[JOYRIGHT] = 0;
+ else if (events[i].value < 0) joy->stateaxes[JOYLEFT] = 1;
+ else joy->stateaxes[JOYRIGHT] = 1;
+ }
+ else if (events[i].number == 1) {
+ if (events[i].value == 0) joy->stateaxes[JOYUP] = joy->stateaxes[JOYDOWN] = 0;
+ else if (events[i].value < 0) joy->stateaxes[JOYUP] = 1;
+ else joy->stateaxes[JOYDOWN] = 1;
+ }
+ event = 1;
+ break;
+ case JS_EVENT_BUTTON:
+ joy->statebuttons[events[i].number] = events[i].value;
+ event = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ else {
+ event = -1;
+ }
+ return event;
+}
+
+
+/*
+ Function: joy_getbutton
+
+ Returns Joystick's button information.
+
+ Parameters:
+
+ button - Button which value you want to know (from 0 to 31).
+ joy - Selected joystick.
+
+ Returns:
+
+ 0 - Button NOT pushed.
+ 1 - Button pushed.
+ -1 - Error: <usbjoy> struct is empty.
+*/
+int joy_getbutton (int button, struct usbjoy * joy) {
+ if (joy != NULL) {
+ if (button < joy_buttons(joy)) return joy->statebuttons[button];
+ else return 0;
+ }
+ else return -1;
+}
+
+
+/*
+ Function: joy_getaxe
+
+ Returns Joystick's axes information.
+
+ Parameters:
+
+ axe - Axe which value you want to know (see <Axes values>).
+ joy - Selected joystick.
+
+ Returns:
+
+ 0 - Direction NOT pushed.
+ 1 - Direction pushed.
+ -1 - Error: <usbjoy> struct is empty.
+*/
+int joy_getaxe (int axe, struct usbjoy * joy) {
+ if (joy != NULL) {
+ if (axe < 4) return joy->stateaxes[axe];
+ else return 0;
+ }
+ else return -1;
+}
+
+
+/*
+ Function: joy_close
+
+ Closes selected joystick's file descriptor and detroys it's fields.
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ 0 - Joystick successfully closed.
+ -1 - Error: <usbjoy> struct is empty.
+*/
+int joy_close (struct usbjoy * joy) {
+ if (joy != NULL) {
+ close (joy->fd);
+ free (joy);
+ return 0;
+ }
+ else return -1;
+}
+
+
+/*********************************************************************/
+/* GP2X USB Joystick Handling -GnoStiC */
+/*********************************************************************/
+
+#include "minimal.h"
+
+int num_of_joys = 0;
+struct usbjoy *joys[4];
+
+void gp2x_usbjoy_init (void) {
+ /* Open available joysticks -GnoStiC */
+ int i, n = 0;
+
+ printf("\n");
+ for (i = 0; i < 4; i++) {
+ joys[n] = joy_open(i+1);
+ if (joys[n] && joy_buttons(joys[n]) > 0) {
+ printf ("+-Joystick %d: \"%s\", buttons = %i\n", i+1, joy_name(joys[n]), joy_buttons(joys[n]));
+ n++;
+ }
+ }
+ num_of_joys = n;
+
+ printf("Found %d Joystick(s)\n",num_of_joys);
+}
+
+void gp2x_usbjoy_update (void) {
+ /* Update Joystick Event Cache */
+ int q, foo;
+ for (q=0; q < num_of_joys; q++) {
+ foo = joy_update (joys[q]);
+ }
+}
+
+int gp2x_usbjoy_check (int joyno) {
+ /* Check Joystick */
+ int q, joyExKey = 0;
+ struct usbjoy *joy = joys[joyno];
+
+ if (joy != NULL) {
+ if (joy_getaxe(JOYUP, joy)) { joyExKey |= GP2X_UP; }
+ if (joy_getaxe(JOYDOWN, joy)) { joyExKey |= GP2X_DOWN; }
+ if (joy_getaxe(JOYLEFT, joy)) { joyExKey |= GP2X_LEFT; }
+ if (joy_getaxe(JOYRIGHT, joy)) { joyExKey |= GP2X_RIGHT; }
+
+ /* loop through joy buttons to check if they are pushed */
+ for (q=0; q<joy_buttons (joy); q++) {
+ if (joy_getbutton (q, joy)) {
+ if (joy->type == JOY_TYPE_LOGITECH) {
+ switch (q) {
+ case 0: joyExKey |= GP2X_A; break;
+ case 1: joyExKey |= GP2X_X; break;
+ case 2: joyExKey |= GP2X_B; break;
+ case 3: joyExKey |= GP2X_Y; break;
+ }
+ } else {
+ switch (q) {
+ case 0: joyExKey |= GP2X_Y; break;
+ case 1: joyExKey |= GP2X_B; break;
+ case 2: joyExKey |= GP2X_X; break;
+ case 3: joyExKey |= GP2X_A; break;
+ }
+ }
+
+ switch (q) {
+ case 4: joyExKey |= GP2X_L; break;
+ case 5: joyExKey |= GP2X_R; break;
+ case 6: joyExKey |= GP2X_L; break; /* left shoulder button 2 */
+ case 7: joyExKey |= GP2X_R; break; /* right shoulder button 2 */
+ case 8: joyExKey |= GP2X_SELECT;break;
+ case 9: joyExKey |= GP2X_START; break;
+ case 10: joyExKey |= GP2X_PUSH; break;
+ case 11: joyExKey |= GP2X_PUSH; break;
+ }
+ }
+ }
+ }
+ return joyExKey;
+}
+
+int gp2x_usbjoy_check2 (int joyno) {
+ /* Check Joystick, don't map to gp2x joy */
+ int q, to, joyExKey = 0;
+ struct usbjoy *joy = joys[joyno];
+
+ if (joy != NULL) {
+ if (joy_getaxe(JOYUP, joy)) { joyExKey |= 1 << 0; }
+ if (joy_getaxe(JOYDOWN, joy)) { joyExKey |= 1 << 1; }
+ if (joy_getaxe(JOYLEFT, joy)) { joyExKey |= 1 << 2; }
+ if (joy_getaxe(JOYRIGHT, joy)) { joyExKey |= 1 << 3; }
+
+ /* loop through joy buttons to check if they are pushed */
+ to = joy->numbuttons;
+ if (to > 32-4) to = 32-4;
+ for (q=0; q < to; q++)
+ if (joy->statebuttons[q]) joyExKey |= 1 << (q+4);
+ }
+ return joyExKey;
+}
+
+
+
+void gp2x_usbjoy_deinit (void) {
+ int i;
+ for (i=0; i<num_of_joys; i++) {
+ joy_close (joys[i]);
+ }
+ num_of_joys = 0;
+}
+
--- /dev/null
+/* Title: USB Joystick library
+ Version 0.2
+ Written by Puck2099 (puck2099@gmail.com), (c) 2006.
+ <http://www.gp32wip.com>
+
+ If you use this library or a part of it, please, let it know.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef USBJOY_H
+#define USBJOY_H
+
+/* notaz: my Logitech has different button layout, and I want it to match gp2x's */
+typedef enum {
+ JOY_TYPE_GENERIC,
+ JOY_TYPE_LOGITECH
+} joy_type;
+
+/*
+ Enumeration: Axes values
+ This enumeration contains shortcuts to the values used on axes.
+
+ Constants:
+ JOYUP - Joystick Up
+ JOYDOWN - Joystick Down
+ JOYLEFT - Joystick Left
+ JOYRIGHT - Joystick Right
+
+ See also:
+ <joy_getaxe>
+*/
+#define JOYUP (0)
+#define JOYDOWN (1)
+#define JOYLEFT (2)
+#define JOYRIGHT (3)
+
+
+/*
+ Struct: usbjoy
+
+ Contains all Joystick needed information.
+
+ Fields:
+ fd - File descriptor used.
+ name - Joystick's name.
+ device - /dev/input/jsX device.
+ numbuttons - Joystick's buttons.
+ numaxes - Joystick's axes.
+ numhats - Joystick's hats.
+ statebuttons - Current state of each button.
+ stateaxes - Current state of each direction.
+*/
+struct usbjoy {
+ int fd;
+ char name [128];
+ char device [128];
+ int numbuttons;
+ int numaxes;
+ int numhats;
+ int statebuttons[32];
+ int stateaxes[4];
+ joy_type type;
+};
+
+
+/*
+ Function: joy_open
+
+ Opens a USB joystick and fills its information.
+
+ Parameters:
+
+ joynumber - Joystick's identifier (0 reserved for GP2X's builtin Joystick).
+
+ Returns:
+
+ Filled usbjoy structure.
+*/
+struct usbjoy * joy_open (int joynumber);
+
+
+/*
+ Function: joy_name
+
+ Returns Joystick's name.
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ Joystick's name or NULL if <usbjoy> struct is empty.
+*/
+char * joy_name (struct usbjoy * joy);
+
+
+/*
+ Function: joy_device
+
+ Returns Joystick's device.
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ Joystick's device or NULL if <usbjoy> struct is empty.
+*/
+char * joy_device (struct usbjoy * joy);
+
+/*
+ Function: joy_buttons
+
+ Returns Joystick's buttons number.
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ Joystick's buttons or 0 if <usbjoy> struct is empty.
+*/
+int joy_buttons (struct usbjoy * joy);
+
+/*
+ Function: joy_axes
+
+ Returns Joystick's axes number.
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ Joystick's axes or 0 if <usbjoy> struct is empty.
+*/
+int joy_axes (struct usbjoy * joy);
+
+
+/*
+ Function: joy_update
+
+ Updates Joystick's internal information (<statebuttons> and <stateaxes> fields).
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ 0 - No events registered (no need to update).
+ 1 - Events registered (a button or axe has been pushed).
+ -1 - Error: <usbjoy> struct is empty.
+*/
+int joy_update (struct usbjoy * joy);
+
+
+/*
+ Function: joy_getbutton
+
+ Returns Joystick's button information.
+
+ Parameters:
+
+ button - Button which value you want to know (from 0 to 31).
+ joy - Selected joystick.
+
+ Returns:
+
+ 0 - Button NOT pushed.
+ 1 - Button pushed.
+ -1 - Error: <usbjoy> struct is empty.
+*/
+int joy_getbutton (int button, struct usbjoy * joy);
+
+
+/*
+ Function: joy_getaxe
+
+ Returns Joystick's axes information.
+
+ Parameters:
+
+ axe - Axe which value you want to know (see <Axes values>).
+ joy - Selected joystick.
+
+ Returns:
+
+ 0 - Direction NOT pushed.
+ 1 - Direction pushed.
+ -1 - Error: <usbjoy> struct is empty.
+*/
+int joy_getaxe (int axe, struct usbjoy * joy);
+
+/*
+ Function: joy_close
+
+ Closes selected joystick's file descriptor and detroys it's fields.
+
+ Parameters:
+
+ joy - Selected joystick.
+
+ Returns:
+
+ 0 - Joystick successfully closed.
+ -1 - Error: <usbjoy> struct is empty.
+*/
+int joy_close (struct usbjoy * joy);
+
+
+
+/* gp2x stuff */
+extern int num_of_joys;
+extern struct usbjoy *joys[4];
+
+void gp2x_usbjoy_update(void);
+void gp2x_usbjoy_init(void);
+int gp2x_usbjoy_check(int joyno);
+int gp2x_usbjoy_check2(int joyno);
+void gp2x_usbjoy_deinit(void);
+
+
+#endif // USBJOY_H
int have_movie = 0;
int fp;
- Exit=1;
+ //Exit=1;
ResetGameLoaded();
strncpy(name2, name, sizeof(name2));
FCEU_fclose(fp);
*p = 0;
fp=FCEU_fopen(name2,"rb");
+ if (!fp && p - name2 > 2) p[-2] = 0;
+ fp=FCEU_fopen(name2,"rb");
if (!fp) {
printf("no ROM for movie\n");
return 0;
if(Exit)
{
- CloseGame();
+ //CloseGame();
break;
}