From 63bd5be0436de94860a00c34048fa4c6c131ece3 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 30 Apr 2007 23:53:52 +0000 Subject: [PATCH] cli added for debug git-svn-id: file:///home/notaz/opt/svn/fceu@122 be3aeb3a-fb24-0410-a615-afba39da0efa --- Makefile.cli | 46 +++ drivers/cli/dface.h | 32 +++ drivers/cli/dos-joystick.c | 190 +++++++++++++ drivers/cli/dos-joystick.h | 27 ++ drivers/cli/dos-keyboard.c | 131 +++++++++ drivers/cli/dos-mouse.c | 77 +++++ drivers/cli/dos-sound.c | 567 +++++++++++++++++++++++++++++++++++++ drivers/cli/dos-sound.h | 26 ++ drivers/cli/dos-video.c | 246 ++++++++++++++++ drivers/cli/dos-video.h | 22 ++ drivers/cli/dos.c | 128 +++++++++ drivers/cli/dos.h | 28 ++ drivers/cli/input.c | 340 ++++++++++++++++++++++ drivers/cli/keyscan.h | 166 +++++++++++ drivers/cli/lnx-joystick.c | 201 +++++++++++++ drivers/cli/lnx-joystick.h | 3 + drivers/cli/main.c | 377 ++++++++++++++++++++++++ drivers/cli/main.h | 30 ++ drivers/cli/sdl-joystick.c | 200 +++++++++++++ drivers/cli/sdl-netplay.c | 163 +++++++++++ drivers/cli/sdl-netplay.h | 5 + drivers/cli/sdl-sound.c | 148 ++++++++++ drivers/cli/sdl-video.c | 228 +++++++++++++++ drivers/cli/sdl-video.h | 1 + drivers/cli/sdl.c | 216 ++++++++++++++ drivers/cli/sdl.h | 47 +++ drivers/cli/svga-video.c | 497 ++++++++++++++++++++++++++++++++ drivers/cli/svga-video.h | 32 +++ drivers/cli/svgalib.c | 178 ++++++++++++ drivers/cli/svgalib.h | 2 + drivers/cli/throttle.c | 45 +++ drivers/cli/throttle.h | 2 + drivers/cli/unix-basedir.h | 15 + drivers/cli/unix-netplay.c | 159 +++++++++++ drivers/cli/unix-netplay.h | 5 + drivers/cli/usage.h | 56 ++++ drivers/cli/vgatweak.c | 168 +++++++++++ 37 files changed, 4804 insertions(+) create mode 100644 Makefile.cli create mode 100644 drivers/cli/dface.h create mode 100644 drivers/cli/dos-joystick.c create mode 100644 drivers/cli/dos-joystick.h create mode 100644 drivers/cli/dos-keyboard.c create mode 100644 drivers/cli/dos-mouse.c create mode 100644 drivers/cli/dos-sound.c create mode 100644 drivers/cli/dos-sound.h create mode 100644 drivers/cli/dos-video.c create mode 100644 drivers/cli/dos-video.h create mode 100644 drivers/cli/dos.c create mode 100644 drivers/cli/dos.h create mode 100644 drivers/cli/input.c create mode 100644 drivers/cli/keyscan.h create mode 100644 drivers/cli/lnx-joystick.c create mode 100644 drivers/cli/lnx-joystick.h create mode 100644 drivers/cli/main.c create mode 100644 drivers/cli/main.h create mode 100644 drivers/cli/sdl-joystick.c create mode 100644 drivers/cli/sdl-netplay.c create mode 100644 drivers/cli/sdl-netplay.h create mode 100644 drivers/cli/sdl-sound.c create mode 100644 drivers/cli/sdl-video.c create mode 100644 drivers/cli/sdl-video.h create mode 100644 drivers/cli/sdl.c create mode 100644 drivers/cli/sdl.h create mode 100644 drivers/cli/svga-video.c create mode 100644 drivers/cli/svga-video.h create mode 100644 drivers/cli/svgalib.c create mode 100644 drivers/cli/svgalib.h create mode 100644 drivers/cli/throttle.c create mode 100644 drivers/cli/throttle.h create mode 100644 drivers/cli/unix-basedir.h create mode 100644 drivers/cli/unix-netplay.c create mode 100644 drivers/cli/unix-netplay.h create mode 100644 drivers/cli/usage.h create mode 100644 drivers/cli/vgatweak.c diff --git a/Makefile.cli b/Makefile.cli new file mode 100644 index 0000000..373e2c6 --- /dev/null +++ b/Makefile.cli @@ -0,0 +1,46 @@ +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 + diff --git a/drivers/cli/dface.h b/drivers/cli/dface.h new file mode 100644 index 0000000..6ff4459 --- /dev/null +++ b/drivers/cli/dface.h @@ -0,0 +1,32 @@ +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 */ diff --git a/drivers/cli/dos-joystick.c b/drivers/cli/dos-joystick.c new file mode 100644 index 0000000..3729187 --- /dev/null +++ b/drivers/cli/dos-joystick.c @@ -0,0 +1,190 @@ +/* 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +#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<=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); +} + diff --git a/drivers/cli/dos-joystick.h b/drivers/cli/dos-joystick.h new file mode 100644 index 0000000..6cfaee5 --- /dev/null +++ b/drivers/cli/dos-joystick.h @@ -0,0 +1,27 @@ +/* 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 UpdateJoyData(void); +uint32 GetJSOr(void); +int InitJoysticks(void); + +/* Variables to save in config file. */ +extern int joy; +extern int joyBMap[4]; diff --git a/drivers/cli/dos-keyboard.c b/drivers/cli/dos-keyboard.c new file mode 100644 index 0000000..22ca9e8 --- /dev/null +++ b/drivers/cli/dos-keyboard.c @@ -0,0 +1,131 @@ +/* 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 +#include +#include +#include +#include +#include +#include "keyscan.h" + +static unsigned char lastsc; +static char keybuf[256]; +int newk; + +/* Read scan code from port $60 */ +/* Acknowledge interrupt( output $20 to port $20) */ + +static void ihandler(_go32_dpmi_registers *r) +{ + unsigned char scode=inp(0x60); /* Get scan code. */ + + + if(scode!=0xE0) + { + int offs=0; + + /* I'm only interested in preserving the independent status of the + right ALT and CONTROL keys. + */ + if(lastsc==0xE0) + if((scode&0x7F)==SCAN_LEFTALT || (scode&0x7F)==SCAN_LEFTCONTROL) + offs=0x80; + + + keybuf[(scode&0x7f)|offs]=((scode&0x80)^0x80); + newk++; + } + lastsc=scode; + + outp(0x20,0x20); /* Acknowledge interrupt. */ +} + +static _go32_dpmi_seginfo KBIBack,KBIBackRM; +static _go32_dpmi_seginfo KBI,KBIRM; +static _go32_dpmi_registers KBIRMRegs; +static int initdone=0; + +int InitKeyboard(void) +{ + /* I'll assume that the keyboard is in the correct scancode mode(translated + mode 2, I think). + */ + newk=0; + memset(keybuf,0,sizeof(keybuf)); + KBIRM.pm_offset=KBI.pm_offset=(int)ihandler; + KBIRM.pm_selector=KBI.pm_selector=_my_cs(); + + _go32_dpmi_get_real_mode_interrupt_vector(9,&KBIBackRM); + _go32_dpmi_allocate_real_mode_callback_iret(&KBIRM, &KBIRMRegs); + _go32_dpmi_set_real_mode_interrupt_vector(9,&KBIRM); + + _go32_dpmi_get_protected_mode_interrupt_vector(9,&KBIBack); + _go32_dpmi_allocate_iret_wrapper(&KBI); + _go32_dpmi_set_protected_mode_interrupt_vector(9,&KBI); + lastsc=0; + initdone=1; + return(1); +} + +void KillKeyboard(void) +{ + if(initdone) + { + _go32_dpmi_set_protected_mode_interrupt_vector(9,&KBIBack); + _go32_dpmi_free_iret_wrapper(&KBI); + + _go32_dpmi_set_real_mode_interrupt_vector(9,&KBIBackRM); + _go32_dpmi_free_real_mode_callback(&KBIRM); + initdone=0; + } +} + +/* In FCE Ultra, it doesn't matter if the key states change + in the middle of the keyboard handling code. If you want + to use this code elsewhere, you may want to memcpy() keybuf + to another buffer and return that when GetKeyboard() is + called. +*/ + +char *GetKeyboard(void) +{ + return keybuf; +} + +/* Returns 1 on new scan codes generated, 0 on no new scan codes. */ +int UpdateKeyboard(void) +{ + int t=newk; + + if(t) + { + asm volatile( + "subl %%eax,_newk\n\t" + : + : "a" (t) + ); + + if(keybuf[SCAN_LEFTCONTROL] && keybuf[SCAN_C]) + raise(SIGINT); + return(1); + } + return(0); +} diff --git a/drivers/cli/dos-mouse.c b/drivers/cli/dos-mouse.c new file mode 100644 index 0000000..ae3e341 --- /dev/null +++ b/drivers/cli/dos-mouse.c @@ -0,0 +1,77 @@ +/* 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 +#include + +#include "dos.h" + +int InitMouse(void) +{ + __dpmi_regs regs; + + memset(®s,0,sizeof(regs)); + regs.x.ax=0; + __dpmi_int(0x33,®s); + if(regs.x.ax!=0xFFFF) + return(0); + + memset(®s,0,sizeof(regs)); + regs.x.ax=0x7; + regs.x.cx=0; // Min X + regs.x.dx=260; // Max X + __dpmi_int(0x33,®s); + + memset(®s,0,sizeof(regs)); + regs.x.ax=0x8; + regs.x.cx=0; // Min Y + regs.x.dx=260; // Max Y + __dpmi_int(0x33,®s); + + memset(®s,0,sizeof(regs)); + regs.x.ax=0xF; + regs.x.cx=8; // Mickey X + regs.x.dx=8; // Mickey Y + __dpmi_int(0x33,®s); + + memset(®s,0,sizeof(regs)); + regs.x.ax=0x2; + __dpmi_int(0x33,®s); + + return(1); +} + +uint32 GetMouseData(uint32 *x, uint32 *y) +{ + __dpmi_regs regs; + + memset(®s,0,sizeof(regs)); + regs.x.ax=0x3; + __dpmi_int(0x33,®s); + + *x=regs.x.cx; + *y=regs.x.dx; + return(regs.x.bx&3); +} + +void KillMouse(void) +{ + +} diff --git a/drivers/cli/dos-sound.c b/drivers/cli/dos-sound.c new file mode 100644 index 0000000..19ef271 --- /dev/null +++ b/drivers/cli/dos-sound.c @@ -0,0 +1,567 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dos.h" +#include "dos-sound.h" +#include "dos-joystick.h" + + +static void SBIRQHandler(_go32_dpmi_registers *r); +static uint32 LMBuffer; /* Address of low memory DMA playback buffer. */ +static int LMSelector; + +static uint8 *WaveBuffer; +static unsigned int IVector, SBIRQ, SBDMA, SBDMA16, SBPort; +static int DSPV,hsmode; +static int format; +static int frags, fragsize, fragtotal; +static volatile int WritePtr, ReadPtr; +static volatile int hbusy; +static volatile int whichbuf; + + +static uint8 PICMask; +/* Protected mode interrupt vector info. */ +static _go32_dpmi_seginfo SBIH,SBIHOld; + +/* Real mode interrupt vector info. */ +static _go32_dpmi_seginfo SBIHRM,SBIHRMOld; +static _go32_dpmi_registers SBIHRMRegs; + +static int WriteDSP(uint8 V) +{ + int x; + + for(x=65536;x;x--) + { + if(!(inportb(SBPort+0xC)&0x80)) + { + outportb(SBPort+0xC,V); + return(1); + } + } + return(0); +} + +static int ReadDSP(uint8 *V) +{ + int x; + + for(x=65536;x;x--) /* Should be more than enough time... */ + { + if(inportb(SBPort+0xE)&0x80) + { + *V=inportb(SBPort+0xA); + return(1); + } + } + return(0); +} + + +static int SetVectors(void) +{ + SBIH.pm_offset=SBIHRM.pm_offset=(int)SBIRQHandler; + SBIH.pm_selector=SBIHRM.pm_selector=_my_cs(); + + /* Get and set real mode interrupt vector. */ + _go32_dpmi_get_real_mode_interrupt_vector(IVector,&SBIHRMOld); + _go32_dpmi_allocate_real_mode_callback_iret(&SBIHRM, &SBIHRMRegs); + _go32_dpmi_set_real_mode_interrupt_vector(IVector,&SBIHRM); + + /* Get and set protected mode interrupt vector. */ + _go32_dpmi_get_protected_mode_interrupt_vector(IVector,&SBIHOld); + _go32_dpmi_allocate_iret_wrapper(&SBIH); + _go32_dpmi_set_protected_mode_interrupt_vector(IVector,&SBIH); + + return(1); +} + +static void ResetVectors(void) +{ + _go32_dpmi_set_protected_mode_interrupt_vector(IVector,&SBIHOld); + _go32_dpmi_free_iret_wrapper(&SBIH); + _go32_dpmi_set_real_mode_interrupt_vector(IVector,&SBIHRMOld); + _go32_dpmi_free_real_mode_callback(&SBIHRM); +} + +int GetBLASTER(void) +{ + int check=0; + char *s; + + if(!(s=getenv("BLASTER"))) + { + puts(" Error getting BLASTER environment variable."); + return(0); + } + + while(*s) + { + switch(toupper(*s)) + { + case 'A': check|=(sscanf(s+1,"%x",&SBPort)==1)?1:0;break; + case 'I': check|=(sscanf(s+1,"%d",&SBIRQ)==1)?2:0;break; + case 'D': check|=(sscanf(s+1,"%d",&SBDMA)==1)?4:0;break; + case 'H': check|=(sscanf(s+1,"%d",&SBDMA16)==1)?8:0;break; + } + s++; + } + + if((check^7)&7 || SBDMA>=4 || (SBDMA16<=4 && check&8) || SBIRQ>15) + { + puts(" Invalid or incomplete BLASTER environment variable."); + return(0); + } + if(!(check&8)) + format=0; + return(1); +} + +static int ResetDSP(void) +{ + uint8 b; + + outportb(SBPort+0x6,0x1); + delay(10); + outportb(SBPort+0x6,0x0); + delay(10); + + if(ReadDSP(&b)) + if(b==0xAA) + return(1); + return(0); +} + +static int GetDSPVersion(void) +{ + int ret; + uint8 t; + + if(!WriteDSP(0xE1)) + return(0); + if(!ReadDSP(&t)) + return(0); + ret=t<<8; + if(!ReadDSP(&t)) + return(0); + ret|=t; + + return(ret); +} + +static void KillDMABuffer(void) +{ + __dpmi_free_dos_memory(LMSelector); +} + +static int MakeDMABuffer(void) +{ + uint32 size; + int32 tmp; + + size=fragsize*2; /* Two buffers in the DMA buffer. */ + size<<=format; /* Twice the size for 16-bit than for 8-bit. */ + + size<<=1; /* Double the size in case the first 2 buffers + cross a 64KB or 128KB page boundary. + */ + size=(size+15)>>4; /* Convert to paragraphs */ + + if((tmp=__dpmi_allocate_dos_memory(size,&LMSelector))<0) + return(0); + + LMBuffer=tmp<<=4; + + if(format) /* Check for and fix 128KB page boundary crossing. */ + { + if((LMBuffer&0x20000) != ((LMBuffer+fragsize*2*2-1)&0x20000)) + LMBuffer+=fragsize*2*2; + } + else /* Check for and fix 64KB page boundary crossing. */ + { + if((LMBuffer&0x10000) != ((LMBuffer+fragsize*2-1)&0x10000)) + LMBuffer+=fragsize*2; + } + + DOSMemSet(LMBuffer, format?0:128, (fragsize*2)<>8); + + /* Page of buffer. */ + outportb(PPorts[format?SBDMA16:SBDMA],LMBuffer>>16); + + /* Offset of buffer within page. */ + if(format) + tmp=((SBDMA16&3)<<2)+0xc0; + else + tmp=SBDMA<<1; + + outportb(tmp,(LMBuffer>>format)); + outportb(tmp,(LMBuffer>>(8+format))); +} + +int InitSB(int Rate, int bittage) +{ + hsmode=hbusy=0; + whichbuf=1; + puts("Initializing Sound Blaster..."); + + format=bittage?1:0; + frags=8; + + if(Rate<=11025) + fragsize=1<<5; + else if(Rate<=22050) + fragsize=1<<6; + else + fragsize=1<<7; + + fragtotal=frags*fragsize; + WaveBuffer=malloc(fragtotal<65535)) + { + printf(" Unsupported playback rate: %d samples per second\n",Rate); + return(0); + } + + if(!GetBLASTER()) + return(0); + + /* Disable IRQ line in PIC0 or PIC1 */ + if(SBIRQ>7) + { + PICMask=inportb(0xA1); + outportb(0xA1,PICMask|(1<<(SBIRQ&7))); + } + else + { + PICMask=inportb(0x21); + outportb(0x21,PICMask|(1<>8,DSPV&0xFF); + if(DSPV<0x201) + { + printf(" DSP version number is too low.\n"); + return(0); + } + + if(DSPV<0x400) + format=0; + if(!MakeDMABuffer()) + { + puts(" Error creating low-memory DMA buffer."); + return(0); + } + + if(SBIRQ>7) IVector=SBIRQ+0x68; + else IVector=SBIRQ+0x8; + + if(!SetVectors()) + { + puts(" Error setting interrupt vectors."); + KillDMABuffer(); + return(0); + } + + /* Reenable IRQ line. */ + if(SBIRQ>7) + outportb(0xA1,PICMask&(~(1<<(SBIRQ&7)))); + else + outportb(0x21,PICMask&(~(1<=0x400) + { + WriteDSP(0x41); // Set sampling rate + WriteDSP(Rate>>8); // High byte + WriteDSP(Rate&0xFF); // Low byte + if(!format) + { + WriteDSP(0xC6); // 8-bit output + WriteDSP(0x00); // 8-bit mono unsigned PCM + } + else + { + WriteDSP(0xB6); // 16-bit output + WriteDSP(0x10); // 16-bit mono signed PCM + } + WriteDSP((fragsize-1)&0xFF);// Low byte of size + WriteDSP((fragsize-1)>>8); // High byte of size + } + else + { + int tc,command; + if(Rate>22050) + { + tc=(65536-(256000000/Rate))>>8; + Rate=256000000/(65536-(tc<<8)); + command=0x90; // High-speed auto-initialize DMA mode transfer + hsmode=1; + } + else + { + tc=256-(1000000/Rate); + Rate=1000000/(256-tc); + command=0x1c; // Auto-initialize DMA mode transfer + } + WriteDSP(0x40); // Set DSP time constant + WriteDSP(tc); // time constant + WriteDSP(0x48); // Set DSP block transfer size + WriteDSP((fragsize-1)&0xFF); + WriteDSP((fragsize-1)>>8); + + WriteDSP(command); + } + + /* Enable DMA */ + if(format) + outportb(0xd4,SBDMA16&3); + else + outportb(0xa,SBDMA); + + printf(" %d hz, %d-bit\n",Rate,8<=8) + outportb(0xA0,0x20); + whichbuf^=1; + return; + } + hbusy=1; + + { + /* This code seems to fail on many SB emulators. Bah. + SCREW SB EMULATORS. ^_^ */ + uint32 count; + uint32 block; + uint32 port; + + if(format) + port=((SBDMA16&3)*4)+0xc2; + else + port=(SBDMA*2)+1; + + count=inportb(port); + count|=inportb(port)<<8; + + if(count>=fragsize) + block=1; + else + block=0; + dest=LMBuffer+((block*fragsize)<>2;x;x--,dest+=4) + { + _farnspokel(dest,sby); + } + } + else + { + for(x=(fragsize<>2;x;x--,dest+=4,src++) + { + _farnspokel(dest,*src); + } + ReadPtr=(ReadPtr+fragsize)&(fragtotal-1); + } + + if(soundjoyeron) + { + static int coot=0; + if(!coot) + { + UpdateJoyData(); + soundjoyer=1; + } + coot=(coot+1)&3; + } + hbusy=0; + outportb(0x20,0x20); + if(SBIRQ>=8) + outportb(0xA0,0x20); +} + +void SilenceSound(int s) +{ + ssilence=s; +} + +void WriteSBSound(int32 *Buffer, int Count, int NoBlocking) +{ + int x; + + if(!format) + { + for(x=0;x>8)^128; + WritePtr=(WritePtr+1)&(fragtotal-1); + } + } + else // 16 bit + { + for(x=0;x7)?0xA1:0x21,PICMask|(1<<(SBIRQ&7))); + ResetVectors(); + outportb((SBIRQ>7)?0xA1:0x21,PICMask); + KillDMABuffer(); +} diff --git a/drivers/cli/dos-sound.h b/drivers/cli/dos-sound.h new file mode 100644 index 0000000..7f5185a --- /dev/null +++ b/drivers/cli/dos-sound.h @@ -0,0 +1,26 @@ +/* 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 + */ + +int InitSB(int Rate, int bittage); +void KillSB(void); + +void WriteSBSound(int32 *Buffer, int Count, int NoBlocking); +void SilenceSound(int s); + diff --git a/drivers/cli/dos-video.c b/drivers/cli/dos-video.c new file mode 100644 index 0000000..574c824 --- /dev/null +++ b/drivers/cli/dos-video.c @@ -0,0 +1,246 @@ +/* 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 +#include +#include +#include +#include +#include + +#include "dos.h" +#include "dos-video.h" + +#define TEXT 3 +#define G320x200x256 0x13 + +static void vga_waitretrace(void) +{ + while(inp(0x3da)&0x8); + while(!(inp(0x3da)&0x8)); +} + +static void vga_setmode(int mode) +{ + __dpmi_regs regs; + + memset(®s,0,sizeof(regs)); + regs.x.ax=mode; + + __dpmi_int(0x10,®s); +} + +void vga_setpalette(int i, int r, int g, int b) +{ + outp(0x3c8,i); + outp(0x3c9,r); + outp(0x3c9,g); + outp(0x3c9,b); +} + +int FCEUDvmode=1; + +static int vidready=0; + +/* Part of the VGA low-level mass register setting code derived from + code by \Firebug\. +*/ + +#include "vgatweak.c" + +void SetBorder(void) +{ + inportb(0x3da); + outportb(0x3c0,(0x11|0x20)); + outportb(0x3c0,0x80); +} + +void TweakVGA(int VGAMode) +{ + int I; + + vga_waitretrace(); + + 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); +} + + +static uint8 palettedbr[256],palettedbg[256],palettedbb[256]; + +static void FlushPalette(void) +{ + int x; + for(x=0;x<256;x++) + { + int z=x; + 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) + { + 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 uint32 ScreenLoc; + +int InitVideo(void) +{ + vidready=0; + switch(FCEUDvmode) + { + default: + case 1: + case 2: + case 3: + case 6: + case 8: + vga_setmode(G320x200x256); + vidready|=1; + ScreenLoc=0xa0000; + TweakVGA(FCEUDvmode); + SetBorder(); + DOSMemSet(ScreenLoc, 128, 256*256); + break; + } + vidready|=2; + FlushPalette(); + return 1; +} + +void KillVideo(void) +{ + if(vidready) + { + vga_setmode(TEXT); + vidready=0; + } +} +void LockConsole(void){} +void UnlockConsole(void){} +void BlitScreen(uint8 *XBuf) +{ + uint32 dest; + int tlines; + + if(eoptions&4 && !NoWaiting) + vga_waitretrace(); + + tlines=erendline-srendline+1; + + dest=ScreenLoc; + + switch(FCEUDvmode) + { + 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; + } + + XBuf+=(srendline<<8)+(srendline<<4); + + _farsetsel(_dos_ds); + if(eoptions&DO_CLIPSIDES) + { + asm volatile( + "agoop1:\n\t" + "movl $30,%%eax\n\t" + "agoop2:\n\t" + "movl (%%esi),%%edx\n\t" + "movl 4(%%esi),%%ecx\n\t" + ".byte 0x64 \n\t" + "movl %%edx,(%%edi)\n\t" + ".byte 0x64 \n\t" + "movl %%ecx,4(%%edi)\n\t" + "addl $8,%%esi\n\t" + "addl $8,%%edi\n\t" + "decl %%eax\n\t" + "jne agoop2\n\t" + "addl $32,%%esi\n\t" + "addl $16,%%edi\n\t" + "decb %%bl\n\t" + "jne agoop1\n\t" + : + : "S" (XBuf+8), "D" (dest+8), "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" + ".byte 0x64 \n\t" + "movl %%edx,(%%edi)\n\t" + ".byte 0x64 \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" ); + } +} + + diff --git a/drivers/cli/dos-video.h b/drivers/cli/dos-video.h new file mode 100644 index 0000000..ee09b51 --- /dev/null +++ b/drivers/cli/dos-video.h @@ -0,0 +1,22 @@ +/* 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 FCEUDvmode; + diff --git a/drivers/cli/dos.c b/drivers/cli/dos.c new file mode 100644 index 0000000..8ba1578 --- /dev/null +++ b/drivers/cli/dos.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include + +#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=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)); +} + diff --git a/drivers/cli/dos.h b/drivers/cli/dos.h new file mode 100644 index 0000000..05bc8e5 --- /dev/null +++ b/drivers/cli/dos.h @@ -0,0 +1,28 @@ +/* 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" +#include "main.h" + +extern int eoptions; +extern int soundo; +void DOSMemSet(uint32 A, uint8 V, uint32 count); +#define DO_CLIPSIDES 1 + diff --git a/drivers/cli/input.c b/drivers/cli/input.c new file mode 100644 index 0000000..73e2e2f --- /dev/null +++ b/drivers/cli/input.c @@ -0,0 +1,340 @@ +/* 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<>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; + } +} diff --git a/drivers/cli/keyscan.h b/drivers/cli/keyscan.h new file mode 100644 index 0000000..af82127 --- /dev/null +++ b/drivers/cli/keyscan.h @@ -0,0 +1,166 @@ +#ifdef SVGALIB + +#include +#define SCANCODE_DELETE SCANCODE_REMOVE +#define SCANCODE_KP_MINUS SCANCODE_KEYPADMINUS +#define SCANCODE_KP_PLUS SCANCODE_KEYPADPLUS +#define MK(k) SCANCODE_##k +#define MK_COUNT 256 +#elif SDL +#include +#define SDLK_A SDLK_a +#define SDLK_B SDLK_b +#define SDLK_C SDLK_c +#define SDLK_D SDLK_d +#define SDLK_E SDLK_e +#define SDLK_F SDLK_f +#define SDLK_G SDLK_g +#define SDLK_H SDLK_h +#define SDLK_I SDLK_i +#define SDLK_J SDLK_j +#define SDLK_K SDLK_k +#define SDLK_L SDLK_l +#define SDLK_M SDLK_m +#define SDLK_N SDLK_n +#define SDLK_O SDLK_o +#define SDLK_P SDLK_p +#define SDLK_Q SDLK_q +#define SDLK_R SDLK_r +#define SDLK_S SDLK_s +#define SDLK_T SDLK_t +#define SDLK_U SDLK_u +#define SDLK_V SDLK_v +#define SDLK_W SDLK_w +#define SDLK_X SDLK_x +#define SDLK_Y SDLK_y +#define SDLK_Z SDLK_z +#define SDLK_LEFTCONTROL SDLK_LCTRL +#define SDLK_RIGHTCONTROL SDLK_RCTRL +#define SDLK_LEFTALT SDLK_LALT +#define SDLK_RIGHTALT SDLK_RALT +#define SDLK_LEFTSHIFT SDLK_LSHIFT +#define SDLK_RIGHTSHIFT SDLK_RSHIFT +#define SDLK_CURSORDOWN SDLK_DOWN +#define SDLK_CURSORUP SDLK_UP +#define SDLK_CURSORLEFT SDLK_LEFT +#define SDLK_CURSORRIGHT SDLK_RIGHT +#define SDLK_ENTER SDLK_RETURN +#define SDLK_EQUAL SDLK_EQUALS +#define SDLK_APOSTROPHE SDLK_QUOTE +#define SDLK_BRACKET_LEFT SDLK_LEFTBRACKET +#define SDLK_BRACKET_RIGHT SDLK_RIGHTBRACKET +#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */ +#define SDLK_GRAVE SDLK_BACKQUOTE +#define MK(k) SDLK_##k +#define MK_COUNT (SDLK_LAST+1) +#elif DOS + +#define SCAN_GRAVE 0x29 +#define SCAN_1 0x02 +#define SCAN_2 0x03 +#define SCAN_3 0x04 +#define SCAN_4 0x05 +#define SCAN_5 0x06 +#define SCAN_6 0x07 +#define SCAN_7 0x08 +#define SCAN_8 0x09 +#define SCAN_9 0x0A +#define SCAN_0 0x0B +#define SCAN_MINUS 0x0C +#define SCAN_EQUAL 0x0D +#define SCAN_BACKSLASH 0x2B +#define SCAN_BACKSPACE 0x0E +#define SCAN_TAB 0x0F +#define SCAN_Q 0x10 +#define SCAN_W 0x11 +#define SCAN_E 0x12 +#define SCAN_R 0x13 +#define SCAN_T 0x14 +#define SCAN_Y 0x15 +#define SCAN_U 0x16 +#define SCAN_I 0x17 +#define SCAN_O 0x18 +#define SCAN_P 0x19 +#define SCAN_BRACKET_LEFT 0x1A +#define SCAN_BRACKET_RIGHT 0x1B +#define SCAN_LOWBACKSLASH 0x2B +#define SCAN_CAPSLOCK 0x3A +#define SCAN_A 0x1E +#define SCAN_S 0x1F +#define SCAN_D 0x20 +#define SCAN_F 0x21 +#define SCAN_G 0x22 +#define SCAN_H 0x23 +#define SCAN_J 0x24 +#define SCAN_K 0x25 +#define SCAN_L 0x26 +#define SCAN_SEMICOLON 0x27 +#define SCAN_APOSTROPHE 0x28 +#define SCAN_ENTER 0x1C +#define SCAN_LEFTSHIFT 0x2A +#define SCAN_Z 0x2C +#define SCAN_X 0x2D +#define SCAN_C 0x2E +#define SCAN_V 0x2F +#define SCAN_B 0x30 +#define SCAN_N 0x31 +#define SCAN_M 0x32 +#define SCAN_COMMA 0x33 +#define SCAN_PERIOD 0x34 +#define SCAN_SLASH 0x35 +#define SCAN_RIGHTSHIFT 0x36 +#define SCAN_LEFTCONTROL 0x1D +#define SCAN_LEFTALT 0x38 +#define SCAN_SPACE 0x39 + +/* Extended keys. */ +#define SCAN_RIGHTALT (0x38|0x80) +#define SCAN_RIGHTCONTROL (0x1D|0x80) +#define SCAN_BL_INSERT (0x52|0x80) +#define SCAN_BL_DELETE (0x53|0x80) +#define SCAN_BL_CURSORLEFT (0x4B|0x80) +#define SCAN_BL_HOME (0x47|0x80) +#define SCAN_BL_END (0x4F|0x80) +#define SCAN_BL_CURSORUP (0x48|0x80) +#define SCAN_BL_CURSORDOWN (0x50|0x80) +#define SCAN_BL_PAGEUP (0x49|0x80) +#define SCAN_BL_PAGEDOWN (0x51|0x80) +#define SCAN_BL_CURSORRIGHT (0x4D|0x80) + +#define SCAN_SCROLLLOCK 0x46 +/* Keys in the key pad area. */ +#define SCAN_NUMLOCK 0x45 +#define SCAN_HOME 0x47 +#define SCAN_CURSORLEFT 0x4B +#define SCAN_END 0x4F +#define SCAN_SLASH 0x35 +#define SCAN_CURSORUP 0x48 +#define SCAN_CENTER 0x4C +#define SCAN_CURSORDOWN 0x50 +#define SCAN_INSERT 0x52 +#define SCAN_ASTERISK 0x37 +#define SCAN_PAGEUP 0x49 +#define SCAN_CURSORRIGHT 0x4D +#define SCAN_PAGEDOWN 0x51 +#define SCAN_DELETE 0x53 +#define SCAN_KP_MINUS 0x4A +#define SCAN_KP_PLUS 0x4E +#define SCAN_KP_ENTER 0x1C + +#define SCAN_ESCAPE 0x01 +#define SCAN_F1 0x3B +#define SCAN_F2 0x3C +#define SCAN_F3 0x3D +#define SCAN_F4 0x3E +#define SCAN_F5 0x3F +#define SCAN_F6 0x40 +#define SCAN_F7 0x41 +#define SCAN_F8 0x42 +#define SCAN_F9 0x43 +#define SCAN_F10 0x44 +#define SCAN_F11 0x57 +#define SCAN_F12 0x58 + +#define MK_COUNT 256 +#define MK(k) SCAN_##k +#endif diff --git a/drivers/cli/lnx-joystick.c b/drivers/cli/lnx-joystick.c new file mode 100644 index 0000000..4c2ae6a --- /dev/null +++ b/drivers/cli/lnx-joystick.c @@ -0,0 +1,201 @@ +/* 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 +#include +#include +#include +#include +#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<=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< +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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]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< +#include +#include +#include + +#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); +} diff --git a/drivers/cli/sdl-netplay.c b/drivers/cli/sdl-netplay.c new file mode 100644 index 0000000..38a4c81 --- /dev/null +++ b/drivers/cli/sdl-netplay.c @@ -0,0 +1,163 @@ +/* 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 +#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; +} diff --git a/drivers/cli/sdl-netplay.h b/drivers/cli/sdl-netplay.h new file mode 100644 index 0000000..48769f6 --- /dev/null +++ b/drivers/cli/sdl-netplay.h @@ -0,0 +1,5 @@ +extern char *netplayhost; +extern int Port; +extern int FDnetplay; +#define netplay FDnetplay + diff --git a/drivers/cli/sdl-sound.c b/drivers/cli/sdl-sound.c new file mode 100644 index 0000000..f8ab865 --- /dev/null +++ b/drivers/cli/sdl-sound.c @@ -0,0 +1,148 @@ +/* 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 +#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 diff --git a/drivers/cli/sdl-video.c b/drivers/cli/sdl-video.c new file mode 100644 index 0000000..b805a8a --- /dev/null +++ b/drivers/cli/sdl-video.c @@ -0,0 +1,228 @@ +/* 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 +#include +#include + +#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(_xrespixels; + + 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)); +} diff --git a/drivers/cli/sdl-video.h b/drivers/cli/sdl-video.h new file mode 100644 index 0000000..036c933 --- /dev/null +++ b/drivers/cli/sdl-video.h @@ -0,0 +1 @@ +uint32 PtoV(uint16 x, uint16 y); diff --git a/drivers/cli/sdl.c b/drivers/cli/sdl.c new file mode 100644 index 0000000..77decae --- /dev/null +++ b/drivers/cli/sdl.c @@ -0,0 +1,216 @@ +#include +#include +#include + +#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); + } +} + diff --git a/drivers/cli/sdl.h b/drivers/cli/sdl.h new file mode 100644 index 0000000..a235951 --- /dev/null +++ b/drivers/cli/sdl.h @@ -0,0 +1,47 @@ +#include +#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 diff --git a/drivers/cli/svga-video.c b/drivers/cli/svga-video.c new file mode 100644 index 0000000..67f4ecb --- /dev/null +++ b/drivers/cli/svga-video.c @@ -0,0 +1,497 @@ +/* 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 +#include +#include +#include + +#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" ); + } + } +} + + diff --git a/drivers/cli/svga-video.h b/drivers/cli/svga-video.h new file mode 100644 index 0000000..e0a991b --- /dev/null +++ b/drivers/cli/svga-video.h @@ -0,0 +1,32 @@ +/* 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); + diff --git a/drivers/cli/svgalib.c b/drivers/cli/svgalib.c new file mode 100644 index 0000000..7d293e9 --- /dev/null +++ b/drivers/cli/svgalib.c @@ -0,0 +1,178 @@ +#include +#include +#include +#include +#include +#include + +#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)); +} diff --git a/drivers/cli/svgalib.h b/drivers/cli/svgalib.h new file mode 100644 index 0000000..8f18b74 --- /dev/null +++ b/drivers/cli/svgalib.h @@ -0,0 +1,2 @@ +#define DO_VSYNC 1 +extern int doptions; diff --git a/drivers/cli/throttle.c b/drivers/cli/throttle.c new file mode 100644 index 0000000..33941bb --- /dev/null +++ b/drivers/cli/throttle.c @@ -0,0 +1,45 @@ +#include +#include +#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; +} + diff --git a/drivers/cli/throttle.h b/drivers/cli/throttle.h new file mode 100644 index 0000000..0b0ad9f --- /dev/null +++ b/drivers/cli/throttle.h @@ -0,0 +1,2 @@ +void RefreshThrottleFPS(void); +void SpeedThrottle(void); diff --git a/drivers/cli/unix-basedir.h b/drivers/cli/unix-basedir.h new file mode 100644 index 0000000..4f6808c --- /dev/null +++ b/drivers/cli/unix-basedir.h @@ -0,0 +1,15 @@ +#include +void GetBaseDirectory(char *BaseDirectory) +{ + char *ol; + + ol=getenv("HOME"); + BaseDirectory[0]=0; + if(ol) + { + strncpy(BaseDirectory,ol,2047); + BaseDirectory[2047]=0; + strcat(BaseDirectory,"/.fceultra"); + } +} + diff --git a/drivers/cli/unix-netplay.c b/drivers/cli/unix-netplay.c new file mode 100644 index 0000000..747fa00 --- /dev/null +++ b/drivers/cli/unix-netplay.c @@ -0,0 +1,159 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} + diff --git a/drivers/cli/unix-netplay.h b/drivers/cli/unix-netplay.h new file mode 100644 index 0000000..48769f6 --- /dev/null +++ b/drivers/cli/unix-netplay.h @@ -0,0 +1,5 @@ +extern char *netplayhost; +extern int Port; +extern int FDnetplay; +#define netplay FDnetplay + diff --git a/drivers/cli/usage.h b/drivers/cli/usage.h new file mode 100644 index 0000000..425a907 --- /dev/null +++ b/drivers/cli/usage.h @@ -0,0 +1,56 @@ +/* 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 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."); +} diff --git a/drivers/cli/vgatweak.c b/drivers/cli/vgatweak.c new file mode 100644 index 0000000..a04cf94 --- /dev/null +++ b/drivers/cli/vgatweak.c @@ -0,0 +1,168 @@ +/* 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; + } +} + -- 2.39.2