--- /dev/null
+CROSS =
+CC = $(CROSS)gcc
+STRIP = $(CROSS)strip
+AS = $(CROSS)as
+TFLAGS = -Winline -Izlib -DGP2X=1 -DLSB_FIRST -DUNIX -DPSS_STYLE=1 -DHAVE_ASPRINTF -DZLIB -DFRAMESKIP -D_REENTRANT `sdl-config --cflags` -DSDL
+RM = rm -f
+B = drivers/cli/
+ifdef DEBUG
+TFLAGS += -ggdb
+LDRIVER += -ggdb
+else
+TFLAGS += -ftracer -fstrength-reduce -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math
+TFLAGS += -O3 # -pg
+LDRIVER += -O3 # -pg
+endif
+
+all: fceu
+
+include zlib/Makefile
+
+OBJDRIVER = ${B}sdl.o ${B}main.o ${B}throttle.o ${B}unix-netplay.o ${B}sdl-sound.o ${B}sdl-video.o ${B}sdl-joystick.o drivers/common/cheat.o drivers/common/config.o drivers/common/args.o drivers/common/vidblit.o ${UNZIPOBJS} ppu.o movie.o
+LDRIVER = -lm `sdl-config --libs` -lz
+
+
+OBJDRIVER += x6502.o
+
+x6502.o: x6502.c x6502.h ops.h fce.h sound.h
+
+ncpu.o: ncpu.S ncpu.h
+ $(CC) $(TFLAGS) -c $< -o $@
+
+include Makefile.base
+
+${B}sdl-joystick.o: ${B}sdl-joystick.c
+${B}main.o: ${B}main.c ${B}main.h ${B}usage.h ${B}input.c ${B}keyscan.h
+${B}sdl.o: ${B}sdl.c ${B}sdl.h
+${B}sdl-video.o: ${B}sdl-video.c
+${B}sdl-sound.o: ${B}sdl-sound.c
+#${B}sdl-netplay.o: ${B}sdl-netplay.c
+${B}unix-netplay.o: ${B}unix-netplay.c
+${B}throttle.o: ${B}throttle.c ${B}main.h ${B}throttle.h
+
+ppu.o: ppu.c ppu.h
+
+include Makefile.common
+
--- /dev/null
+extern CFGSTRUCT DriverConfig[];
+extern ARGPSTRUCT DriverArgs[];
+extern char *DriverUsage;
+
+void DoDriverArgs(void);
+void GetBaseDirectory(char *BaseDirectory);
+
+int InitSound(void);
+void WriteSound(int16 *Buffer, int Count, int NoWaiting);
+void KillSound(void);
+void SilenceSound(int s); /* DOS and SDL */
+
+
+int InitMouse(void);
+void KillMouse(void);
+void GetMouseData(uint32 *MouseData);
+
+int InitJoysticks(void);
+void KillJoysticks(void);
+uint32 *GetJSOr(void);
+
+int InitKeyboard(void);
+int UpdateKeyboard(void);
+char *GetKeyboard(void);
+void KillKeyboard(void);
+
+int InitVideo(void);
+void KillVideo(void);
+void BlitScreen(uint8 *XBuf);
+void LockConsole(void);
+void UnlockConsole(void);
+void ToggleFS(); /* SDL */
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <dpmi.h>
+#include <sys/farptr.h>
+#include <go32.h>
+#include <pc.h>
+
+#include "dos.h"
+#include "dos-joystick.h"
+
+#define JOY_A 1
+#define JOY_B 2
+#define JOY_SELECT 4
+#define JOY_START 8
+#define JOY_UP 0x10
+#define JOY_DOWN 0x20
+#define JOY_LEFT 0x40
+#define JOY_RIGHT 0x80
+
+int joy=0;
+int joyBMap[4];
+
+static int32 joybuttons=0;
+static uint32 joyx=0;
+static uint32 joyy=0;
+static uint32 joyxcenter;
+static uint32 joyycenter;
+
+static void ConfigJoystick(void);
+volatile int soundjoyer=0;
+volatile int soundjoyeron=0;
+
+/* Crude method to detect joystick. */
+static int DetectJoystick(void)
+{
+ uint8 b;
+
+ outportb(0x201,0);
+ b=inportb(0x201);
+ sleep(1);
+ if((inportb(0x201)&3)==(b&3))
+ return 0;
+ else
+ return 1;
+}
+
+void UpdateJoyData(void)
+{
+ uint32 xc,yc;
+
+
+ joybuttons=((inportb(0x201)&0xF0)^0xF0)>>4;
+
+ xc=yc=0;
+
+ {
+ outportb(0x201,0);
+
+ for(;;)
+ {
+ uint8 b;
+
+ b=inportb(0x201);
+ if(!(b&3))
+ break;
+ if(b&1) xc++;
+ if(b&2) yc++;
+ }
+ }
+
+ joyx=xc;
+ joyy=yc;
+}
+
+uint32 GetJSOr(void)
+{
+ int y;
+ unsigned long ret;
+ ret=0;
+
+ if(!soundo)
+ UpdateJoyData();
+ for(y=0;y<4;y++)
+ if(joybuttons&joyBMap[y]) ret|=(1<<y)<<((joy-1)<<3);
+
+ if(joyx<=joyxcenter*.25) ret|=JOY_LEFT<<((joy-1)<<3);
+ else if(joyx>=joyxcenter*1.75) ret|=JOY_RIGHT<<((joy-1)<<3);
+ if(joyy<=joyycenter*.25) ret|=JOY_UP<<((joy-1)<<3);
+ else if(joyy>=joyycenter*1.75) ret|=JOY_DOWN<<((joy-1)<<3);
+
+ return ret;
+}
+
+int InitJoysticks(void)
+{
+ if(!joy) return(0);
+ if(!DetectJoystick())
+ {
+ printf("Joystick not detected!\n");
+ joy=0;
+ return 0;
+ }
+ if(soundo)
+ {
+ soundjoyeron=1;
+ while(!soundjoyer);
+ }
+ else
+ UpdateJoyData();
+
+ joyxcenter=joyx;
+ joyycenter=joyy;
+
+ if(!(joyBMap[0]|joyBMap[1]|joyBMap[2]|joyBMap[3]))
+ ConfigJoystick();
+ return(1);
+}
+
+static void BConfig(int b)
+{
+ int c=0;
+ uint32 st=time(0);
+
+ while(time(0)< (st+4) )
+ {
+ if(!soundo)
+ UpdateJoyData();
+ if(joybuttons) c=joybuttons;
+ else if(c && !joybuttons)
+ {
+ joyBMap[b]=c;
+ break;
+ }
+
+ }
+}
+
+void KillJoysticks(void)
+{
+
+}
+
+static void ConfigJoystick(void)
+{
+ static char *genb="** Press button for ";
+
+ printf("\n\n Joystick button configuration:\n\n");
+ printf(" Push and release the button to map to the virtual joystick.\n");
+ printf(" If you do not wish to assign a button, wait a few seconds\n");
+ printf(" and the configuration will continue.\n\n");
+ printf(" Press enter to continue...\n");
+ getchar();
+
+ printf("%s\"Select\".\n",genb);
+ BConfig(2);
+
+ printf("%s\"Start\".\n",genb);
+ BConfig(3);
+
+ printf("%s\"B\".\n",genb);
+ BConfig(1);
+
+ printf("%s\"A\".\n",genb);
+ BConfig(0);
+}
+
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator\r
+ *\r
+ * Copyright notice for this file:\r
+ * Copyright (C) 2002 Ben Parnell\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+void UpdateJoyData(void);\r
+uint32 GetJSOr(void);\r
+int InitJoysticks(void);\r
+\r
+/* Variables to save in config file. */\r
+extern int joy;\r
+extern int joyBMap[4];\r
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator\r
+ *\r
+ * Copyright notice for this file:\r
+ * Copyright (C) 2002 Ben Parnell\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <signal.h>\r
+#include <string.h>\r
+#include <pc.h>\r
+#include <dpmi.h>\r
+#include <go32.h>\r
+#include "keyscan.h"\r
+\r
+static unsigned char lastsc;\r
+static char keybuf[256];\r
+int newk;\r
+\r
+/* Read scan code from port $60 */\r
+/* Acknowledge interrupt( output $20 to port $20) */\r
+\r
+static void ihandler(_go32_dpmi_registers *r)\r
+{\r
+ unsigned char scode=inp(0x60); /* Get scan code. */\r
+\r
+\r
+ if(scode!=0xE0)\r
+ {\r
+ int offs=0;\r
+\r
+ /* I'm only interested in preserving the independent status of the\r
+ right ALT and CONTROL keys.\r
+ */\r
+ if(lastsc==0xE0)\r
+ if((scode&0x7F)==SCAN_LEFTALT || (scode&0x7F)==SCAN_LEFTCONTROL)\r
+ offs=0x80;\r
+ \r
+\r
+ keybuf[(scode&0x7f)|offs]=((scode&0x80)^0x80);\r
+ newk++;\r
+ }\r
+ lastsc=scode;\r
+\r
+ outp(0x20,0x20); /* Acknowledge interrupt. */\r
+}\r
+\r
+static _go32_dpmi_seginfo KBIBack,KBIBackRM;\r
+static _go32_dpmi_seginfo KBI,KBIRM;\r
+static _go32_dpmi_registers KBIRMRegs;\r
+static int initdone=0;\r
+\r
+int InitKeyboard(void)\r
+{\r
+ /* I'll assume that the keyboard is in the correct scancode mode(translated\r
+ mode 2, I think).\r
+ */\r
+ newk=0;\r
+ memset(keybuf,0,sizeof(keybuf));\r
+ KBIRM.pm_offset=KBI.pm_offset=(int)ihandler;\r
+ KBIRM.pm_selector=KBI.pm_selector=_my_cs();\r
+\r
+ _go32_dpmi_get_real_mode_interrupt_vector(9,&KBIBackRM);\r
+ _go32_dpmi_allocate_real_mode_callback_iret(&KBIRM, &KBIRMRegs);\r
+ _go32_dpmi_set_real_mode_interrupt_vector(9,&KBIRM);\r
+\r
+ _go32_dpmi_get_protected_mode_interrupt_vector(9,&KBIBack);\r
+ _go32_dpmi_allocate_iret_wrapper(&KBI);\r
+ _go32_dpmi_set_protected_mode_interrupt_vector(9,&KBI);\r
+ lastsc=0;\r
+ initdone=1;\r
+ return(1);\r
+}\r
+\r
+void KillKeyboard(void)\r
+{\r
+ if(initdone)\r
+ {\r
+ _go32_dpmi_set_protected_mode_interrupt_vector(9,&KBIBack);\r
+ _go32_dpmi_free_iret_wrapper(&KBI);\r
+\r
+ _go32_dpmi_set_real_mode_interrupt_vector(9,&KBIBackRM);\r
+ _go32_dpmi_free_real_mode_callback(&KBIRM);\r
+ initdone=0;\r
+ }\r
+}\r
+\r
+/* In FCE Ultra, it doesn't matter if the key states change\r
+ in the middle of the keyboard handling code. If you want\r
+ to use this code elsewhere, you may want to memcpy() keybuf\r
+ to another buffer and return that when GetKeyboard() is\r
+ called.\r
+*/\r
+\r
+char *GetKeyboard(void)\r
+{\r
+ return keybuf;\r
+}\r
+\r
+/* Returns 1 on new scan codes generated, 0 on no new scan codes. */\r
+int UpdateKeyboard(void)\r
+{\r
+ int t=newk;\r
+\r
+ if(t)\r
+ {\r
+ asm volatile(\r
+ "subl %%eax,_newk\n\t"\r
+ :\r
+ : "a" (t)\r
+ );\r
+\r
+ if(keybuf[SCAN_LEFTCONTROL] && keybuf[SCAN_C])\r
+ raise(SIGINT);\r
+ return(1);\r
+ }\r
+ return(0);\r
+}\r
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator\r
+ *\r
+ * Copyright notice for this file:\r
+ * Copyright (C) 2002 Ben Parnell\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+#include <dpmi.h>\r
+#include <string.h>\r
+\r
+#include "dos.h"\r
+\r
+int InitMouse(void)\r
+{\r
+ __dpmi_regs regs;\r
+\r
+ memset(®s,0,sizeof(regs));\r
+ regs.x.ax=0;\r
+ __dpmi_int(0x33,®s);\r
+ if(regs.x.ax!=0xFFFF)\r
+ return(0);\r
+\r
+ memset(®s,0,sizeof(regs));\r
+ regs.x.ax=0x7;\r
+ regs.x.cx=0; // Min X\r
+ regs.x.dx=260; // Max X\r
+ __dpmi_int(0x33,®s);\r
+\r
+ memset(®s,0,sizeof(regs));\r
+ regs.x.ax=0x8;\r
+ regs.x.cx=0; // Min Y\r
+ regs.x.dx=260; // Max Y\r
+ __dpmi_int(0x33,®s);\r
+\r
+ memset(®s,0,sizeof(regs));\r
+ regs.x.ax=0xF;\r
+ regs.x.cx=8; // Mickey X\r
+ regs.x.dx=8; // Mickey Y\r
+ __dpmi_int(0x33,®s);\r
+\r
+ memset(®s,0,sizeof(regs));\r
+ regs.x.ax=0x2;\r
+ __dpmi_int(0x33,®s);\r
+\r
+ return(1);\r
+}\r
+\r
+uint32 GetMouseData(uint32 *x, uint32 *y)\r
+{\r
+ __dpmi_regs regs;\r
+\r
+ memset(®s,0,sizeof(regs));\r
+ regs.x.ax=0x3;\r
+ __dpmi_int(0x33,®s);\r
+\r
+ *x=regs.x.cx;\r
+ *y=regs.x.dx;\r
+ return(regs.x.bx&3);\r
+}\r
+\r
+void KillMouse(void)\r
+{\r
+\r
+}\r
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator\r
+ *\r
+ * Copyright notice for this file:\r
+ * Copyright (C) 2002 Ben Parnell\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <sys/farptr.h>\r
+#include <pc.h>\r
+#include <dos.h>\r
+#include <dpmi.h>\r
+#include <go32.h>\r
+#include <ctype.h>\r
+\r
+#include "dos.h"\r
+#include "dos-sound.h"\r
+#include "dos-joystick.h"\r
+\r
+\r
+static void SBIRQHandler(_go32_dpmi_registers *r);\r
+static uint32 LMBuffer; /* Address of low memory DMA playback buffer. */\r
+static int LMSelector;\r
+\r
+static uint8 *WaveBuffer;\r
+static unsigned int IVector, SBIRQ, SBDMA, SBDMA16, SBPort;\r
+static int DSPV,hsmode;\r
+static int format;\r
+static int frags, fragsize, fragtotal;\r
+static volatile int WritePtr, ReadPtr;\r
+static volatile int hbusy;\r
+static volatile int whichbuf;\r
+\r
+\r
+static uint8 PICMask;\r
+/* Protected mode interrupt vector info. */\r
+static _go32_dpmi_seginfo SBIH,SBIHOld;\r
+\r
+/* Real mode interrupt vector info. */\r
+static _go32_dpmi_seginfo SBIHRM,SBIHRMOld;\r
+static _go32_dpmi_registers SBIHRMRegs;\r
+\r
+static int WriteDSP(uint8 V)\r
+{\r
+ int x;\r
+\r
+ for(x=65536;x;x--)\r
+ {\r
+ if(!(inportb(SBPort+0xC)&0x80))\r
+ {\r
+ outportb(SBPort+0xC,V);\r
+ return(1);\r
+ }\r
+ }\r
+ return(0);\r
+}\r
+\r
+static int ReadDSP(uint8 *V)\r
+{\r
+ int x;\r
+\r
+ for(x=65536;x;x--) /* Should be more than enough time... */\r
+ {\r
+ if(inportb(SBPort+0xE)&0x80)\r
+ {\r
+ *V=inportb(SBPort+0xA);\r
+ return(1);\r
+ }\r
+ }\r
+ return(0);\r
+}\r
+\r
+\r
+static int SetVectors(void)\r
+{\r
+ SBIH.pm_offset=SBIHRM.pm_offset=(int)SBIRQHandler;\r
+ SBIH.pm_selector=SBIHRM.pm_selector=_my_cs();\r
+\r
+ /* Get and set real mode interrupt vector. */\r
+ _go32_dpmi_get_real_mode_interrupt_vector(IVector,&SBIHRMOld);\r
+ _go32_dpmi_allocate_real_mode_callback_iret(&SBIHRM, &SBIHRMRegs);\r
+ _go32_dpmi_set_real_mode_interrupt_vector(IVector,&SBIHRM); \r
+\r
+ /* Get and set protected mode interrupt vector. */\r
+ _go32_dpmi_get_protected_mode_interrupt_vector(IVector,&SBIHOld);\r
+ _go32_dpmi_allocate_iret_wrapper(&SBIH);\r
+ _go32_dpmi_set_protected_mode_interrupt_vector(IVector,&SBIH); \r
+\r
+ return(1);\r
+}\r
+\r
+static void ResetVectors(void)\r
+{\r
+ _go32_dpmi_set_protected_mode_interrupt_vector(IVector,&SBIHOld);\r
+ _go32_dpmi_free_iret_wrapper(&SBIH);\r
+ _go32_dpmi_set_real_mode_interrupt_vector(IVector,&SBIHRMOld);\r
+ _go32_dpmi_free_real_mode_callback(&SBIHRM);\r
+}\r
+\r
+int GetBLASTER(void)\r
+{\r
+ int check=0;\r
+ char *s;\r
+\r
+ if(!(s=getenv("BLASTER")))\r
+ {\r
+ puts(" Error getting BLASTER environment variable.");\r
+ return(0);\r
+ }\r
+\r
+ while(*s)\r
+ {\r
+ switch(toupper(*s))\r
+ {\r
+ case 'A': check|=(sscanf(s+1,"%x",&SBPort)==1)?1:0;break;\r
+ case 'I': check|=(sscanf(s+1,"%d",&SBIRQ)==1)?2:0;break;\r
+ case 'D': check|=(sscanf(s+1,"%d",&SBDMA)==1)?4:0;break;\r
+ case 'H': check|=(sscanf(s+1,"%d",&SBDMA16)==1)?8:0;break;\r
+ }\r
+ s++;\r
+ }\r
+ \r
+ if((check^7)&7 || SBDMA>=4 || (SBDMA16<=4 && check&8) || SBIRQ>15)\r
+ {\r
+ puts(" Invalid or incomplete BLASTER environment variable.");\r
+ return(0);\r
+ }\r
+ if(!(check&8))\r
+ format=0;\r
+ return(1);\r
+}\r
+\r
+static int ResetDSP(void)\r
+{\r
+ uint8 b;\r
+\r
+ outportb(SBPort+0x6,0x1);\r
+ delay(10);\r
+ outportb(SBPort+0x6,0x0);\r
+ delay(10);\r
+\r
+ if(ReadDSP(&b))\r
+ if(b==0xAA)\r
+ return(1); \r
+ return(0);\r
+}\r
+\r
+static int GetDSPVersion(void)\r
+{\r
+ int ret;\r
+ uint8 t;\r
+\r
+ if(!WriteDSP(0xE1))\r
+ return(0);\r
+ if(!ReadDSP(&t))\r
+ return(0);\r
+ ret=t<<8;\r
+ if(!ReadDSP(&t))\r
+ return(0);\r
+ ret|=t;\r
+\r
+ return(ret);\r
+}\r
+\r
+static void KillDMABuffer(void)\r
+{\r
+ __dpmi_free_dos_memory(LMSelector);\r
+}\r
+\r
+static int MakeDMABuffer(void)\r
+{\r
+ uint32 size;\r
+ int32 tmp;\r
+\r
+ size=fragsize*2; /* Two buffers in the DMA buffer. */\r
+ size<<=format; /* Twice the size for 16-bit than for 8-bit. */\r
+\r
+ size<<=1; /* Double the size in case the first 2 buffers\r
+ cross a 64KB or 128KB page boundary.\r
+ */\r
+ size=(size+15)>>4; /* Convert to paragraphs */\r
+\r
+ if((tmp=__dpmi_allocate_dos_memory(size,&LMSelector))<0)\r
+ return(0);\r
+\r
+ LMBuffer=tmp<<=4;\r
+\r
+ if(format) /* Check for and fix 128KB page boundary crossing. */\r
+ {\r
+ if((LMBuffer&0x20000) != ((LMBuffer+fragsize*2*2-1)&0x20000))\r
+ LMBuffer+=fragsize*2*2;\r
+ }\r
+ else /* Check for and fix 64KB page boundary crossing. */\r
+ {\r
+ if((LMBuffer&0x10000) != ((LMBuffer+fragsize*2-1)&0x10000))\r
+ LMBuffer+=fragsize*2;\r
+ }\r
+\r
+ DOSMemSet(LMBuffer, format?0:128, (fragsize*2)<<format);\r
+\r
+ return(1);\r
+}\r
+\r
+static void ProgramDMA(void)\r
+{\r
+ static int PPorts[8]={0x87,0x83,0x81,0x82,0,0x8b,0x89,0x8a};\r
+ uint32 tmp;\r
+\r
+ if(format)\r
+ {\r
+ outportb(0xd4,(SBDMA16&0x3)|0x4);\r
+ outportb(0xd8,0x0);\r
+ outportb(0xd6,(SBDMA16&0x3)|0x58);\r
+ tmp=((SBDMA16&3)<<2)+0xC2;\r
+ }\r
+ else\r
+ {\r
+ outportb(0xA,SBDMA|0x4);\r
+ outportb(0xC,0x0);\r
+ outportb(0xB,SBDMA|0x58);\r
+ tmp=(SBDMA<<1)+1;\r
+ }\r
+\r
+ /* Size of entire buffer. */\r
+ outportb(tmp,(fragsize*2-1));\r
+ outportb(tmp,(fragsize*2-1)>>8);\r
+\r
+ /* Page of buffer. */\r
+ outportb(PPorts[format?SBDMA16:SBDMA],LMBuffer>>16);\r
+\r
+ /* Offset of buffer within page. */\r
+ if(format)\r
+ tmp=((SBDMA16&3)<<2)+0xc0;\r
+ else\r
+ tmp=SBDMA<<1;\r
+\r
+ outportb(tmp,(LMBuffer>>format));\r
+ outportb(tmp,(LMBuffer>>(8+format)));\r
+}\r
+\r
+int InitSB(int Rate, int bittage)\r
+{\r
+ hsmode=hbusy=0;\r
+ whichbuf=1;\r
+ puts("Initializing Sound Blaster...");\r
+\r
+ format=bittage?1:0;\r
+ frags=8;\r
+\r
+ if(Rate<=11025)\r
+ fragsize=1<<5;\r
+ else if(Rate<=22050)\r
+ fragsize=1<<6;\r
+ else\r
+ fragsize=1<<7;\r
+\r
+ fragtotal=frags*fragsize;\r
+ WaveBuffer=malloc(fragtotal<<format);\r
+\r
+ if(format)\r
+ memset(WaveBuffer,0,fragtotal*2);\r
+ else\r
+ memset(WaveBuffer,128,fragtotal);\r
+\r
+ WritePtr=ReadPtr=0;\r
+\r
+ if((Rate<8192) || (Rate>65535))\r
+ {\r
+ printf(" Unsupported playback rate: %d samples per second\n",Rate);\r
+ return(0);\r
+ }\r
+\r
+ if(!GetBLASTER())\r
+ return(0);\r
+ \r
+ /* Disable IRQ line in PIC0 or PIC1 */\r
+ if(SBIRQ>7)\r
+ {\r
+ PICMask=inportb(0xA1);\r
+ outportb(0xA1,PICMask|(1<<(SBIRQ&7)));\r
+ }\r
+ else\r
+ {\r
+ PICMask=inportb(0x21);\r
+ outportb(0x21,PICMask|(1<<SBIRQ));\r
+ }\r
+ if(!ResetDSP())\r
+ {\r
+ puts(" Error resetting the DSP.");\r
+ return(0);\r
+ }\r
+ \r
+ if(!(DSPV=GetDSPVersion()))\r
+ {\r
+ puts(" Error getting the DSP version.");\r
+ return(0);\r
+ }\r
+\r
+ printf(" DSP Version: %d.%d\n",DSPV>>8,DSPV&0xFF);\r
+ if(DSPV<0x201)\r
+ {\r
+ printf(" DSP version number is too low.\n");\r
+ return(0);\r
+ }\r
+\r
+ if(DSPV<0x400)\r
+ format=0;\r
+ if(!MakeDMABuffer())\r
+ {\r
+ puts(" Error creating low-memory DMA buffer.");\r
+ return(0);\r
+ }\r
+\r
+ if(SBIRQ>7) IVector=SBIRQ+0x68;\r
+ else IVector=SBIRQ+0x8;\r
+\r
+ if(!SetVectors())\r
+ {\r
+ puts(" Error setting interrupt vectors.");\r
+ KillDMABuffer();\r
+ return(0);\r
+ }\r
+\r
+ /* Reenable IRQ line. */\r
+ if(SBIRQ>7)\r
+ outportb(0xA1,PICMask&(~(1<<(SBIRQ&7))));\r
+ else\r
+ outportb(0x21,PICMask&(~(1<<SBIRQ)));\r
+\r
+ ProgramDMA();\r
+\r
+ /* Note that the speaker must always be turned on before the mode transfer\r
+ byte is sent to the DSP if we're going into high-speed mode, since\r
+ a real Sound Blaster(at least my SBPro) won't accept DSP commands(except\r
+ for the reset "command") after it goes into high-speed mode.\r
+ */\r
+ WriteDSP(0xD1); // Turn on DAC speaker\r
+\r
+ if(DSPV>=0x400)\r
+ {\r
+ WriteDSP(0x41); // Set sampling rate\r
+ WriteDSP(Rate>>8); // High byte\r
+ WriteDSP(Rate&0xFF); // Low byte\r
+ if(!format)\r
+ {\r
+ WriteDSP(0xC6); // 8-bit output\r
+ WriteDSP(0x00); // 8-bit mono unsigned PCM\r
+ }\r
+ else\r
+ {\r
+ WriteDSP(0xB6); // 16-bit output\r
+ WriteDSP(0x10); // 16-bit mono signed PCM\r
+ }\r
+ WriteDSP((fragsize-1)&0xFF);// Low byte of size\r
+ WriteDSP((fragsize-1)>>8); // High byte of size\r
+ }\r
+ else\r
+ {\r
+ int tc,command;\r
+ if(Rate>22050)\r
+ {\r
+ tc=(65536-(256000000/Rate))>>8;\r
+ Rate=256000000/(65536-(tc<<8));\r
+ command=0x90; // High-speed auto-initialize DMA mode transfer\r
+ hsmode=1;\r
+ }\r
+ else\r
+ {\r
+ tc=256-(1000000/Rate);\r
+ Rate=1000000/(256-tc);\r
+ command=0x1c; // Auto-initialize DMA mode transfer\r
+ }\r
+ WriteDSP(0x40); // Set DSP time constant\r
+ WriteDSP(tc); // time constant\r
+ WriteDSP(0x48); // Set DSP block transfer size\r
+ WriteDSP((fragsize-1)&0xFF);\r
+ WriteDSP((fragsize-1)>>8);\r
+\r
+ WriteDSP(command);\r
+ }\r
+\r
+ /* Enable DMA */\r
+ if(format)\r
+ outportb(0xd4,SBDMA16&3);\r
+ else\r
+ outportb(0xa,SBDMA);\r
+\r
+ printf(" %d hz, %d-bit\n",Rate,8<<format);\r
+ return(Rate);\r
+}\r
+\r
+extern volatile int soundjoyer;\r
+extern volatile int soundjoyeron;\r
+static int ssilence=0;\r
+\r
+static void SBIRQHandler(_go32_dpmi_registers *r)\r
+{\r
+ uint32 *src;\r
+ uint32 dest;\r
+ int32 x;\r
+\r
+\r
+ if(format)\r
+ {\r
+ uint8 status;\r
+\r
+ outportb(SBPort+4,0x82);\r
+ status=inportb(SBPort+5);\r
+ if(status&2)\r
+ inportb(SBPort+0x0F);\r
+ }\r
+ else\r
+ inportb(SBPort+0x0E);\r
+\r
+ #ifdef OLD\r
+ {\r
+ uint8 status;\r
+\r
+ outportb(SBPort+4,0x82);\r
+ status=inportb(SBPort+5);\r
+ if(status&1)\r
+ inportb(SBPort+0x0E);\r
+ else if(status&2)\r
+ inportb(SBPort+0x0F);\r
+ else\r
+ return; // Mysterious interrupt source! *eerie music*\r
+ } \r
+ #endif\r
+\r
+ if(hbusy)\r
+ {\r
+ outportb(0x20,0x20);\r
+ if(SBIRQ>=8)\r
+ outportb(0xA0,0x20);\r
+ whichbuf^=1; \r
+ return;\r
+ }\r
+ hbusy=1;\r
+\r
+ {\r
+ /* This code seems to fail on many SB emulators. Bah.\r
+ SCREW SB EMULATORS. ^_^ */\r
+ uint32 count;\r
+ uint32 block;\r
+ uint32 port;\r
+ \r
+ if(format)\r
+ port=((SBDMA16&3)*4)+0xc2;\r
+ else\r
+ port=(SBDMA*2)+1;\r
+\r
+ count=inportb(port);\r
+ count|=inportb(port)<<8;\r
+\r
+ if(count>=fragsize)\r
+ block=1;\r
+ else\r
+ block=0;\r
+ dest=LMBuffer+((block*fragsize)<<format);\r
+\r
+ #ifdef MOO\r
+ dest=LMBuffer+((whichbuf*fragsize)<<format);\r
+ whichbuf^=1;\r
+ #endif\r
+ }\r
+\r
+ _farsetsel(_dos_ds);\r
+\r
+ src=(uint32 *)(WaveBuffer+(ReadPtr<<format));\r
+\r
+ if(ssilence)\r
+ {\r
+ uint32 sby;\r
+ if(format) sby=0; /* 16-bit silence. */\r
+ else sby=0x80808080; /* 8-bit silence. */\r
+\r
+ for(x=(fragsize<<format)>>2;x;x--,dest+=4)\r
+ {\r
+ _farnspokel(dest,sby);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ for(x=(fragsize<<format)>>2;x;x--,dest+=4,src++)\r
+ {\r
+ _farnspokel(dest,*src);\r
+ }\r
+ ReadPtr=(ReadPtr+fragsize)&(fragtotal-1);\r
+ }\r
+\r
+ if(soundjoyeron)\r
+ {\r
+ static int coot=0;\r
+ if(!coot)\r
+ {\r
+ UpdateJoyData();\r
+ soundjoyer=1;\r
+ }\r
+ coot=(coot+1)&3;\r
+ }\r
+ hbusy=0;\r
+ outportb(0x20,0x20);\r
+ if(SBIRQ>=8) \r
+ outportb(0xA0,0x20);\r
+}\r
+\r
+void SilenceSound(int s)\r
+{\r
+ ssilence=s;\r
+}\r
+\r
+void WriteSBSound(int32 *Buffer, int Count, int NoBlocking)\r
+{\r
+ int x;\r
+\r
+ if(!format)\r
+ {\r
+ for(x=0;x<Count;x++)\r
+ {\r
+ while(WritePtr==ReadPtr)\r
+ if(NoBlocking)\r
+ return;\r
+ WaveBuffer[WritePtr]=(uint8)((Buffer[x])>>8)^128;\r
+ WritePtr=(WritePtr+1)&(fragtotal-1);\r
+ }\r
+ } \r
+ else // 16 bit\r
+ {\r
+ for(x=0;x<Count;x++)\r
+ {\r
+ while(WritePtr==ReadPtr)\r
+ if(NoBlocking)\r
+ return;\r
+ ((int16 *)WaveBuffer)[WritePtr]=Buffer[x];\r
+ WritePtr=(WritePtr+1)&(fragtotal-1);\r
+ }\r
+ }\r
+}\r
+\r
+void KillSB(void)\r
+{\r
+ if(hsmode)\r
+ ResetDSP(); /* High-speed mode requires a DSP reset. */\r
+ else\r
+ WriteDSP(format?0xD9:0xDA); /* Exit auto-init DMA transfer mode. */ \r
+ WriteDSP(0xD3); /* Turn speaker off. */\r
+\r
+ outportb((SBIRQ>7)?0xA1:0x21,PICMask|(1<<(SBIRQ&7)));\r
+ ResetVectors();\r
+ outportb((SBIRQ>7)?0xA1:0x21,PICMask);\r
+ KillDMABuffer();\r
+}\r
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator\r
+ *\r
+ * Copyright notice for this file:\r
+ * Copyright (C) 2002 Ben Parnell\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+int InitSB(int Rate, int bittage);\r
+void KillSB(void);\r
+\r
+void WriteSBSound(int32 *Buffer, int Count, int NoBlocking);\r
+void SilenceSound(int s);\r
+\r
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator\r
+ *\r
+ * Copyright notice for this file:\r
+ * Copyright (C) 1998 \Firebug\\r
+ * Copyright (C) 2002 Ben Parnell\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <dpmi.h>\r
+#include <sys/farptr.h>\r
+#include <go32.h>\r
+#include <pc.h>\r
+\r
+#include "dos.h"\r
+#include "dos-video.h"\r
+\r
+#define TEXT 3\r
+#define G320x200x256 0x13\r
+\r
+static void vga_waitretrace(void)\r
+{ \r
+ while(inp(0x3da)&0x8); \r
+ while(!(inp(0x3da)&0x8));\r
+}\r
+\r
+static void vga_setmode(int mode)\r
+{\r
+ __dpmi_regs regs;\r
+\r
+ memset(®s,0,sizeof(regs));\r
+ regs.x.ax=mode;\r
+\r
+ __dpmi_int(0x10,®s);\r
+}\r
+\r
+void vga_setpalette(int i, int r, int g, int b)\r
+{ \r
+ outp(0x3c8,i);\r
+ outp(0x3c9,r);\r
+ outp(0x3c9,g);\r
+ outp(0x3c9,b); \r
+}\r
+\r
+int FCEUDvmode=1;\r
+\r
+static int vidready=0;\r
+\r
+/* Part of the VGA low-level mass register setting code derived from\r
+ code by \Firebug\.\r
+*/\r
+\r
+#include "vgatweak.c"\r
+\r
+void SetBorder(void)\r
+{\r
+ inportb(0x3da);\r
+ outportb(0x3c0,(0x11|0x20));\r
+ outportb(0x3c0,0x80);\r
+}\r
+\r
+void TweakVGA(int VGAMode)\r
+{\r
+ int I;\r
+ \r
+ vga_waitretrace();\r
+\r
+ outportb(0x3C8,0x00);\r
+ for(I=0;I<768;I++) outportb(0x3C9,0x00);\r
+\r
+ outportb(0x3D4,0x11);\r
+ I=inportb(0x3D5)&0x7F;\r
+ outportb(0x3D4,0x11);\r
+ outportb(0x3D5,I);\r
+\r
+ switch(VGAMode)\r
+ {\r
+ case 1: for(I=0;I<25;I++) VGAPortSet(v256x240[I]);break;\r
+ case 2: for(I=0;I<25;I++) VGAPortSet(v256x256[I]);break;\r
+ case 3: for(I=0;I<25;I++) VGAPortSet(v256x256S[I]);break;\r
+ case 6: for(I=0;I<25;I++) VGAPortSet(v256x224S[I]);break;\r
+ case 8: for(I=0;I<25;I++) VGAPortSet(v256x224_103[I]);break;\r
+ default: break;\r
+ }\r
+\r
+ outportb(0x3da,0);\r
+}\r
+\r
+\r
+static uint8 palettedbr[256],palettedbg[256],palettedbb[256];\r
+\r
+static void FlushPalette(void)\r
+{\r
+ int x;\r
+ for(x=0;x<256;x++)\r
+ {\r
+ int z=x;\r
+ vga_setpalette(z,palettedbr[x]>>2,palettedbg[x]>>2,palettedbb[x]>>2);\r
+ }\r
+}\r
+\r
+void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)\r
+{\r
+ palettedbr[index]=r;\r
+ palettedbg[index]=g;\r
+ palettedbb[index]=b;\r
+ if(vidready)\r
+ {\r
+ vga_setpalette(index,r>>2,g>>2,b>>2);\r
+ }\r
+}\r
+\r
+\r
+void FCEUD_GetPalette(uint8 i, uint8 *r, uint8 *g, uint8 *b)\r
+{\r
+ *r=palettedbr[i];\r
+ *g=palettedbg[i];\r
+ *b=palettedbb[i];\r
+}\r
+\r
+static uint32 ScreenLoc;\r
+\r
+int InitVideo(void)\r
+{\r
+ vidready=0;\r
+ switch(FCEUDvmode)\r
+ {\r
+ default:\r
+ case 1:\r
+ case 2:\r
+ case 3:\r
+ case 6:\r
+ case 8:\r
+ vga_setmode(G320x200x256);\r
+ vidready|=1;\r
+ ScreenLoc=0xa0000;\r
+ TweakVGA(FCEUDvmode);\r
+ SetBorder();\r
+ DOSMemSet(ScreenLoc, 128, 256*256);\r
+ break;\r
+ }\r
+ vidready|=2;\r
+ FlushPalette();\r
+ return 1;\r
+}\r
+\r
+void KillVideo(void)\r
+{\r
+ if(vidready)\r
+ {\r
+ vga_setmode(TEXT);\r
+ vidready=0;\r
+ }\r
+}\r
+void LockConsole(void){}\r
+void UnlockConsole(void){}\r
+void BlitScreen(uint8 *XBuf)\r
+{\r
+ uint32 dest;\r
+ int tlines;\r
+\r
+ if(eoptions&4 && !NoWaiting)\r
+ vga_waitretrace();\r
+\r
+ tlines=erendline-srendline+1;\r
+\r
+ dest=ScreenLoc;\r
+\r
+ switch(FCEUDvmode)\r
+ {\r
+ case 1:dest+=(((240-tlines)>>1)<<8);break;\r
+ case 2:\r
+ case 3:dest+=(((256-tlines)>>1)<<8);break;\r
+ case 4:\r
+ case 5:dest+=(((240-tlines)>>1)*640+((640-512)>>1));break;\r
+ case 8:\r
+ case 6:if(tlines>224) tlines=224;dest+=(((224-tlines)>>1)<<8);break;\r
+ }\r
+ \r
+ XBuf+=(srendline<<8)+(srendline<<4);\r
+ \r
+ _farsetsel(_dos_ds);\r
+ if(eoptions&DO_CLIPSIDES)\r
+ {\r
+ asm volatile( \r
+ "agoop1:\n\t"\r
+ "movl $30,%%eax\n\t"\r
+ "agoop2:\n\t"\r
+ "movl (%%esi),%%edx\n\t"\r
+ "movl 4(%%esi),%%ecx\n\t"\r
+ ".byte 0x64 \n\t"\r
+ "movl %%edx,(%%edi)\n\t"\r
+ ".byte 0x64 \n\t"\r
+ "movl %%ecx,4(%%edi)\n\t"\r
+ "addl $8,%%esi\n\t"\r
+ "addl $8,%%edi\n\t"\r
+ "decl %%eax\n\t"\r
+ "jne agoop2\n\t"\r
+ "addl $32,%%esi\n\t"\r
+ "addl $16,%%edi\n\t"\r
+ "decb %%bl\n\t"\r
+ "jne agoop1\n\t"\r
+ :\r
+ : "S" (XBuf+8), "D" (dest+8), "b" (tlines)\r
+ : "%eax","%cc","%edx","%ecx" );\r
+ }\r
+ else\r
+ {\r
+ asm volatile( \r
+ "goop1:\n\t"\r
+ "movl $32,%%eax\n\t"\r
+ "goop2:\n\t"\r
+ "movl (%%esi),%%edx\n\t"\r
+ "movl 4(%%esi),%%ecx\n\t"\r
+ ".byte 0x64 \n\t"\r
+ "movl %%edx,(%%edi)\n\t"\r
+ ".byte 0x64 \n\t"\r
+ "movl %%ecx,4(%%edi)\n\t"\r
+ "addl $8,%%esi\n\t"\r
+ "addl $8,%%edi\n\t"\r
+ "decl %%eax\n\t"\r
+ "jne goop2\n\t"\r
+ "addl $16,%%esi\n\t"\r
+ "decb %%bl\n\t"\r
+ "jne goop1\n\t"\r
+ :\r
+ : "S" (XBuf), "D" (dest), "b" (tlines)\r
+ : "%eax","%cc","%edx","%ecx" );\r
+ }\r
+}\r
+\r
+\r
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator\r
+ *\r
+ * Copyright notice for this file:\r
+ * Copyright (C) 2002 Ben Parnell\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+extern int FCEUDvmode;\r
+\r
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <crt0.h>
+#include <sys/farptr.h>
+#include <go32.h>
+
+#include "dos.h"
+#include "dos-joystick.h"
+#include "dos-video.h"
+#include "dos-sound.h"
+#include "../common/args.h"
+#include "../common/config.h"
+
+/* _CRT0_FLAG_LOCK_MEMORY might not always result in all memory being locked.
+ Bummer. I'll add code to explicitly lock the data touched by the sound
+ interrupt handler(and the handler itself), if necessary(though that might
+ be tricky...). I'll also to cover the data the keyboard
+ interrupt handler touches.
+*/
+
+int _crt0_startup_flags = _CRT0_FLAG_FILL_SBRK_MEMORY | _CRT0_FLAG_LOCK_MEMORY | _CRT0_FLAG_USE_DOS_SLASHES;
+
+static int f8bit=0;
+int soundo=44100;
+int doptions=0;
+
+
+CFGSTRUCT DriverConfig[]={
+ NAC("sound",soundo),
+ AC(doptions),
+ AC(f8bit),
+ AC(FCEUDvmode),
+ NACA("joybmap",joyBMap),
+ AC(joy),
+ ENDCFGSTRUCT
+};
+
+char *DriverUsage=
+"-vmode x Select video mode(all are 8 bpp).\n\
+ 1 = 256x240 6 = 256x224(with scanlines)\n\
+ 2 = 256x256 8 = 256x224\n\
+ 3 = 256x256(with scanlines)\n\
+-vsync x Wait for the screen's vertical retrace before updating the\n\
+ screen. Refer to the documentation for caveats.\n\
+ 0 = Disabled.\n\
+ 1 = Enabled.\n\
+-sound x Sound.\n\
+ 0 = Disabled.\n\
+ Otherwise, x = playback rate.\n\
+-f8bit x Force 8-bit sound.\n\
+ 0 = Disabled.\n\
+ 1 = Enabled.\n\
+-joy x Joystick mapped to virtual joystick x(1-4).\n\
+ 0 = Disabled, reset configuration.\n\
+ 1 = Enabled.";
+
+ARGPSTRUCT DriverArgs[]={
+ {"-vmode",0,&FCEUDvmode,0},
+ {"-sound",0,&soundo,0},
+ {"-f8bit",0,&f8bit,0},
+ {"-joy",0,&joy,0},
+ {"-vsync",0,&eoptions,0x8004},
+ {0,0,0,0}
+};
+
+void DoDriverArgs(void)
+{
+ if(!joy) memset(joyBMap,0,4);
+}
+
+int InitSound(void)
+{
+ if(soundo)
+ {
+ if(soundo==1)
+ soundo=44100;
+ soundo=InitSB(soundo,f8bit?0:1);
+ FCEUI_Sound(soundo);
+ }
+ return(soundo?1:0);
+}
+
+void WriteSound(int32 *Buffer, int Count, int NoWaiting)
+{
+ WriteSBSound(Buffer,Count,NoWaiting);
+}
+
+void KillSound(void)
+{
+ if(soundo)
+ KillSB();
+}
+
+void DOSMemSet(uint32 A, uint8 V, uint32 count)
+{
+ uint32 x;
+
+ _farsetsel(_dos_ds);
+ for(x=0;x<count;x++)
+ _farnspokeb(A+x,V);
+}
+
+static char *arg0;
+void GetBaseDirectory(char *BaseDirectory)
+{
+ int x=0;
+
+ if(arg0)
+ for(x=strlen(arg0);x>=0;x--)
+ {
+ if(arg0[x]=='/' || arg0[x]=='\\')
+ {
+ strncpy(BaseDirectory,arg0,x);
+ break;
+ }
+ }
+
+ BaseDirectory[x]=0;
+}
+
+int main(int argc, char *argv[])
+{
+ puts("\nStarting FCE Ultra "VERSION_STRING"...\n");
+ arg0=argv[0];
+ return(CLImain(argc,argv));
+}
+
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator\r
+ *\r
+ * Copyright notice for this file:\r
+ * Copyright (C) 2002 Ben Parnell\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+#include "../../driver.h"\r
+#include "main.h"\r
+\r
+extern int eoptions;\r
+extern int soundo;\r
+void DOSMemSet(uint32 A, uint8 V, uint32 count);\r
+#define DO_CLIPSIDES 1\r
+\r
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define JOY_A 1
+#define JOY_B 2
+#define JOY_SELECT 4
+#define JOY_START 8
+#define JOY_UP 0x10
+#define JOY_DOWN 0x20
+#define JOY_LEFT 0x40
+#define JOY_RIGHT 0x80
+
+static void UpdateFKB(void);
+
+/* UsrInputType[] is user-specified. InputType[] is current
+ (game loading can override user settings)
+*/
+static int UsrInputType[2]={SI_GAMEPAD,SI_GAMEPAD};
+static int InputType[2];
+
+static int UsrInputTypeFC={SI_NONE};
+static int InputTypeFC;
+
+static uint32 JSreturn;
+int NoWaiting=0;
+
+static void DoCheatSeq(void)
+{
+ #if defined(DOS) || defined(SDL)
+ if(inited&1)
+ SilenceSound(1);
+ #endif
+ KillKeyboard();
+ KillVideo();
+
+ DoConsoleCheatConfig();
+ InitVideo();
+ InitKeyboard();
+ #if defined(DOS) || defined(SDL)
+ if(inited&1)
+ SilenceSound(0);
+ #endif
+}
+
+#include "keyscan.h"
+static char *keys;
+static int DIPS=0;
+static uint8 keyonce[MK_COUNT];
+#define KEY(__a) keys[MK(__a)]
+#define keyonly(__a,__z) {if(KEY(__a)){if(!keyonce[MK(__a)]) {keyonce[MK(__a)]=1;__z}}else{keyonce[MK(__a)]=0;}}
+static int JoySwap=0;
+static int cidisabled=0;
+static int KeyboardUpdate(void)
+{
+
+ if(!UpdateKeyboard())
+ if(keys)
+ return 0;
+
+ keys=GetKeyboard();
+
+ if(InputTypeFC==SIFC_FKB)
+ {
+ keyonly(SCROLLLOCK,cidisabled^=1;
+ FCEUI_DispMessage("Family Keyboard %sabled.",cidisabled?"en":"dis");)
+ #ifdef SDL
+ SDL_WM_GrabInput(cidisabled?SDL_GRAB_ON:SDL_GRAB_OFF);
+ #endif
+ if(cidisabled) return(1);
+ }
+ #ifdef SVGALIB
+ keyonly(F3,LockConsole();)
+ keyonly(F4,UnlockConsole();)
+ #elif SDL
+ keyonly(F4,ToggleFS();)
+ #endif
+ NoWaiting&=~1;
+ if(KEY(GRAVE))
+ NoWaiting|=1;
+
+ if(gametype==GIT_FDS)
+ {
+ keyonly(S,DriverInterface(DES_FDSSELECT,0);)
+ keyonly(I,DriverInterface(DES_FDSINSERT,0);)
+ keyonly(E,DriverInterface(DES_FDSEJECT,0);)
+ }
+
+ keyonly(F9,FCEUI_SaveSnapshot();)
+ if(gametype!=GIT_NSF)
+ {
+ keyonly(F2,DoCheatSeq();)
+ keyonly(F5,FCEUI_SaveState();)
+ keyonly(F7,FCEUI_LoadState();)
+ }
+ else
+ {
+ keyonly(CURSORLEFT,DriverInterface(DES_NSFDEC,0);)
+ keyonly(CURSORRIGHT,DriverInterface(DES_NSFINC,0);)
+ if( KEY(ENTER)) DriverInterface(DES_NSFRES,0);
+ if( KEY(CURSORUP)) DriverInterface(DES_NSFINC,0);
+ if( KEY(CURSORDOWN)) DriverInterface(DES_NSFDEC,0);
+ }
+
+ keyonly(F10,DriverInterface(DES_RESET,0);)
+ keyonly(F11,DriverInterface(DES_POWER,0);)
+ if(KEY(F12) || KEY(ESCAPE)) FCEUI_CloseGame();
+
+ if(gametype==GIT_VSUNI)
+ {
+ keyonly(C,DriverInterface(DES_VSUNICOIN,0);)
+ keyonly(V,DIPS^=1;DriverInterface(DES_VSUNITOGGLEDIPVIEW,0);)
+ if(!(DIPS&1)) goto DIPSless;
+ keyonly(1,DriverInterface(DES_VSUNIDIPSET,(void *)1);)
+ keyonly(2,DriverInterface(DES_VSUNIDIPSET,(void *)2);)
+ keyonly(3,DriverInterface(DES_VSUNIDIPSET,(void *)3);)
+ keyonly(4,DriverInterface(DES_VSUNIDIPSET,(void *)4);)
+ keyonly(5,DriverInterface(DES_VSUNIDIPSET,(void *)5);)
+ keyonly(6,DriverInterface(DES_VSUNIDIPSET,(void *)6);)
+ keyonly(7,DriverInterface(DES_VSUNIDIPSET,(void *)7);)
+ keyonly(8,DriverInterface(DES_VSUNIDIPSET,(void *)8);)
+ }
+ else
+ {
+ keyonly(H,DriverInterface(DES_NTSCSELHUE,0);)
+ keyonly(T,DriverInterface(DES_NTSCSELTINT,0);)
+ if(KEY(KP_MINUS) || KEY(MINUS)) DriverInterface(DES_NTSCDEC,0);
+ if(KEY(KP_PLUS) || KEY(EQUAL)) DriverInterface(DES_NTSCINC,0);
+
+ DIPSless:
+ keyonly(0,FCEUI_SelectState(0);)
+ keyonly(1,FCEUI_SelectState(1);)
+ keyonly(2,FCEUI_SelectState(2);)
+ keyonly(3,FCEUI_SelectState(3);)
+ keyonly(4,FCEUI_SelectState(4);)
+ keyonly(5,FCEUI_SelectState(5);)
+ keyonly(6,FCEUI_SelectState(6);)
+ keyonly(7,FCEUI_SelectState(7);)
+ keyonly(8,FCEUI_SelectState(8);)
+ keyonly(9,FCEUI_SelectState(9);)
+ }
+ return 1;
+}
+
+static uint32 KeyboardDodo(void)
+{
+ uint32 JS=0;
+
+ //if(gametype!=GIT_NSF)
+ {
+ int x,y;
+ x=y=0;
+ keyonly(CAPSLOCK,
+ {
+ char tmp[64];
+ JoySwap=(JoySwap+8)%32;
+ sprintf(tmp,"Joystick %d selected.",(JoySwap>>3)+1);
+ FCEUI_DispMessage(tmp);
+ })
+
+ if(KEY(LEFTALT) || KEY(X)) JS|=JOY_A<<JoySwap;
+ if(KEY(LEFTCONTROL) || KEY(SPACE) || KEY(Z) ) JS |=JOY_B<<JoySwap;
+ if(KEY(ENTER)) JS |= JOY_START<<JoySwap;
+ if(KEY(TAB)) JS |= JOY_SELECT<<JoySwap;
+ if(KEY(CURSORDOWN)) y|= JOY_DOWN;
+ if(KEY(CURSORUP)) y|= JOY_UP;
+ if(KEY(CURSORLEFT)) x|= JOY_LEFT;
+ if(KEY(CURSORRIGHT)) x|= JOY_RIGHT;
+ if(y!=(JOY_DOWN|JOY_UP)) JS|=y<<JoySwap;
+ if(x!=(JOY_LEFT|JOY_RIGHT)) JS|=x<<JoySwap;
+ }
+ return JS;
+}
+
+static int powerpadsc[2][12]={
+ {
+ MK(O),MK(P),MK(BRACKET_LEFT),
+ MK(BRACKET_RIGHT),MK(K),MK(L),MK(SEMICOLON),
+ MK(APOSTROPHE),
+ MK(M),MK(COMMA),MK(PERIOD),MK(SLASH)
+ },
+ {
+ MK(O),MK(P),MK(BRACKET_LEFT),
+ MK(BRACKET_RIGHT),MK(K),MK(L),MK(SEMICOLON),
+ MK(APOSTROPHE),
+ MK(M),MK(COMMA),MK(PERIOD),MK(SLASH)
+ }
+ };
+
+static uint32 powerpadbuf[2];
+static int powerpadside=0;
+
+static uint32 UpdatePPadData(int w)
+{
+ static const char shifttableA[12]={8,9,0,1,11,7,4,2,10,6,5,3};
+ static const char shifttableB[12]={1,0,9,8,2,4,7,11,3,5,6,10};
+ uint32 r=0;
+ int *ppadtsc=powerpadsc[w];
+ int x;
+
+ if(powerpadside&(1<<w))
+ {
+ for(x=0;x<12;x++)
+ if(keys[ppadtsc[x]]) r|=1<<shifttableA[x];
+ }
+ else
+ {
+ for(x=0;x<12;x++)
+ if(keys[ppadtsc[x]]) r|=1<<shifttableB[x];
+ }
+ return r;
+}
+
+static uint32 MouseData[3];
+static uint8 fkbkeys[0x48];
+
+void FCEUD_UpdateInput(void)
+{
+ int x;
+ int t=0;
+ static uint32 KeyBJS=0;
+ uint32 JS;
+ int b;
+
+ b=KeyboardUpdate();
+
+ for(x=0;x<2;x++)
+ switch(InputType[x])
+ {
+ case SI_GAMEPAD:t|=1;break;
+ case SI_ARKANOID:t|=2;break;
+ case SI_ZAPPER:t|=2;break;
+ case SI_POWERPADA:powerpadbuf[x]=UpdatePPadData(x);break;
+ }
+
+ switch(InputTypeFC)
+ {
+ case SIFC_ARKANOID:t|=2;break;
+ case SIFC_SHADOW:t|=2;break;
+ case SIFC_FKB:if(cidisabled) UpdateFKB();break;
+ }
+
+ if(t&1)
+ {
+ if(b)
+ KeyBJS=KeyboardDodo();
+ JS=KeyBJS;
+ JS|=(uint32)GetJSOr();
+ JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8);
+ }
+ if(t&2)
+ GetMouseData(MouseData);
+}
+
+static void InitOtherInput(void)
+{
+ void *InputDPtr;
+
+ int t;
+ int x;
+ int attrib;
+
+ for(t=0,x=0;x<2;x++)
+ {
+ attrib=0;
+ InputDPtr=0;
+ switch(InputType[x])
+ {
+ case SI_POWERPADA:InputDPtr=&powerpadbuf[x];break;
+ case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break;
+ case SI_ARKANOID:InputDPtr=MouseData;t|=1;break;
+ case SI_ZAPPER:InputDPtr=MouseData;
+ t|=1;
+ attrib=1;
+ break;
+ }
+ FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
+ }
+
+ attrib=0;
+ InputDPtr=0;
+ switch(InputTypeFC)
+ {
+ case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
+ case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
+ case SIFC_FKB:InputDPtr=fkbkeys;break;
+ }
+
+ FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib);
+ FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
+
+ if(t && !(inited&16))
+ {
+ InitMouse();
+ inited|=16;
+ }
+}
+
+int fkbmap[0x48]=
+{
+ MK(F1),MK(F2),MK(F3),MK(F4),MK(F5),MK(F6),MK(F7),MK(F8),
+ MK(1),MK(2),MK(3),MK(4),MK(5),MK(6),MK(7),MK(8),MK(9),MK(0),
+ MK(MINUS),MK(EQUAL),MK(BACKSLASH),MK(BACKSPACE),
+ MK(ESCAPE),MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y),MK(U),MK(I),MK(O),
+ MK(P),MK(GRAVE),MK(BRACKET_LEFT),MK(ENTER),
+ MK(LEFTCONTROL),MK(A),MK(S),MK(D),MK(F),MK(G),MK(H),MK(J),MK(K),
+ MK(L),MK(SEMICOLON),MK(APOSTROPHE),MK(BRACKET_RIGHT),MK(INSERT),
+ MK(LEFTSHIFT),MK(Z),MK(X),MK(C),MK(V),MK(B),MK(N),MK(M),MK(COMMA),
+ MK(PERIOD),MK(SLASH),MK(RIGHTALT),MK(RIGHTSHIFT),MK(LEFTALT),MK(SPACE),
+ MK(DELETE),MK(END),MK(PAGEDOWN),
+ MK(CURSORUP),MK(CURSORLEFT),MK(CURSORRIGHT),MK(CURSORDOWN)
+};
+
+static void UpdateFKB(void)
+{
+ int x;
+
+ for(x=0;x<0x48;x++)
+ {
+ fkbkeys[x]=0;
+ if(keys[fkbmap[x]])
+ fkbkeys[x]=1;
+ }
+}
--- /dev/null
+#ifdef SVGALIB\r
+\r
+#include <vgakeyboard.h>\r
+#define SCANCODE_DELETE SCANCODE_REMOVE\r
+#define SCANCODE_KP_MINUS SCANCODE_KEYPADMINUS\r
+#define SCANCODE_KP_PLUS SCANCODE_KEYPADPLUS\r
+#define MK(k) SCANCODE_##k\r
+#define MK_COUNT 256\r
+#elif SDL\r
+#include <SDL.h>\r
+#define SDLK_A SDLK_a\r
+#define SDLK_B SDLK_b\r
+#define SDLK_C SDLK_c\r
+#define SDLK_D SDLK_d\r
+#define SDLK_E SDLK_e\r
+#define SDLK_F SDLK_f\r
+#define SDLK_G SDLK_g\r
+#define SDLK_H SDLK_h\r
+#define SDLK_I SDLK_i\r
+#define SDLK_J SDLK_j\r
+#define SDLK_K SDLK_k\r
+#define SDLK_L SDLK_l\r
+#define SDLK_M SDLK_m\r
+#define SDLK_N SDLK_n\r
+#define SDLK_O SDLK_o\r
+#define SDLK_P SDLK_p\r
+#define SDLK_Q SDLK_q\r
+#define SDLK_R SDLK_r\r
+#define SDLK_S SDLK_s\r
+#define SDLK_T SDLK_t\r
+#define SDLK_U SDLK_u\r
+#define SDLK_V SDLK_v\r
+#define SDLK_W SDLK_w\r
+#define SDLK_X SDLK_x\r
+#define SDLK_Y SDLK_y\r
+#define SDLK_Z SDLK_z\r
+#define SDLK_LEFTCONTROL SDLK_LCTRL\r
+#define SDLK_RIGHTCONTROL SDLK_RCTRL\r
+#define SDLK_LEFTALT SDLK_LALT\r
+#define SDLK_RIGHTALT SDLK_RALT\r
+#define SDLK_LEFTSHIFT SDLK_LSHIFT\r
+#define SDLK_RIGHTSHIFT SDLK_RSHIFT\r
+#define SDLK_CURSORDOWN SDLK_DOWN\r
+#define SDLK_CURSORUP SDLK_UP\r
+#define SDLK_CURSORLEFT SDLK_LEFT\r
+#define SDLK_CURSORRIGHT SDLK_RIGHT\r
+#define SDLK_ENTER SDLK_RETURN\r
+#define SDLK_EQUAL SDLK_EQUALS\r
+#define SDLK_APOSTROPHE SDLK_QUOTE\r
+#define SDLK_BRACKET_LEFT SDLK_LEFTBRACKET\r
+#define SDLK_BRACKET_RIGHT SDLK_RIGHTBRACKET\r
+#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */\r
+#define SDLK_GRAVE SDLK_BACKQUOTE\r
+#define MK(k) SDLK_##k\r
+#define MK_COUNT (SDLK_LAST+1)\r
+#elif DOS\r
+\r
+#define SCAN_GRAVE 0x29\r
+#define SCAN_1 0x02\r
+#define SCAN_2 0x03\r
+#define SCAN_3 0x04\r
+#define SCAN_4 0x05\r
+#define SCAN_5 0x06\r
+#define SCAN_6 0x07\r
+#define SCAN_7 0x08\r
+#define SCAN_8 0x09\r
+#define SCAN_9 0x0A\r
+#define SCAN_0 0x0B\r
+#define SCAN_MINUS 0x0C\r
+#define SCAN_EQUAL 0x0D\r
+#define SCAN_BACKSLASH 0x2B\r
+#define SCAN_BACKSPACE 0x0E\r
+#define SCAN_TAB 0x0F\r
+#define SCAN_Q 0x10\r
+#define SCAN_W 0x11\r
+#define SCAN_E 0x12\r
+#define SCAN_R 0x13\r
+#define SCAN_T 0x14\r
+#define SCAN_Y 0x15\r
+#define SCAN_U 0x16\r
+#define SCAN_I 0x17\r
+#define SCAN_O 0x18\r
+#define SCAN_P 0x19\r
+#define SCAN_BRACKET_LEFT 0x1A\r
+#define SCAN_BRACKET_RIGHT 0x1B\r
+#define SCAN_LOWBACKSLASH 0x2B\r
+#define SCAN_CAPSLOCK 0x3A\r
+#define SCAN_A 0x1E\r
+#define SCAN_S 0x1F\r
+#define SCAN_D 0x20\r
+#define SCAN_F 0x21\r
+#define SCAN_G 0x22\r
+#define SCAN_H 0x23\r
+#define SCAN_J 0x24\r
+#define SCAN_K 0x25\r
+#define SCAN_L 0x26\r
+#define SCAN_SEMICOLON 0x27\r
+#define SCAN_APOSTROPHE 0x28\r
+#define SCAN_ENTER 0x1C\r
+#define SCAN_LEFTSHIFT 0x2A\r
+#define SCAN_Z 0x2C\r
+#define SCAN_X 0x2D\r
+#define SCAN_C 0x2E\r
+#define SCAN_V 0x2F\r
+#define SCAN_B 0x30\r
+#define SCAN_N 0x31\r
+#define SCAN_M 0x32\r
+#define SCAN_COMMA 0x33\r
+#define SCAN_PERIOD 0x34\r
+#define SCAN_SLASH 0x35\r
+#define SCAN_RIGHTSHIFT 0x36\r
+#define SCAN_LEFTCONTROL 0x1D\r
+#define SCAN_LEFTALT 0x38\r
+#define SCAN_SPACE 0x39\r
+\r
+/* Extended keys. */\r
+#define SCAN_RIGHTALT (0x38|0x80)\r
+#define SCAN_RIGHTCONTROL (0x1D|0x80)\r
+#define SCAN_BL_INSERT (0x52|0x80)\r
+#define SCAN_BL_DELETE (0x53|0x80)\r
+#define SCAN_BL_CURSORLEFT (0x4B|0x80)\r
+#define SCAN_BL_HOME (0x47|0x80)\r
+#define SCAN_BL_END (0x4F|0x80)\r
+#define SCAN_BL_CURSORUP (0x48|0x80)\r
+#define SCAN_BL_CURSORDOWN (0x50|0x80)\r
+#define SCAN_BL_PAGEUP (0x49|0x80)\r
+#define SCAN_BL_PAGEDOWN (0x51|0x80)\r
+#define SCAN_BL_CURSORRIGHT (0x4D|0x80)\r
+\r
+#define SCAN_SCROLLLOCK 0x46\r
+/* Keys in the key pad area. */\r
+#define SCAN_NUMLOCK 0x45\r
+#define SCAN_HOME 0x47\r
+#define SCAN_CURSORLEFT 0x4B\r
+#define SCAN_END 0x4F\r
+#define SCAN_SLASH 0x35\r
+#define SCAN_CURSORUP 0x48\r
+#define SCAN_CENTER 0x4C\r
+#define SCAN_CURSORDOWN 0x50\r
+#define SCAN_INSERT 0x52\r
+#define SCAN_ASTERISK 0x37\r
+#define SCAN_PAGEUP 0x49\r
+#define SCAN_CURSORRIGHT 0x4D\r
+#define SCAN_PAGEDOWN 0x51\r
+#define SCAN_DELETE 0x53\r
+#define SCAN_KP_MINUS 0x4A\r
+#define SCAN_KP_PLUS 0x4E\r
+#define SCAN_KP_ENTER 0x1C\r
+\r
+#define SCAN_ESCAPE 0x01\r
+#define SCAN_F1 0x3B\r
+#define SCAN_F2 0x3C\r
+#define SCAN_F3 0x3D\r
+#define SCAN_F4 0x3E\r
+#define SCAN_F5 0x3F\r
+#define SCAN_F6 0x40\r
+#define SCAN_F7 0x41\r
+#define SCAN_F8 0x42\r
+#define SCAN_F9 0x43\r
+#define SCAN_F10 0x44\r
+#define SCAN_F11 0x57\r
+#define SCAN_F12 0x58\r
+ \r
+#define MK_COUNT 256\r
+#define MK(k) SCAN_##k\r
+#endif\r
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <linux/joystick.h>
+#include "main.h"
+#include "lnx-joystick.h"
+
+int joy[4]={0,0,0,0};
+int joyBMap[4][4];
+
+static int32 joybuttons[4]={0,0,0,0};
+static int32 joyx[4]={0,0,0,0};
+static int32 joyy[4]={0,0,0,0};
+
+static void ConfigJoystick(int z);
+static int fd[4];
+
+#define JOY_A 1
+#define JOY_B 2
+#define JOY_SELECT 4
+#define JOY_START 8
+#define JOY_UP 0x10
+#define JOY_DOWN 0x20
+#define JOY_LEFT 0x40
+#define JOY_RIGHT 0x80
+
+static void UpdateJoyData(int x)
+{
+ struct js_event e;
+
+ while(read(fd[x],&e,sizeof(struct js_event))==sizeof(struct js_event))
+ {
+ e.type&=~JS_EVENT_INIT;
+ if(e.type==JS_EVENT_BUTTON)
+ {
+ if(e.value)
+ joybuttons[x]|=(1<<e.number);
+ else
+ joybuttons[x]&=~(1<<e.number);
+ }
+ else if(e.type==JS_EVENT_AXIS)
+ {
+ if(e.number==0)
+ joyx[x]=e.value;
+ else if(e.number==1)
+ joyy[x]=e.value;
+ }
+ }
+}
+
+uint32 GetJSOr(void)
+{
+ int x,y;
+ unsigned long ret;
+ ret=0;
+
+ for(x=0;x<4;x++)
+ {
+ int *joym=joyBMap[x];
+
+ if(!joy[x]) continue;
+ UpdateJoyData(x);
+ for(y=0;y<4;y++)
+ if(joybuttons[x]&joym[y]) ret|=(1<<y)<<(x<<3);
+ if(joyx[x]<=-16383) ret|=JOY_LEFT<<(x<<3);
+ else if(joyx[x]>=16383) ret|=JOY_RIGHT<<(x<<3);
+ if(joyy[x]<=-16383) ret|=JOY_UP<<(x<<3);
+ else if(joyy[x]>=16383) ret|=JOY_DOWN<<(x<<3);
+ }
+ return ret;
+}
+
+void KillJoysticks(void)
+{
+ int x;
+ for(x=0;x<4;x++)
+ if(joy[x])
+ close(fd[x]);
+}
+
+int InitJoysticks(void)
+{
+ char dbuf[64];
+ int version;
+ int z;
+
+ for(z=0;z<4;z++)
+ {
+ if(!joy[z]) continue;
+ sprintf(dbuf,"/dev/js%d",joy[z]-1);
+ if((fd[z]=open(dbuf,O_RDONLY|O_NONBLOCK))<0)
+ {
+ printf("Could not open %s.\n",dbuf);
+ joy[z]=0;
+ continue;
+ }
+
+ if(ioctl(fd[z], JSIOCGVERSION, &version)==-1)
+ {
+ printf("Error using ioctl JSIOCGVERSION on %s.\n",dbuf);
+ joy[z]=0;
+ close(fd[z]);
+ continue;
+ }
+
+ if(!(joyBMap[z][0]|joyBMap[z][1]|joyBMap[z][2]|joyBMap[z][3]))
+ ConfigJoystick(z);
+ }
+
+ return(joy[0]|joy[1]|joy[2]|joy[3]);
+}
+
+#define WNOINPUT(); for(;;){uint8 t; if(read(fileno(stdin),&t,1)==-1) \
+ {break;}}
+
+static void BConfig(int z,int b)
+{
+ WNOINPUT();
+ for(;;)
+ {
+ uint8 t;
+ if(read(fileno(stdin),&t,1)==-1)
+ {
+ if(errno!=EAGAIN) break;
+ }
+ else
+ break;
+
+ {
+ struct js_event e;
+
+ while(read(fd[z],&e,sizeof(struct js_event))==sizeof(struct js_event))
+ {
+ if(e.type==JS_EVENT_BUTTON)
+ {
+ if(!e.value)
+ {
+ joyBMap[z][b]=1<<e.number;
+ goto endsa;
+ }
+ }
+ }
+ }
+
+ }
+ endsa:
+ WNOINPUT();
+}
+
+void ConfigJoystick(int z)
+{
+ int sa;
+ static char *genb="** Press button for ";
+
+ printf("\n\n Joystick button configuration:\n\n");
+ printf(" Push the button to map to the virtual joystick.\n");
+ printf(" If you do not wish to assign a button, press Enter to skip\n");
+ printf(" that button.\n\n");
+ printf(" Press enter to continue...\n");
+ getchar();
+ printf("**** Configuring joystick %d ****\n\n",z+1);
+
+ sa=fcntl(fileno(stdin),F_GETFL);
+ fcntl(fileno(stdin),F_SETFL,O_NONBLOCK);
+
+ printf("%s\"Select\".\n",genb);
+ BConfig(z,2);
+
+ printf("%s\"Start\".\n",genb);
+ BConfig(z,3);
+
+ printf("%s\"B\".\n",genb);
+ BConfig(z,1);
+
+ printf("%s\"A\".\n",genb);
+ BConfig(z,0);
+
+ fcntl(fileno(stdin),F_SETFL,sa);
+}
+
--- /dev/null
+extern int joy[4];
+extern int joyBMap[4][4];
+
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* This file contains or coordinates all of the code necessary to compile
+ on a UNIX system that can use svgalib, such as FreeBSD and Linux.
+ This code is not guaranteed to compile on FreeBSD, though.
+*/
+
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "main.h"
+#include "throttle.h"
+
+#include "../common/config.h"
+#include "../common/args.h"
+#include "../common/unixdsp.h"
+#include "../common/cheat.h"
+
+#include "dface.h"
+
+static int ntsccol=0,ntschue=-1,ntsctint=-1;
+/*static*/ int soundvol=100;
+static int inited=0;
+
+int srendlinev[2]={8,0};
+int erendlinev[2]={239,239};
+int srendline,erendline;
+
+
+static char BaseDirectory[2048];
+
+int eoptions=0;
+
+static void DriverKill(void);
+static int DriverInitialize(void);
+
+static int gametype;
+#include "input.c"
+
+static void ParseGI(FCEUGI *gi)
+{
+ gametype=gi->type;
+
+ InputType[0]=UsrInputType[0];
+ InputType[1]=UsrInputType[1];
+ InputTypeFC=UsrInputTypeFC;
+
+ if(gi->input[0]>=0)
+ InputType[0]=gi->input[0];
+ if(gi->input[1]>=0)
+ InputType[1]=gi->input[1];
+ if(gi->inputfc>=0)
+ InputTypeFC=gi->inputfc;
+ FCEUI_GetCurrentVidSystem(&srendline,&erendline);
+}
+
+void FCEUD_PrintError(char *s)
+{
+ puts(s);
+}
+
+static char *cpalette=0;
+static void LoadCPalette(void)
+{
+ uint8 tmpp[192];
+ FILE *fp;
+
+ if(!(fp=fopen(cpalette,"rb")))
+ {
+ printf(" Error loading custom palette from file: %s\n",cpalette);
+ return;
+ }
+ fread(tmpp,1,192,fp);
+ FCEUI_SetPaletteArray(tmpp);
+ fclose(fp);
+}
+
+static CFGSTRUCT fceuconfig[]={
+ AC(soundvol),
+ ACS(cpalette),
+ AC(ntsctint),
+ AC(ntschue),
+ AC(ntsccol),
+ AC(UsrInputTypeFC),
+ ACA(UsrInputType),
+ AC(powerpadside),
+ AC(powerpadsc),
+ AC(eoptions),
+ ACA(srendlinev),
+ ACA(erendlinev),
+ ADDCFGSTRUCT(DriverConfig),
+ ENDCFGSTRUCT
+};
+
+static void SaveConfig(void)
+{
+ char tdir[2048];
+ sprintf(tdir,"%s"PSS"fceu.cfg",BaseDirectory);
+ DriverInterface(DES_GETNTSCTINT,&ntsctint);
+ DriverInterface(DES_GETNTSCHUE,&ntschue);
+ SaveFCEUConfig(tdir,fceuconfig);
+}
+
+static void LoadConfig(void)
+{
+ char tdir[2048];
+ sprintf(tdir,"%s"PSS"fceu.cfg",BaseDirectory);
+ LoadFCEUConfig(tdir,fceuconfig);
+ if(ntsctint>=0) DriverInterface(DES_SETNTSCTINT,&ntsctint);
+ if(ntschue>=0) DriverInterface(DES_SETNTSCHUE,&ntschue);
+}
+
+static void CreateDirs(void)
+{
+ char *subs[5]={"fcs","snaps","gameinfo","sav","cheats"};
+ char tdir[2048];
+ int x;
+
+ mkdir(BaseDirectory,S_IRWXU);
+ for(x=0;x<5;x++)
+ {
+ sprintf(tdir,"%s"PSS"%s",BaseDirectory,subs[x]);
+ mkdir(tdir,S_IRWXU);
+ }
+}
+
+static void SetSignals(void (*t)(int))
+{
+ int sigs[11]={SIGINT,SIGTERM,SIGHUP,SIGPIPE,SIGSEGV,SIGFPE,SIGKILL,SIGALRM,SIGABRT,SIGUSR1,SIGUSR2};
+ int x;
+ for(x=0;x<11;x++)
+ signal(sigs[x],t);
+}
+
+static void CloseStuff(int signum)
+{
+ DriverKill();
+ printf("\nSignal %d has been caught and dealt with...\n",signum);
+ switch(signum)
+ {
+ case SIGINT:printf("How DARE you interrupt me!\n");break;
+ case SIGTERM:printf("MUST TERMINATE ALL HUMANS\n");break;
+ case SIGHUP:printf("Reach out and hang-up on someone.\n");break;
+ case SIGPIPE:printf("The pipe has broken! Better watch out for floods...\n");break;
+ case SIGSEGV:printf("Iyeeeeeeeee!!! A segmentation fault has occurred. Have a fluffy day.\n");break;
+ /* So much SIGBUS evil. */
+ #ifdef SIGBUS
+ #if(SIGBUS!=SIGSEGV)
+ case SIGBUS:printf("I told you to be nice to the driver.\n");break;
+ #endif
+ #endif
+ case SIGFPE:printf("Those darn floating points. Ne'er know when they'll bite!\n");break;
+ case SIGALRM:printf("Don't throw your clock at the meowing cats!\n");break;
+ case SIGABRT:printf("Abort, Retry, Ignore, Fail?\n");break;
+ case SIGUSR1:
+ case SIGUSR2:printf("Killing your processes is not nice.\n");break;
+ }
+ exit(1);
+}
+
+static void DoArgs(int argc, char *argv[])
+{
+ static char *cortab[5]={"none","gamepad","zapper","powerpad","arkanoid"};
+ static int cortabi[5]={SI_NONE,SI_GAMEPAD,
+ SI_ZAPPER,SI_POWERPADA,SI_ARKANOID};
+ static char *fccortab[5]={"none","arkanoid","shadow","4player","fkb"};
+ static int fccortabi[5]={SIFC_NONE,SIFC_ARKANOID,SIFC_SHADOW,
+ SIFC_4PLAYER,SIFC_FKB};
+
+ int x;
+ static char *inputa[2]={0,0};
+ static char *fcexp=0;
+ static int docheckie[4];
+
+ static ARGPSTRUCT FCEUArgs[]={
+ {"-soundvol",0,&soundvol,0},
+ {"-cpalette",0,&cpalette,0x4001},
+
+ {"-ntsccol",0,&ntsccol,0},
+ {"-pal",&docheckie[0],0,0},
+ {"-input1",0,&inputa[0],0x4001},{"-input2",0,&inputa[1],0x4001},
+ {"-fcexp",0,&fcexp,0x4001},
+
+ {"-gg",&docheckie[1],0,0},
+ {"-no8lim",0,&eoptions,0x8001},
+ {"-subase",0,&eoptions,0x8002},
+ {"-snapname",0,&eoptions,0x8000|EO_SNAPNAME},
+ {"-nofs",0,&eoptions,0x8000|EO_NOFOURSCORE},
+ {"-clipsides",0,&eoptions,0x8000|EO_CLIPSIDES},
+ {"-nothrottle",0,&eoptions,0x8000|EO_NOTHROTTLE},
+ {"-slstart",0,&srendlinev[0],0},{"-slend",0,&erendlinev[0],0},
+ {"-slstartp",0,&srendlinev[1],0},{"-slendp",0,&erendlinev[1],0},
+ {0,(void *)DriverArgs,0,0},
+ {0,0,0,0}
+ };
+
+ memset(docheckie,0,sizeof(docheckie));
+ ParseArguments(argc, argv, FCEUArgs);
+ if(cpalette)
+ {
+ if(cpalette[0]=='0')
+ if(cpalette[1]==0)
+ {
+ free(cpalette);
+ cpalette=0;
+ }
+ }
+ if(docheckie[0])
+ FCEUI_SetVidSystem(1);
+ if(docheckie[1])
+ FCEUI_SetGameGenie(1);
+
+ FCEUI_DisableSpriteLimitation(eoptions&1);
+ FCEUI_SaveExtraDataUnderBase(eoptions&2);
+ FCEUI_SetSnapName(eoptions&EO_SNAPNAME);
+
+ for(x=0;x<2;x++)
+ {
+ if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
+ if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
+ }
+
+ FCEUI_SetRenderedLines(srendlinev[0],erendlinev[0],srendlinev[1],erendlinev[1]);
+ FCEUI_SetSoundVolume(soundvol);
+ //DriverInterface(DES_NTSCCOL,&ntsccol);
+ DoDriverArgs();
+
+ if(fcexp)
+ {
+ int y;
+ for(y=0;y<5;y++)
+ {
+ if(!strncmp(fccortab[y],fcexp,8))
+ {
+ UsrInputTypeFC=fccortabi[y];
+ break;
+ }
+ }
+ free(fcexp);
+ }
+ for(x=0;x<2;x++)
+ {
+ int y;
+
+ if(!inputa[x])
+ continue;
+
+ for(y=0;y<5;y++)
+ {
+ if(!strncmp(cortab[y],inputa[x],8))
+ {
+ UsrInputType[x]=cortabi[y];
+ if(y==3)
+ {
+ powerpadside&=~(1<<x);
+ powerpadside|=((((inputa[x][8])-'a')&1)^1)<<x;
+ }
+ free(inputa[x]);
+ }
+ }
+ }
+}
+
+#include "usage.h"
+
+int CLImain(int argc, char *argv[])
+{
+ FCEUGI *tmp;
+ int ret;
+
+ if(!(ret=FCEUI_Initialize()))
+ return(1);
+ GetBaseDirectory(BaseDirectory);
+ FCEUI_SetBaseDirectory(BaseDirectory);
+
+ CreateDirs();
+ if(argc<=1)
+ {
+ ShowUsage(argv[0]);
+ return 1;
+ }
+ LoadConfig();
+ DoArgs(argc-2,&argv[1]);
+ FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
+ if(cpalette)
+ LoadCPalette();
+ if(InitSound())
+ inited|=1;
+
+ if(!(tmp=FCEUI_LoadGame(argv[argc-1])))
+ {
+ ret=0;
+ goto dk;
+ }
+ ParseGI(tmp);
+ RefreshThrottleFPS();
+ if(!DriverInitialize())
+ {
+ ret=0;
+ goto dk;
+ }
+ InitOtherInput();
+ FCEUI_Emulate();
+
+ dk:
+ DriverKill();
+ return(ret?0:1);
+}
+
+static int DriverInitialize(void)
+{
+ SetSignals((void *)CloseStuff);
+
+ if(InitJoysticks())
+ inited|=2;
+ if(!InitVideo()) return 0;
+ inited|=4;
+ if(!InitKeyboard()) return 0;
+ inited|=8;
+ return 1;
+}
+
+static void DriverKill(void)
+{
+ SaveConfig();
+ SetSignals(SIG_IGN);
+
+ if(inited&2)
+ KillJoysticks();
+ if(inited&8)
+ KillKeyboard();
+ if(inited&4)
+ KillVideo();
+ if(inited&1)
+ KillSound();
+ if(inited&16)
+ KillMouse();
+ inited=0;
+}
+
+void FCEUD_Update(uint8 *XBuf, int16 *Buffer, int Count)
+{
+ if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
+ SpeedThrottle();
+ BlitScreen(XBuf);
+ if(Count)
+ WriteSound(Buffer,Count,NoWaiting);
+ FCEUD_UpdateInput();
+}
+
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "../../driver.h"
+
+extern int eoptions;
+#define EO_NO8LIM 1
+#define EO_SUBASE 2
+#define EO_CLIPSIDES 8
+#define EO_SNAPNAME 16
+#define EO_NOFOURSCORE 32
+#define EO_NOTHROTTLE 64
+extern int srendline,erendline,srendlinev[2],erendlinev[2];
+extern int NoWaiting;
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ * Copyright (C) 2002 Paul Kuliniewicz
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* PK: SDL joystick input stuff */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "sdl.h"
+static SDL_Joystick *jo[4] = {NULL, NULL, NULL, NULL};
+
+static void ConfigJoystick (int z);
+
+#define JOY_A 0x01
+#define JOY_B 0x02
+#define JOY_SELECT 0x04
+#define JOY_START 0x08
+#define JOY_UP 0x10
+#define JOY_DOWN 0x20
+#define JOY_LEFT 0x40
+#define JOY_RIGHT 0x80
+
+/* Gets the current joystick position information. */
+uint32 GetJSOr (void)
+{
+ int n; /* joystick index */
+ int b; /* button index */
+ int *joym; /* pointer to a joystick's button map */
+ Sint16 pos; /* axis position */
+ uint32 ret = 0; /* return value */
+
+ for (n = 0; n < 4; n++)
+ {
+ if (joy[n] == 0)
+ continue;
+ joym = joyBMap[n];
+
+ /* Axis information. */
+ pos = SDL_JoystickGetAxis(jo[n], joyAMap[n][0]);
+ if (pos <= -16383)
+ ret |= JOY_LEFT << (n << 3);
+ else if (pos >= 16363)
+ ret |= JOY_RIGHT << (n << 3);
+ pos = SDL_JoystickGetAxis(jo[n], joyAMap[n][1]);
+ if (pos <= -16383)
+ ret |= JOY_UP << (n << 3);
+ else if (pos >= 16383)
+ ret |= JOY_DOWN << (n << 3);
+
+ /* Button information. */
+ for (b = 0; b < 4; b++)
+ {
+ if (SDL_JoystickGetButton(jo[n], joym[b]))
+ ret |= (1 << b) << (n << 3);
+ }
+ }
+
+ return ret;
+}
+
+/* Cleanup opened joysticks. */
+void KillJoysticks (void)
+{
+ int n; /* joystick index */
+
+ for (n = 0; n < 4; n++)
+ {
+ if (joy[n] != 0)
+ SDL_JoystickClose(jo[n]);
+ }
+ SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+ return;
+}
+
+/* Initialize joysticks. */
+int InitJoysticks (void)
+{
+ int n; /* joystick index */
+ if(!(joy[0]|joy[1]|joy[2]|joy[3]))
+ return(0);
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ for (n = 0; n < 4; n++)
+ {
+ if (joy[n] == 0)
+ continue;
+
+ /* Open the joystick under SDL. */
+ jo[n] = SDL_JoystickOpen(joy[n] - 1);
+ if (jo[n] == NULL)
+ {
+ printf("Could not open joystick %d: %s.\n",
+ joy[n] - 1, SDL_GetError());
+ joy[n] = 0;
+ continue;
+ }
+
+ /* Check for a button map. */
+ if (!(joyBMap[n][0] | joyBMap[n][1] | joyBMap[n][2] |
+ joyBMap[n][3]))
+ {
+ ConfigJoystick(n);
+ }
+ }
+
+ return (1);
+}
+
+#define WNOINPUT(); for(;;){uint8 t; if(read(fileno(stdin),&t,1)==-1) \
+ {break;}}
+
+/* Configure a joystick button. */
+static void BConfig (int n, int b)
+{
+ SDL_Event event; /* SDL event structure */
+ WNOINPUT();
+ while (1)
+ {
+ uint8 t;
+ if (read(fileno(stdin), &t, 1) == -1)
+ {
+ if (errno != EAGAIN)
+ break;
+ }
+ else
+ break;
+
+ if (SDL_PollEvent(&event) && event.type == SDL_JOYBUTTONDOWN)
+ {
+ joyBMap[n][b] = event.jbutton.button;
+ goto endsa;
+ }
+ }
+
+ endsa:
+ WNOINPUT();
+
+ return;
+}
+
+/* Joystick button and axis configuration. */
+void ConfigJoystick (int n)
+{
+ int sa; /* buffer value */
+ char buf[128]; /* input buffer */
+
+ printf("\n\n Joystick button and axis configuration:\n\n");
+ printf(" Select the joystick axes to use for the virtual d-pad.\n");
+ printf(" If you do not wish to assign an axis, press Enter to skip\n");
+ printf(" that axis.\n");
+ printf(" Push the button to map to the virtual joystick.\n");
+ printf(" If you do not wish to assign a button, press Enter to skip\n");
+ printf(" that button.\n Press enter to continue...\n");
+ getchar();
+ printf("**** Configuring joystick %d ****\n\n", n + 1);
+
+ printf("** Enter axis to use for the x-axis (default 0).\n");
+ fgets(buf, sizeof(buf), stdin);
+ joyAMap[n][0] = ('0' <= buf[0] && buf[9] <= '9') ? atoi(buf) : 0;
+
+ printf("** Enter axis to use for the y-axis (default 1).\n");
+ fgets(buf, sizeof(buf), stdin);
+ joyAMap[n][1] = ('0' <= buf[0] && buf[9] <= '9') ? atoi(buf) : 1;
+
+ sa = fcntl(fileno(stdin), F_GETFL);
+ fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+
+ printf("** Press button for \"Select\".\n");
+ BConfig(n, 2);
+
+ printf("** Press button for \"Start\".\n");
+ BConfig(n, 3);
+
+ printf("** Press button for \"B\".\n");
+ BConfig(n, 1);
+
+ printf("** Press button for \"A\".\n");
+ BConfig(n, 0);
+
+ fcntl(fileno(stdin), F_SETFL, sa);
+}
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2001 LULU
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "sdl.h"
+#include <SDL/SDL_net.h>
+#include "sdl-netplay.h"
+
+char *netplayhost=0;
+
+static int tonowait;
+
+int Port=0xFCE;
+int FDnetplay=0;
+
+
+static SDLNet_SocketSet socketset = NULL;
+static TCPsocket tcpsock = NULL, servsock = NULL;
+
+void cleanup(void)
+{
+ if (tcpsock != NULL) {
+ SDLNet_TCP_DelSocket(socketset, tcpsock);
+ SDLNet_TCP_Close(tcpsock);
+ tcpsock = NULL;
+ }
+ if (servsock != NULL) {
+ SDLNet_TCP_DelSocket(socketset, servsock);
+ SDLNet_TCP_Close(servsock);
+ servsock = NULL;
+ }
+ if (socketset != NULL) {
+ SDLNet_FreeSocketSet(socketset);
+ socketset = NULL;
+ }
+}
+
+int FCEUD_NetworkConnect(void)
+{
+ IPaddress serverIP;
+
+ tonowait=0;
+
+ if (netplay == 2) {
+ /* client */
+ printf("connecting to %s\n", netplayhost);
+
+ SDLNet_ResolveHost(&serverIP, netplayhost, Port);
+ if (serverIP.host == INADDR_NONE) {
+ fprintf(stderr, "Couldn't connected to %s\n", netplayhost);
+ return -1;
+ } else {
+ tcpsock = SDLNet_TCP_Open(&serverIP);
+ if (tcpsock == NULL) {
+ fprintf(stderr, "Couldn't connected to %s\n", netplayhost);
+ return -1;
+ }
+ }
+ printf("connected to %s\n", netplayhost);
+
+ socketset = SDLNet_AllocSocketSet(1);
+ if (socketset == NULL) {
+ fprintf(stderr, "Couldn't create socket set: %s\n",
+ SDLNet_GetError());
+ return -1;
+ }
+ SDLNet_TCP_AddSocket(socketset, tcpsock);
+
+ return 1;
+ } else {
+ /* server */
+
+ SDLNet_ResolveHost(&serverIP, NULL, Port);
+ printf("Server IP: %x, %d\n", serverIP.host, serverIP.port);
+ servsock = SDLNet_TCP_Open(&serverIP);
+ if (servsock == NULL) {
+ cleanup();
+ fprintf(stderr, "Couldn't create server socket: %s\n",
+ SDLNet_GetError());
+ return -1;
+ }
+
+ socketset = SDLNet_AllocSocketSet(2);
+ if (socketset == NULL) {
+ fprintf(stderr, "Couldn't create socket set: %s\n",
+ SDLNet_GetError());
+ return -1;
+ }
+ SDLNet_TCP_AddSocket(socketset, servsock);
+
+ if (SDLNet_CheckSockets(socketset, ~0)) {
+ tcpsock = SDLNet_TCP_Accept(servsock);
+ if (tcpsock == NULL) {
+ return -1;
+ }
+ SDLNet_TCP_AddSocket(socketset, tcpsock);
+
+ printf("OK, connected\n");
+ return 1;
+ }
+ }
+
+ return -1;
+}
+
+void FCEUD_NetworkClose(void)
+{
+ cleanup();
+}
+
+int FCEUD_NetworkRecvData(uint8 *data, uint32 len, int block)
+{
+ if(block)
+ {
+ if(SDLNet_TCP_Recv(tcpsock, (void *) data, len)!=len)
+ {
+ cleanup();
+ return(0);
+ }
+ switch(SDLNet_CheckSockets(socketset,0))
+ {
+ case -1:return(0);
+ case 0:NoWaiting&=~2;tonowait=0;break;
+ default:if(tonowait>=3)
+ NoWaiting|=2;
+ else tonowait++;
+ break;
+ }
+ return(1);
+ }
+ else
+ {
+ int t=SDLNet_CheckSockets(socketset,0);
+ if(t<0) return(0);
+ if(!t) return(-1);
+ return(SDLNet_TCP_Recv(tcpsock, (void *) data, len)==len);
+ }
+}
+
+/* 0 on failure, 1 on success. This function should always block. */
+int FCEUD_NetworkSendData(uint8 *Value, uint32 len)
+{
+ if (tcpsock)
+ return(SDLNet_TCP_Send(tcpsock, (void *) Value, len)==len);
+ return 0;
+}
--- /dev/null
+extern char *netplayhost;
+extern int Port;
+extern int FDnetplay;
+#define netplay FDnetplay
+
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include "sdl.h"
+
+#ifndef DSPSOUND
+
+//#define BSIZE (32768-1024)
+
+static int32 BSIZE;
+static volatile int16 AudioBuf[32768];
+static volatile uint32 readoffs,writeoffs;
+void fillaudio(void *udata, uint8 *stream, int len)
+{
+ int16 *dest=(int16 *)stream;
+
+ len>>=1;
+ while(len)
+ {
+ *dest=AudioBuf[readoffs];
+ dest++;
+ readoffs=(readoffs+1)&32767;
+ len--;
+ }
+}
+
+void WriteSound(int16 *Buffer, int Count, int NoWaiting)
+{
+ while(Count)
+ {
+ while(writeoffs==((readoffs-BSIZE)&32767))
+ if(NoWaiting)
+ return;
+ AudioBuf[writeoffs]=*Buffer;
+ writeoffs=(writeoffs+1)&32767;
+ Buffer++;
+ Count--;
+ }
+}
+
+int InitSound(void)
+{
+ if(_sound)
+ {
+ SDL_AudioSpec spec;
+
+ if(_lbufsize<_ebufsize)
+ {
+ puts("Ack, lbufsize must not be smaller than ebufsize!");
+ return(0);
+ }
+ if(_lbufsize<6 || _lbufsize>13)
+ {
+ puts("lbufsize out of range");
+ return(0);
+ }
+ if(_ebufsize<5)
+ {
+ puts("ebufsize out of range");
+ return(0);
+ }
+ memset(&spec,0,sizeof(spec));
+ if(SDL_InitSubSystem(SDL_INIT_AUDIO)<0)
+ {
+ puts(SDL_GetError());
+ return(0);
+ }
+ if(_sound==1) _sound=44100;
+ spec.freq=_sound;
+ spec.format=AUDIO_S16;
+ spec.channels=1;
+ spec.samples=1<<_ebufsize;
+ spec.callback=fillaudio;
+ spec.userdata=0;
+
+ if(SDL_OpenAudio(&spec,0)<0)
+ {
+ puts(SDL_GetError());
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ return(0);
+ }
+ FCEUI_Sound(_sound);
+ BSIZE=32768-(1<<_lbufsize);
+ SDL_PauseAudio(0);
+ return(1);
+ }
+ return(0);
+}
+
+void SilenceSound(int n)
+{
+ SDL_PauseAudio(n);
+
+}
+
+void KillSound(void)
+{
+ SDL_CloseAudio();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+}
+
+#else
+#include "../common/unixdsp.h"
+
+void WriteSound(int32 *Buffer, int Count, int NoWaiting)
+{
+ WriteUNIXDSPSound(Buffer, Count, NoWaiting);
+}
+
+int InitSound(void)
+{
+ if(_sound)
+ {
+ int rate;
+ if(_sound==1)
+ _sound=48000;
+ rate=_sound;
+ if(InitUNIXDSPSound(&rate,_f8bit?0:1,8,8))
+ {
+ FCEUI_Sound(rate);
+ return(1);
+ }
+ }
+ return(0);
+}
+void KillSound(void)
+{
+ KillUNIXDSPSound();
+}
+#endif
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "sdl.h"
+#include "../common/vidblit.h"
+
+#define _sline srendline
+#define _eline erendline
+
+SDL_Surface *screen;
+
+static int tlines;
+static int inited=0;
+
+static int exs,eys,eefx;
+#define NWIDTH (256-((eoptions&EO_CLIPSIDES)?16:0))
+#define NOFFSET (32-8+(eoptions&EO_CLIPSIDES?8:0))
+
+static void CleanSurface(void)
+{
+ uint32 x;
+
+ x=screen->pitch*screen->h;
+
+ if(SDL_MUSTLOCK(screen))
+ SDL_LockSurface(screen);
+
+ memset((uint8*)screen->pixels, 0x80, x);
+
+ if(SDL_MUSTLOCK(screen))
+ SDL_UnlockSurface(screen);
+
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+}
+
+static int paletterefresh;
+
+void KillVideo(void)
+{
+ if(inited&1)
+ {
+ SDL_QuitSubSystem(SDL_INIT_VIDEO);
+ }
+ inited=0;
+}
+
+int InitVideo(void)
+{
+ const SDL_VideoInfo *vinf;
+ int flags=0;
+
+ #ifdef BROKEN
+ if(_fullscreen && _fshack)
+ setenv("SDL_VIDEODRIVER",_fshack,1);
+ else
+ {
+ if(!_fshacksave)
+ unsetenv("SDL_VIDEODRIVER");
+ else
+ setenv("SDL_VIDEODRIVER",_fshacksave,1);
+ }
+ #endif
+ if(SDL_InitSubSystem(SDL_INIT_VIDEO)==-1)
+ {
+ puts(SDL_GetError());
+ return(0);
+ }
+ inited|=1;
+
+ SDL_ShowCursor(0);
+ tlines=_eline-_sline+1;
+
+ vinf=SDL_GetVideoInfo();
+
+ if(vinf->hw_available)
+ flags|=SDL_HWSURFACE;
+
+ if(_fullscreen)
+ flags|=SDL_FULLSCREEN;
+ flags|=SDL_HWPALETTE;
+
+ if(_fullscreen)
+ {
+ exs=_xscalefs;
+ eys=_yscalefs;
+ eefx=_efxfs;
+ if(_xres<NWIDTH*exs || _yres<tlines*eys)
+ {
+ puts("xscale and/or yscale out of bounds.");
+ KillVideo();
+ return(0);
+ }
+ screen = SDL_SetVideoMode(_xres, _yres, 8, flags);
+ }
+ else
+ {
+ exs=_xscale;
+ eys=_yscale;
+ eefx=_efx;
+ screen = SDL_SetVideoMode(NWIDTH*exs, tlines*eys, 8, flags);
+ }
+ if(!screen)
+ {
+ puts(SDL_GetError());
+ KillVideo();
+ return(0);
+ }
+ inited=1;
+ CleanSurface();
+
+ SDL_WM_SetCaption("FCE Ultra","FCE Ultra");
+ paletterefresh=1;
+ return 1;
+}
+
+void ToggleFS(void)
+{
+ KillVideo();
+ _fullscreen=!_fullscreen;
+
+ if(!InitVideo())
+ {
+ _fullscreen=!_fullscreen;
+ if(!InitVideo())
+ {
+ puts("Gah, bailing out.");
+ exit(1);
+ }
+ }
+}
+static SDL_Color psdl[256];
+
+void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
+{
+
+ psdl[index].r=r;
+ psdl[index].g=g;
+ psdl[index].b=b;
+
+ paletterefresh=1;
+}
+
+void FCEUD_GetPalette(uint8 index, uint8 *r, uint8 *g, uint8 *b)
+{
+ *r=psdl[index].r;
+ *g=psdl[index].g;
+ *b=psdl[index].b;
+}
+
+static void RedoPalette(void)
+{
+ SDL_SetPalette(screen,SDL_PHYSPAL,psdl,0,256);
+}
+
+void LockConsole(){}
+void UnlockConsole(){}
+void BlitScreen(uint8 *XBuf)
+{
+ uint8 *dest;
+ int xo=0,yo=0;
+
+ if(paletterefresh)
+ {
+ RedoPalette();
+ paletterefresh=0;
+ }
+
+ XBuf+=_sline*320;
+
+ if(SDL_MUSTLOCK(screen))
+ SDL_LockSurface(screen);
+
+ dest=screen->pixels;
+
+ if(_fullscreen)
+ {
+ xo=(((screen->w-NWIDTH*exs))>>1);
+ dest+=xo;
+ if(screen->h>(tlines*eys))
+ {
+ yo=((screen->h-tlines*eys)>>1);
+ dest+=yo*screen->pitch;
+ }
+ }
+
+ Blit8To8(XBuf+NOFFSET,dest, NWIDTH, tlines, screen->pitch,exs,eys,eefx);
+
+ if(SDL_MUSTLOCK(screen))
+ SDL_UnlockSurface(screen);
+
+ SDL_UpdateRect(screen, xo, yo, NWIDTH*exs, tlines*eys);
+}
+
+uint32 PtoV(uint16 x, uint16 y)
+{
+ if(_fullscreen)
+ {
+
+ }
+ else
+ {
+ if(eoptions&EO_CLIPSIDES)
+ x+=8;
+ y+=srendline;
+ }
+ return(x|(y<<16));
+}
--- /dev/null
+uint32 PtoV(uint16 x, uint16 y);
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sdl.h"
+#include "sdl-video.h"
+#ifdef NETWORK
+#include "unix-netplay.h"
+#endif
+
+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),
+ 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\
+-sound x Sound.\n\
+ 0 = Disabled.\n\
+ Otherwise, x = playback rate.\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
+"-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.";
+
+//static int docheckie[2]={0,0};
+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
+ #ifdef NETWORK
+ {"-connect",&docheckie[0],&netplayhost,0x4001},
+ {"-server",&docheckie[1],0,0},
+ {"-netport",0,&Port,0},
+ #endif
+ {0,0,0,0}
+};
+
+static void SetDefaults(void)
+{
+ _xres=320;
+ _yres=240;
+ _fullscreen=0;
+ _sound=48000;
+ #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));
+}
+
+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;
+ else if(docheckie[1])
+ netplay=1;
+
+ if(netplay)
+ FCEUI_SetNetworkPlay(netplay);
+ #endif
+
+ for(x=0;x<4;x++)
+ if(!joy[x])
+ {
+ memset(joyBMap[x],0,sizeof(joyBMap[0]));
+ memset(joyAMap[x],0,sizeof(joyAMap[0]));
+ }
+}
+int InitMouse(void)
+{
+ return(0);
+}
+void KillMouse(void){}
+void GetMouseData(uint32 *d)
+{
+ int x,y;
+ uint32 t;
+
+ t=SDL_GetMouseState(&x,&y);
+ d[2]=0;
+ if(t&SDL_BUTTON(1))
+ d[2]|=1;
+ if(t&SDL_BUTTON(3))
+ d[2]|=2;
+ t=PtoV(x,y);
+ d[0]=t&0xFFFF;
+ d[1]=(t>>16)&0xFFFF;
+}
+
+int InitKeyboard(void)
+{
+ return(1);
+}
+
+int UpdateKeyboard(void)
+{
+ return(1);
+}
+
+void KillKeyboard(void)
+{
+
+}
+
+char *GetKeyboard(void)
+{
+ SDL_PumpEvents();
+ return (char *)SDL_GetKeyState(0);
+}
+#include "unix-basedir.h"
+
+int CLImain(int argc, char *argv[]);
+int main(int argc, char *argv[])
+{
+ puts("\nStarting FCE Ultra "VERSION_STRING"...\n");
+ if(SDL_Init(0))
+ {
+ printf("Could not initialize SDL: %s.\n", SDL_GetError());
+ return(-1);
+ }
+ SetDefaults();
+
+ #ifdef BROKEN
+ if(getenv("SDL_VIDEODRIVER"))
+ {
+ if((_fshacksave=malloc(strlen(getenv("SDL_VIDEODRIVER"))+1)))
+ strcpy(_fshacksave,getenv("SDL_VIDEODRIVER"));
+ }
+ else
+ _fshacksave=0;
+ #endif
+
+ {
+ int ret=CLImain(argc,argv);
+ SDL_Quit();
+ return(ret);
+ }
+}
+
--- /dev/null
+#include <SDL.h>
+#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;
+} 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
+
+#define joyAMap Settings.joyAMap
+#define joyBMap Settings.joyBMap
+#define joy Settings.joy
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 1998 \Firebug\
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <vga.h>
+#include <sys/io.h>
+
+#define inportb inb
+#define outportb(port, value) outb(value, port)
+#define outportw(port, value) outw(value, port)
+
+#include "main.h"
+#include "svgalib.h"
+#include "svga-video.h"
+
+
+int vmode=1;
+
+#ifdef FRAMESKIP
+int FCEUDfskip=0;
+#endif
+
+static int vidready=0;
+static int conlock=0;
+
+void LockConsole(void)
+{
+ if(!conlock)
+ {
+ vga_lockvc();
+ conlock=1;
+ FCEUI_DispMessage("Console locked.");
+ }
+}
+
+void UnlockConsole(void)
+{
+ if(conlock)
+ {
+ vga_unlockvc();
+ conlock=0;
+ FCEUI_DispMessage("Console unlocked.");
+ }
+}
+
+void SetBorder(void)
+{
+ if(!conlock)
+ vga_lockvc();
+ inportb(0x3da);
+ outportb(0x3c0,(0x11|0x20));
+ outportb(0x3c0,0x80);
+ if(!conlock)
+ vga_unlockvc();
+}
+
+#include "vgatweak.c"
+
+void TweakVGA(int VGAMode)
+{
+ int I;
+
+ if(!conlock)
+ vga_lockvc();
+
+ outportb(0x3C8,0x00);
+ for(I=0;I<768;I++) outportb(0x3C9,0x00);
+
+ outportb(0x3D4,0x11);
+ I=inportb(0x3D5)&0x7F;
+ outportb(0x3D4,0x11);
+ outportb(0x3D5,I);
+
+ switch(VGAMode)
+ {
+ case 1: for(I=0;I<25;I++) VGAPortSet(v256x240[I]);break;
+ case 2: for(I=0;I<25;I++) VGAPortSet(v256x256[I]);break;
+ case 3: for(I=0;I<25;I++) VGAPortSet(v256x256S[I]);break;
+ case 6: for(I=0;I<25;I++) VGAPortSet(v256x224S[I]);break;
+ case 8: for(I=0;I<25;I++) VGAPortSet(v256x224_103[I]);break;
+ default: break;
+ }
+
+ outportb(0x3da,0);
+ if(!conlock)
+ vga_unlockvc();
+}
+
+
+static uint8 palettedbr[256],palettedbg[256],palettedbb[256];
+
+static void FlushPalette(void)
+{
+ int x;
+ for(x=0;x<256;x++)
+ {
+ int z=x;
+ if(vmode==4 || vmode==5 || vmode==7) z^=0x80;
+ vga_setpalette(z,palettedbr[x]>>2,palettedbg[x]>>2,palettedbb[x]>>2);
+ }
+}
+
+void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
+{
+ palettedbr[index]=r;
+ palettedbg[index]=g;
+ palettedbb[index]=b;
+
+ if(vidready)
+ {
+ if(vmode==4 || vmode==5 || vmode==7) index^=0x80;
+ vga_setpalette(index,r>>2,g>>2,b>>2);
+ }
+}
+
+
+void FCEUD_GetPalette(uint8 i, uint8 *r, uint8 *g, uint8 *b)
+{
+ *r=palettedbr[i];
+ *g=palettedbg[i];
+ *b=palettedbb[i];
+}
+
+static void vcfix(void)
+{
+ int z;
+
+ if(!conlock)
+ vga_lockvc();
+ z=inportb(0x3cc);
+ if(!conlock)
+ vga_unlockvc();
+ if(z!=0xe3 && z!=0xe7) // Common value in all tweaked video modes(and not in 320x200 mode).
+ {
+ TweakVGA(vmode);
+ SetBorder();
+ FlushPalette();
+ }
+}
+
+static uint8 *ScreenLoc;
+
+int InitVideo(void)
+{
+ #ifdef DUMMY
+ return(1);
+ #endif
+ vidready=0;
+
+ if(vmode<=3 || vmode==6 || vmode==8)
+ {
+ if(vga_getcurrentchipset()==FBDEV)
+ {
+ puts("Tweaked VGA video modes will not work. Using a 320x240 video mode instead...");
+ vmode=7;
+ }
+ }
+
+ switch(vmode)
+ {
+ default:
+ case 1:
+ case 2:
+ case 3:
+ case 6:
+ case 8:
+ vga_setmode(G320x200x256);
+ vidready|=1;
+ ScreenLoc=vga_getgraphmem();
+ TweakVGA(vmode);
+ SetBorder();
+ memset(ScreenLoc,128,256*256);
+ break;
+ case 4:
+ case 5:
+ if(!(vga_getmodeinfo(G640x480x256)->flags & CAPABLE_LINEAR))
+ {
+ puts("Video: No linear addressing mode available!");
+ return 0;
+ }
+ if(vga_setmode(G640x480x256)==-1)
+ {
+ puts("Video: Could not set 640x480x8bpp video mode!");
+ return 0;
+ }
+ vidready|=1;
+
+ vga_setpage(0);
+ if(vga_setlinearaddressing()!=-1)
+ ScreenLoc=vga_getgraphmem();
+ else
+ {
+ puts("Video: Could not set linear addressing!");
+ return 0;
+ }
+ memset(ScreenLoc,0,640*480);
+ break;
+ case 7:
+ if(!(vga_getmodeinfo(G320x240x256V)->flags & CAPABLE_LINEAR))
+ {
+ puts("Video: No linear addressing mode available!");
+ return 0;
+ }
+ if(vga_setmode(G320x240x256V)==-1)
+ {
+ puts("Video: Could not set 320x240x8bpp video mode!");
+ return 0;
+ }
+ vidready|=1;
+
+ vga_setpage(0);
+ if(vga_setlinearaddressing()!=-1)
+ ScreenLoc=vga_getgraphmem();
+ else
+ {
+ puts("Video: Could not set linear addressing!");
+ return 0;
+ }
+ memset(ScreenLoc,0,320*240);
+ break;
+ }
+ vidready|=2;
+ FlushPalette(); // Needed for cheat console code(and it isn't a bad thing to do anyway...).
+ return 1;
+}
+
+void KillVideo(void)
+{
+ if(vidready)
+ {
+ vga_setmode(TEXT);
+ vidready=0;
+ }
+}
+
+
+void BlitScreen(uint8 *XBuf)
+{
+ static int conto=0;
+ uint8 *dest;
+ int tlines;
+ #ifdef DUMMY
+ return;
+ #endif
+ #ifdef FRAMESKIP
+ FCEUI_FrameSkip(FCEUDfskip);
+ #endif
+
+ if(doptions&DO_VSYNC && !NoWaiting)
+ {
+ vga_waitretrace();
+ }
+
+ tlines=erendline-srendline+1;
+
+ dest=ScreenLoc;
+
+ if(vmode!=4 && vmode!=5 && vmode!=7)
+ {
+ conto=(conto+1)&0x3F;
+ if(!conto) vcfix();
+ }
+ switch(vmode)
+ {
+ case 1:dest+=(((240-tlines)>>1)<<8);break;
+ case 2:
+ case 3:dest+=(((256-tlines)>>1)<<8);break;
+ case 4:
+ case 5:dest+=(((240-tlines)>>1)*640+((640-512)>>1));break;
+ case 8:
+ case 6:if(tlines>224) tlines=224;dest+=(((224-tlines)>>1)<<8);break;
+ case 7:dest+=(((240-tlines)>>1)*320)+32;break;
+ }
+
+ XBuf+=(srendline<<8)+(srendline<<4);
+
+ if(eoptions&EO_CLIPSIDES)
+ {
+ if(vmode==5)
+ {
+ asm volatile(
+ "xorl %%edx, %%edx\n\t"
+ "ckoop1:\n\t"
+ "movb $120,%%al \n\t"
+ "ckoop2:\n\t"
+ "movb 1(%%esi),%%dl\n\t"
+ "shl $16,%%edx\n\t"
+ "movb (%%esi),%%dl\n\t"
+ "xorl $0x00800080,%%edx\n\t"
+ "movl %%edx,(%%edi)\n\t"
+ "addl $2,%%esi\n\t"
+ "addl $4,%%edi\n\t"
+ "decb %%al\n\t"
+ "jne ckoop2\n\t"
+
+ "addl $32,%%esi\n\t"
+ "addl $800,%%edi\n\t"
+ "decb %%bl\n\t"
+ "jne ckoop1\n\t"
+ :
+ : "S" (XBuf+8), "D" (dest+8), "b" (tlines)
+ : "%al", "%edx", "%cc" );
+ }
+ else if(vmode==4)
+ {
+ asm volatile(
+ "cyoop1:\n\t"
+ "movb $120,%%al \n\t"
+ "cyoop2:\n\t"
+ "movb 1(%%esi),%%dh\n\t"
+ "movb %%dh,%%dl\n\t"
+ "shl $16,%%edx\n\t"
+ "movb (%%esi),%%dl\n\t"
+ "movb %%dl,%%dh\n\t" // Ugh
+ "xorl $0x80808080,%%edx\n\t"
+ "movl %%edx,(%%edi)\n\t"
+ "addl $2,%%esi\n\t"
+ "addl $4,%%edi\n\t"
+ "decb %%al\n\t"
+ "jne cyoop2\n\t"
+
+ "addl $32,%%esi\n\t"
+ "addl $800,%%edi\n\t"
+ "decb %%bl\n\t"
+ "jne cyoop1\n\t"
+ :
+ : "S" (XBuf+8), "D" (dest+8), "b" (tlines)
+ : "%al", "%edx", "%cc" );
+ }
+ else if(vmode==7)
+ {
+ asm volatile(
+ "cgoop81:\n\t"
+ "movl $30,%%eax\n\t"
+ "cgoop82:\n\t"
+ "movl (%%esi),%%edx\n\t"
+ "movl 4(%%esi),%%ecx\n\t"
+ "xorl $0x80808080,%%edx\n\t"
+ "xorl $0x80808080,%%ecx\n\t"
+ "movl %%edx,(%%edi)\n\t"
+ "movl %%ecx,4(%%edi)\n\t"
+ "addl $8,%%esi\n\t"
+ "addl $8,%%edi\n\t"
+ "decl %%eax\n\t"
+ "jne cgoop82\n\t"
+ "addl $80,%%edi\n\t"
+ "addl $32,%%esi\n\t"
+ "decb %%bl\n\t"
+ "jne cgoop81\n\t"
+ :
+ : "S" (XBuf+8), "D" (dest+8), "b" (tlines)
+ : "%eax","%cc","%edx","%ecx" );
+ }
+ else
+ {
+ asm volatile(
+ "cgoop1:\n\t"
+ "movl $30,%%eax\n\t"
+ "cgoop2:\n\t"
+ "movl (%%esi),%%edx\n\t"
+ "movl 4(%%esi),%%ecx\n\t"
+ "movl %%edx,(%%edi)\n\t"
+ "movl %%ecx,4(%%edi)\n\t"
+ "addl $8,%%esi\n\t"
+ "addl $8,%%edi\n\t"
+ "decl %%eax\n\t"
+ "jne cgoop2\n\t"
+ "addl $32,%%esi\n\t"
+ "addl $16,%%edi\n\t"
+ "decb %%bl\n\t"
+ "jne cgoop1\n\t"
+ :
+ : "S" (XBuf+8), "D" (dest+8), "b" (tlines)
+ : "%eax","%cc","%edx","%ecx" );
+ }
+ }
+ else
+ {
+ if(vmode==5)
+ {
+ asm volatile(
+ "xorl %%edx, %%edx\n\t"
+ "koop1:\n\t"
+ "movb $128,%%al \n\t"
+ "koop2:\n\t"
+ "movb 1(%%esi),%%dl\n\t"
+ "shl $16,%%edx\n\t"
+ "movb (%%esi),%%dl\n\t"
+ "xorl $0x00800080,%%edx\n\t"
+ "movl %%edx,(%%edi)\n\t"
+ "addl $2,%%esi\n\t"
+ "addl $4,%%edi\n\t"
+ "decb %%al\n\t"
+ "jne koop2\n\t"
+
+ "addl $16,%%esi\n\t"
+ "addl $768,%%edi\n\t"
+ "decb %%bl\n\t"
+ "jne koop1\n\t"
+ :
+ : "S" (XBuf), "D" (dest), "b" (tlines)
+ : "%al", "%edx", "%cc" );
+ }
+ else if(vmode==4)
+ {
+ asm volatile(
+ "yoop1:\n\t"
+ "movb $128,%%al \n\t"
+ "yoop2:\n\t"
+ "movb 1(%%esi),%%dh\n\t"
+ "movb %%dh,%%dl\n\t"
+ "shl $16,%%edx\n\t"
+ "movb (%%esi),%%dl\n\t"
+ "movb %%dl,%%dh\n\t" // Ugh
+ "xorl $0x80808080,%%edx\n\t"
+ "movl %%edx,(%%edi)\n\t"
+ "addl $2,%%esi\n\t"
+ "addl $4,%%edi\n\t"
+ "decb %%al\n\t"
+ "jne yoop2\n\t"
+
+ "addl $16,%%esi\n\t"
+ "addl $768,%%edi\n\t"
+ "decb %%bl\n\t"
+ "jne yoop1\n\t"
+ :
+ : "S" (XBuf), "D" (dest), "b" (tlines)
+ : "%al", "%edx", "%cc" );
+ }
+ else if(vmode==7)
+ {
+ asm volatile(
+ "goop81:\n\t"
+ "movl $32,%%eax\n\t"
+ "goop82:\n\t"
+ "movl (%%esi),%%edx\n\t"
+ "movl 4(%%esi),%%ecx\n\t"
+ "xorl $0x80808080,%%edx\n\t"
+ "xorl $0x80808080,%%ecx\n\t"
+ "movl %%edx,(%%edi)\n\t"
+ "movl %%ecx,4(%%edi)\n\t"
+ "addl $8,%%esi\n\t"
+ "addl $8,%%edi\n\t"
+ "decl %%eax\n\t"
+ "jne goop82\n\t"
+ "addl $64,%%edi\n\t"
+ "addl $16,%%esi\n\t"
+ "decb %%bl\n\t"
+ "jne goop81\n\t"
+ :
+ : "S" (XBuf), "D" (dest), "b" (tlines)
+ : "%eax","%cc","%edx","%ecx" );
+ }
+ else
+ {
+ asm volatile(
+ "goop1:\n\t"
+ "movl $32,%%eax\n\t"
+ "goop2:\n\t"
+ "movl (%%esi),%%edx\n\t"
+ "movl 4(%%esi),%%ecx\n\t"
+ "movl %%edx,(%%edi)\n\t"
+ "movl %%ecx,4(%%edi)\n\t"
+ "addl $8,%%esi\n\t"
+ "addl $8,%%edi\n\t"
+ "decl %%eax\n\t"
+ "jne goop2\n\t"
+ "addl $16,%%esi\n\t"
+ "decb %%bl\n\t"
+ "jne goop1\n\t"
+ :
+ : "S" (XBuf), "D" (dest), "b" (tlines)
+ : "%eax","%cc","%edx","%ecx" );
+ }
+ }
+}
+
+
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+extern int vmode;
+
+#ifdef FRAMESKIP
+extern int FCEUDfskip;
+#endif
+
+void LockConsole(void);
+void UnlockConsole(void);
+int InitVideo(void);
+void KillVideo(void);
+void FCEUD_BlitScreen(uint8 *XBuf);
+
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vga.h>
+#include <vgamouse.h>
+#include <vgakeyboard.h>
+
+#include "../../driver.h"
+#include "../common/args.h"
+#include "../common/config.h"
+#include "../common/unixdsp.h"
+
+#include "svgalib.h"
+#include "svga-video.h"
+#include "lnx-joystick.h"
+#include "unix-netplay.h"
+
+static int soundo=48000;
+static int f8bit=0;
+static int sfragsize=7,snfrags=8;
+
+int doptions=0;
+
+CFGSTRUCT DriverConfig[]={
+ NAC("sound",soundo),
+ AC(doptions),
+ AC(f8bit),
+ AC(vmode),
+ NACA("joybmap",joyBMap),
+ ACA(joy),
+ AC(snfrags),
+ AC(sfragsize),
+ ENDCFGSTRUCT
+};
+
+
+char *DriverUsage=
+"-vmode x Select video mode(all are 8 bpp).\n\
+ 1 = 256x240 5 = 640x480(\"1 per 4\")\n\
+ 2 = 256x256 6 = 256x224(with scanlines)\n\
+ 3 = 256x256(with scanlines) 7 = 320x240\n\
+ 4 = 640x480(with scanlines) 8 = 256x224\n\
+-vsync x Wait for the screen's vertical retrace before updating the\n\
+ screen. Refer to the documentation for caveats.\n\
+ 0 = Disabled.\n\
+ 1 = Enabled.\n\
+-joyx y Joystick mapped to virtual joystick x(1-4).\n\
+ 0 = Disabled, reset configuration.\n\
+ Otherwise, y(1-inf) = joystick number.\n\
+-sound x Sound.\n\
+ 0 = Disabled.\n\
+ Otherwise, x = playback rate.\n\
+-sfragsize x Set sound fragment size to 2^x samples.\n\
+-snfrags x Set number of sound fragments to x.\n\
+-f8bit x Force 8-bit sound.\n\
+ 0 = Disabled.\n\
+ 1 = Enabled.\n\
+-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.";
+
+
+static int docheckie[2]={0,0};
+ARGPSTRUCT DriverArgs[]={
+ {"-joy1",0,&joy[0],0},{"-joy2",0,&joy[1],0},
+ {"-joy3",0,&joy[2],0},{"-joy4",0,&joy[3],0},
+ {"-snfrags",0,&snfrags,0},{"-sfragsize",0,&sfragsize,0},
+ {"-vmode",0,&vmode,0},
+ {"-vsync",0,&doptions,0x8000|DO_VSYNC},
+ {"-sound",0,&soundo,0},
+ {"-f8bit",0,&f8bit,0},
+ {"-connect",&docheckie[0],&netplayhost,0x4001},
+ {"-server",&docheckie[1],0,0},
+ {"-netport",0,&Port,0},
+ {0,0,0,0}
+};
+
+void DoDriverArgs(void)
+{
+ int x;
+
+ if(docheckie[0])
+ netplay=2;
+ else if(docheckie[1])
+ netplay=1;
+
+ if(netplay)
+ FCEUI_SetNetworkPlay(netplay);
+
+ for(x=0;x<4;x++)
+ if(!joy[x]) memset(joyBMap[x],0,4*sizeof(int));
+}
+
+int InitSound(void)
+{
+ if(soundo)
+ {
+ int rate;
+ if(soundo==1)
+ soundo=48000;
+ rate=soundo;
+ if(InitUNIXDSPSound(&rate,f8bit?0:1,sfragsize,snfrags))
+ {
+ FCEUI_Sound(rate);
+ return(1);
+ }
+ }
+ return(0);
+}
+
+void WriteSound(int32 *Buffer, int Count, int NoWaiting)
+{
+ WriteUNIXDSPSound(Buffer,Count,NoWaiting);
+}
+
+void KillSound(void)
+{
+ KillUNIXDSPSound();
+}
+
+int InitMouse(void)
+{
+ vga_setmousesupport(1);
+ mouse_setxrange(0,260);
+ mouse_setyrange(0,260);
+ mouse_setscale(1);
+ return(1);
+}
+
+void KillMouse(void)
+{
+ mouse_close();
+}
+
+void GetMouseData(uint32 *MouseData)
+{
+ int z;
+ mouse_update();
+ MouseData[0]=mouse_getx();
+ MouseData[1]=mouse_gety();
+ z=mouse_getbutton();
+ MouseData[2]=((z&MOUSE_LEFTBUTTON)?1:0)|((z&MOUSE_RIGHTBUTTON)?2:0);
+}
+
+#include "unix-basedir.h"
+
+int InitKeyboard(void)
+{
+ if(keyboard_init()==-1)
+ {
+ puts("Error initializing keyboard.");
+ return 0;
+ }
+ keyboard_translatekeys(TRANSLATE_CURSORKEYS | TRANSLATE_DIAGONAL);
+ return 1;
+}
+
+int UpdateKeyboard(void)
+{
+ return(keyboard_update());
+}
+
+char *GetKeyboard(void)
+{
+ return(keyboard_getstate());
+}
+
+void KillKeyboard(void)
+{
+ keyboard_close();
+}
+
+int main(int argc, char *argv[])
+{
+ puts("\nStarting FCE Ultra "VERSION_STRING"...\n");
+ vga_init();
+ return(CLImain(argc,argv));
+}
--- /dev/null
+#define DO_VSYNC 1
+extern int doptions;
--- /dev/null
+#include <sys/time.h>
+#include <unistd.h>
+#include "main.h"
+#include "throttle.h"
+
+static uint64 tfreq;
+static uint64 desiredfps;
+
+void RefreshThrottleFPS(void)
+{
+ desiredfps=FCEUI_GetDesiredFPS()>>8;
+ tfreq=1000000;
+ tfreq<<=16; /* Adjustment for fps returned from FCEUI_GetDesiredFPS(). */
+}
+
+static uint64 GetCurTime(void)
+{
+ uint64 ret;
+ struct timeval tv;
+
+ gettimeofday(&tv,0);
+ ret=(uint64)tv.tv_sec*1000000;
+ ret+=tv.tv_usec;
+ return(ret);
+}
+
+void SpeedThrottle(void)
+{
+ static uint64 ttime,ltime;
+
+ waiter:
+
+ ttime=GetCurTime();
+
+ if( (ttime-ltime) < (tfreq/desiredfps) )
+ {
+ usleep(1000);
+ goto waiter;
+ }
+ if( (ttime-ltime) >= (tfreq*4/desiredfps))
+ ltime=ttime;
+ else
+ ltime+=tfreq/desiredfps;
+}
+
--- /dev/null
+void RefreshThrottleFPS(void);
+void SpeedThrottle(void);
--- /dev/null
+#include <stdlib.h>
+void GetBaseDirectory(char *BaseDirectory)
+{
+ char *ol;
+
+ ol=getenv("HOME");
+ BaseDirectory[0]=0;
+ if(ol)
+ {
+ strncpy(BaseDirectory,ol,2047);
+ BaseDirectory[2047]=0;
+ strcat(BaseDirectory,"/.fceultra");
+ }
+}
+
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <errno.h>
+
+#ifndef socklen_t
+#define socklen_t int
+#endif
+
+static int Socket=-1;
+#include "main.h"
+#include "unix-netplay.h"
+
+char *netplayhost=0;
+int Port=0xFCE;
+int netplay=0;
+
+int FCEUD_NetworkConnect(void)
+{
+ struct sockaddr_in sockn;
+ int TSocket;
+
+ memset(&sockn,0,sizeof(sockn));
+ sockn.sin_family=AF_INET;
+ sockn.sin_port=htons(Port);
+
+ if((TSocket=socket(AF_INET, SOCK_STREAM, 0))<0)
+ {
+ puts("Error creating socket.");
+ return(0);
+ }
+
+ if(netplay==1) /* Be a server. */
+ {
+ sockn.sin_addr.s_addr=INADDR_ANY;
+ if(bind(TSocket, (struct sockaddr *)&sockn, sizeof(sockn))<0)
+ {
+ close(TSocket);
+ puts("Error binding to socket.");
+ return(0);
+ }
+ if(listen(TSocket, 1)<0)
+ {
+ puts("Error listening on socket.");
+ close(TSocket);
+ return(0);
+ }
+ {
+ socklen_t len=sizeof(sockn);
+
+ printf("Accepting connection on port %d...\n",Port);
+ if((Socket=accept(TSocket,(struct sockaddr *)&sockn,&len))<0 )
+ {
+ puts("Error accepting a connection.");
+ close(TSocket);
+ return(0);
+ }
+ close(TSocket);
+ }
+
+ }
+ else /* Connect as a client if not a server. */
+ {
+ struct hostent *Host;
+
+ if((sockn.sin_addr.s_addr=inet_addr(netplayhost))==INADDR_NONE)
+ {
+ if(!(Host=gethostbyname(netplayhost)))
+ {
+ puts("Error getting network host entry.");
+ return(0);
+ }
+ memcpy(&sockn.sin_addr,Host->h_addr,Host->h_length);
+ }
+ printf("Attempting to connect to %s...\n",netplayhost);
+ if( connect(TSocket, (struct sockaddr *)&sockn, sizeof(sockn)) <0 )
+ {
+ puts("Error connecting to remote host.");
+ close(TSocket);
+ return(0);
+ }
+ Socket=TSocket;
+ }
+ return(1);
+}
+
+/* 0 on failure, 1 on success, -1 if it would block and blocking is not
+ specified.
+*/
+
+int FCEUD_NetworkRecvData(uint8 *data, uint32 len, int block)
+{
+ if(block)
+ {
+ int t;
+ uint8 temp[32];
+ t=recv(Socket,temp,32,MSG_PEEK|MSG_DONTWAIT);
+ if(t==-1)
+ {
+ if(errno!=EAGAIN) return(0);
+ }
+ else if(t==32)
+ NoWaiting|=2;
+ else
+ NoWaiting&=~2;
+ return(recv(Socket,data,len,0)==len);
+ }
+ else
+ {
+ int t=recv(Socket,data,len,MSG_DONTWAIT);
+ if(t==-1)
+ {
+ if(errno==EAGAIN) // Would block
+ return(-1);
+ return(0);
+ }
+ return(1);
+ }
+}
+
+/* 0 on failure, 1 on success. This function should always block. */
+
+int FCEUD_NetworkSendData(uint8 *Value, uint32 len)
+{
+ return(send(Socket,Value,len,0)==len);
+}
+
+void FCEUD_NetworkClose(void)
+{
+ if(Socket>0)
+ close(Socket);
+ Socket=-1;
+}
+
--- /dev/null
+extern char *netplayhost;
+extern int Port;
+extern int FDnetplay;
+#define netplay FDnetplay
+
--- /dev/null
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ * Copyright (C) 2002 Ben Parnell
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+void ShowUsage(char *prog)
+{
+printf("\nUsage is as follows:\n%s <options> filename\n\n",prog);
+puts("Options:");
+puts(DriverUsage);
+puts("-cpalette x Load a custom global palette from file x.\n\
+-ntsccol x Emulate an NTSC's TV's colors.\n\
+ 0 = Disabled.\n\
+ 1 = Enabled.\n\
+-pal Emulate a PAL NES.\n\
+-soundvol x Sound volume. x is an integral percentage value.\n\
+-inputx str Select device mapped to virtual input port x(1-2).\n\
+ str may be: none, gamepad, zapper, powerpada, powerpadb,\n\
+ arkanoid\n\
+-fcexp str Select Famicom expansion port device.\n\
+ str may be: none, shadow, arkanoid, 4player, fkb\n\
+-nofs x Disables Four-Score emulation if x is 1.\n\
+-gg Enable Game Genie emulation.\n\
+-no8lim x Disables the 8 sprites per scanline limitation.\n\
+ 0 = Limitation enabled.\n\
+ 1 = Limitation disabled.\n\
+-subase x Save extra game data files under the base directory if enabled.\n\
+ 0 = Disabled.\n\
+ 1 = Enabled.\n\
+-snapname x Selects what type of file name snapshots will have.\n\
+ 0 = Numeric(0.png)\n\
+ 1 = File base and numeric(mario-0.png)\n\
+-nothrottle x Disable artificial speed throttling if x is non-zero.\n\
+-clipsides x Clip leftmost and rightmost 8 columns of pixels of video output.\n\
+ 0 = No clipping.\n\
+ 1 = Clipping.\n\
+-slstart x Set the first drawn emulated scanline. Valid values for x are\n\
+ 0 through 239.\n\
+-slend x Set the last drawn emulated scanline. Valid values for x are\n\
+ 0 through 239.");
+}
--- /dev/null
+/* This file is "#include"d from dos-video.c and svga-video.c */
+
+typedef struct {
+ uint8 p;
+ uint8 i;
+ uint8 v;
+} vgareg;
+
+vgareg v256x224_103[25] =
+{
+ { 0xc2, 0x0, 0xe7},
+ { 0xd4, 0x0, 0x45},
+ { 0xd4, 0x1, 0x3f},
+ { 0xd4, 0x2, 0x40},
+ { 0xd4, 0x3, 0x86},
+ { 0xd4, 0x4, 0x3f},
+ { 0xd4, 0x5, 0x10},
+ { 0xd4, 0x6, 0xcd},
+ { 0xd4, 0x7, 0x1f},
+ { 0xd4, 0x8, 0x0},
+ { 0xd4, 0x9, 0x41},
+ { 0xd4, 0x10, 0xc0},
+ { 0xd4, 0x11, 0xac},
+ { 0xd4, 0x12, 0xbf},
+ { 0xd4, 0x13, 0x20},
+ { 0xd4, 0x14, 0x40}, //
+ { 0xd4, 0x15, 0xe7},
+ { 0xd4, 0x16, 0x06}, //
+ { 0xd4, 0x17, 0xa3},
+ { 0xc4, 0x1, 0x1},
+ { 0xc4, 0x4, 0xe}, //
+ { 0xce, 0x5, 0x40},
+ { 0xce, 0x6, 0x5},
+ { 0xc0, 0x10, 0x41},
+ { 0xc0, 0x13, 0x0},
+};
+
+vgareg v256x240[25] =
+{
+ { 0xc2, 0x0, 0xe3},
+ { 0xd4, 0x0, 0x4f},
+ { 0xd4, 0x1, 0x3f},
+ { 0xd4, 0x2, 0x40},
+ { 0xd4, 0x3, 0x92},
+ { 0xd4, 0x4, 0x44},
+ { 0xd4, 0x5, 0x10},
+ { 0xd4, 0x6, 0x0a},
+ { 0xd4, 0x7, 0x3e},
+ { 0xd4, 0x8, 0x00},
+ { 0xd4, 0x9, 0x41},
+ { 0xd4, 0x10, 0xea},
+ { 0xd4, 0x11, 0xac},
+ { 0xd4, 0x12, 0xdf},
+ { 0xd4, 0x13, 0x20},
+ { 0xd4, 0x14, 0x40},
+ { 0xd4, 0x15, 0xe7},
+ { 0xd4, 0x16, 0x06},
+ { 0xd4, 0x17, 0xa3},
+ { 0xc4, 0x1, 0x1},
+ { 0xc4, 0x4, 0xe},
+ { 0xce, 0x5, 0x40},
+ { 0xce, 0x6, 0x5},
+ { 0xc0, 0x10, 0x41},
+ { 0xc0, 0x13, 0x0}
+};
+
+vgareg v256x224S[25] =
+{
+ { 0xc2, 0x0, 0xe3},
+ { 0xd4, 0x0, 0x5f},
+ { 0xd4, 0x1, 0x3f},
+ { 0xd4, 0x2, 0x40},
+ { 0xd4, 0x3, 0x82},
+ { 0xd4, 0x4, 0x4e},
+ { 0xd4, 0x5, 0x96},
+ { 0xd4, 0x6, 0x5},
+ { 0xd4, 0x7, 0x1},
+ { 0xd4, 0x8, 0x0},
+ { 0xd4, 0x9, 0x40},
+ { 0xd4, 0x10, 0xea},
+ { 0xd4, 0x11, 0xac},
+ { 0xd4, 0x12, 0xdf},
+ { 0xd4, 0x13, 0x20},
+ { 0xd4, 0x14, 0x40},
+ { 0xd4, 0x15, 0xe7},
+ { 0xd4, 0x16, 0x0},
+ { 0xd4, 0x17, 0xe3},
+ { 0xc4, 0x1, 0x1},
+ { 0xc4, 0x4, 0xe},
+ { 0xce, 0x5, 0x40},
+ { 0xce, 0x6, 0x5},
+ { 0xc0, 0x10, 0x41},
+ { 0xc0, 0x13, 0x0}
+};
+
+vgareg v256x256[25] =
+{
+ { 0xc2, 0x0, 0xe7},
+ { 0xd4, 0x0, 0x5f},
+ { 0xd4, 0x1, 0x3f},
+ { 0xd4, 0x2, 0x40},
+ { 0xd4, 0x3, 0x82},
+ { 0xd4, 0x4, 0x4a},
+ { 0xd4, 0x5, 0x9a},
+ { 0xd4, 0x6, 0x23},
+ { 0xd4, 0x7, 0xb2},
+ { 0xd4, 0x8, 0x0},
+ { 0xd4, 0x9, 0x61},
+ { 0xd4, 0x10, 0xa},
+ { 0xd4, 0x11, 0xac},
+ { 0xd4, 0x12, 0xff},
+ { 0xd4, 0x13, 0x20},
+ { 0xd4, 0x14, 0x40},
+ { 0xd4, 0x15, 0x7},
+ { 0xd4, 0x16, 0x1a},
+ { 0xd4, 0x17, 0xa3},
+ { 0xc4, 0x1, 0x1},
+ { 0xc4, 0x4, 0xe},
+ { 0xce, 0x5, 0x40},
+ { 0xce, 0x6, 0x5},
+ { 0xc0, 0x10, 0x41},
+ { 0xc0, 0x13, 0x0}
+};
+
+vgareg v256x256S[25] =
+{
+ { 0xc2, 0x00, 0xe7},{ 0xd4, 0x00, 0x5F},{ 0xd4, 0x01, 0x3f},
+ { 0xd4, 0x02, 0x40},{ 0xd4, 0x03, 0x82},{ 0xd4, 0x04, 0x4a},
+ { 0xd4, 0x05, 0x9a},{ 0xd4, 0x06, 0x25},{ 0xd4, 0x07, 0x15},
+ { 0xd4, 0x08, 0x00},{ 0xd4, 0x09, 0x60},{ 0xd4, 0x10, 0x0a},
+ { 0xd4, 0x11, 0xac},{ 0xd4, 0x12, 0xff},{ 0xd4, 0x13, 0x20},
+ { 0xd4, 0x14, 0x40},{ 0xd4, 0x15, 0x07},{ 0xd4, 0x16, 0x1a},
+ { 0xd4, 0x17, 0xa3},{ 0xc4, 0x01, 0x01},{ 0xc4, 0x04, 0x0e},
+ { 0xce, 0x05, 0x40},{ 0xce, 0x06, 0x05},{ 0xc0, 0x10, 0x41},
+ { 0xc0, 0x13, 0x00}
+};
+
+static void VGAPortSet(vgareg R)
+{
+ int p,i,v;
+
+ p=0x300|R.p;
+ i=R.i;
+ v=R.v;
+
+ switch(p)
+ {
+ case 0x3C0: inportb(0x3DA);
+ outportb(0x3C0,i);
+ outportb(0x3C0,v);
+ break;
+ case 0x3C2:
+ case 0x3C3:
+ default: outportb(p, v);
+ break;
+ case 0x3C4: if(i==1)
+ {
+ outportw(0x3c4,0x100);
+ outportw(0x3c4,(v<<8)|1);
+ outportw(0x3c4,0x300);
+ break;
+ }
+ case 0x3CE:
+ case 0x3D4: outportw(p,i|(v<<8));
+ break;
+ }
+}
+