Added sdl stuff from the attic
This commit is contained in:
parent
83d450d368
commit
71fe9d6662
|
@ -0,0 +1,72 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#include "../common/args.h"
|
||||||
|
#include "../common/config.h"
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
extern FCEUGI *CurGame;
|
||||||
|
|
||||||
|
extern CFGSTRUCT DriverConfig[];
|
||||||
|
extern ARGPSTRUCT DriverArgs[];
|
||||||
|
extern char *DriverUsage;
|
||||||
|
|
||||||
|
void DoDriverArgs(void);
|
||||||
|
uint8 *GetBaseDirectory(void);
|
||||||
|
|
||||||
|
int InitSound(FCEUGI *gi);
|
||||||
|
void WriteSound(int32 *Buffer, int Count);
|
||||||
|
int KillSound(void);
|
||||||
|
uint32 GetMaxSound(void);
|
||||||
|
uint32 GetWriteSound(void);
|
||||||
|
|
||||||
|
void SilenceSound(int s); /* DOS and SDL */
|
||||||
|
|
||||||
|
|
||||||
|
int InitMouse(void);
|
||||||
|
void KillMouse(void);
|
||||||
|
void GetMouseData(uint32 *MouseData);
|
||||||
|
|
||||||
|
int InitJoysticks(void);
|
||||||
|
int KillJoysticks(void);
|
||||||
|
uint32 *GetJSOr(void);
|
||||||
|
|
||||||
|
int InitKeyboard(void);
|
||||||
|
int UpdateKeyboard(void);
|
||||||
|
char *GetKeyboard(void);
|
||||||
|
void KillKeyboard(void);
|
||||||
|
|
||||||
|
int InitVideo(FCEUGI *gi);
|
||||||
|
int KillVideo(void);
|
||||||
|
void BlitScreen(uint8 *XBuf);
|
||||||
|
void LockConsole(void);
|
||||||
|
void UnlockConsole(void);
|
||||||
|
void ToggleFS(); /* SDL */
|
||||||
|
|
||||||
|
int LoadGame(const char *path);
|
||||||
|
int CloseGame(void);
|
||||||
|
int GUI_Init(int argc, char **argv, int (*dofunc)(void));
|
||||||
|
int GUI_Idle(void);
|
||||||
|
int GUI_Update(void);
|
||||||
|
void GUI_Hide(int);
|
||||||
|
void GUI_RequestExit(void);
|
||||||
|
int GUI_SetVideo(int fullscreen, int width, int height);
|
||||||
|
char *GUI_GetKeyboard(void);
|
||||||
|
void GUI_GetMouseState(uint32 *b, int *x, int *y);
|
||||||
|
|
||||||
|
void UpdatePhysicalInput(void);
|
||||||
|
int DTestButton(ButtConfig *bc);
|
||||||
|
int DWaitButton(const uint8 *text, ButtConfig *bc, int wb);
|
||||||
|
int ButtonConfigBegin(void);
|
||||||
|
void ButtonConfigEnd(void);
|
||||||
|
|
||||||
|
void Giggles(int);
|
||||||
|
void DoFun(void);
|
||||||
|
|
||||||
|
int FCEUD_NetworkConnect(void);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <dpmi.h>
|
||||||
|
#include <sys/farptr.h>
|
||||||
|
#include <go32.h>
|
||||||
|
#include <pc.h>
|
||||||
|
|
||||||
|
#include "dos.h"
|
||||||
|
#include "dos-joystick.h"
|
||||||
|
|
||||||
|
#define JOY_A 1
|
||||||
|
#define JOY_B 2
|
||||||
|
#define JOY_SELECT 4
|
||||||
|
#define JOY_START 8
|
||||||
|
#define JOY_UP 0x10
|
||||||
|
#define JOY_DOWN 0x20
|
||||||
|
#define JOY_LEFT 0x40
|
||||||
|
#define JOY_RIGHT 0x80
|
||||||
|
|
||||||
|
int joy=0;
|
||||||
|
int joyBMap[6];
|
||||||
|
|
||||||
|
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;
|
||||||
|
static int rtoggle=0;
|
||||||
|
ret=0;
|
||||||
|
|
||||||
|
rtoggle^=1;
|
||||||
|
if(!soundo)
|
||||||
|
UpdateJoyData();
|
||||||
|
for(y=0;y<6;y++)
|
||||||
|
if((y>=4 && rtoggle) || y<4)
|
||||||
|
if(joybuttons&joyBMap[y]) ret|=(1<<y&3)<<((joy-1)<<3);
|
||||||
|
|
||||||
|
if(joyx<=joyxcenter*.25) ret|=JOY_LEFT<<((joy-1)<<3);
|
||||||
|
else if(joyx>=joyxcenter*1.75) ret|=JOY_RIGHT<<((joy-1)<<3);
|
||||||
|
if(joyy<=joyycenter*.25) ret|=JOY_UP<<((joy-1)<<3);
|
||||||
|
else if(joyy>=joyycenter*1.75) ret|=JOY_DOWN<<((joy-1)<<3);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitJoysticks(void)
|
||||||
|
{
|
||||||
|
if(!joy) return(0);
|
||||||
|
if(!DetectJoystick())
|
||||||
|
{
|
||||||
|
printf("Joystick not detected!\n");
|
||||||
|
joy=0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(soundo)
|
||||||
|
{
|
||||||
|
soundjoyeron=1;
|
||||||
|
while(!soundjoyer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
UpdateJoyData();
|
||||||
|
|
||||||
|
joyxcenter=joyx;
|
||||||
|
joyycenter=joyy;
|
||||||
|
|
||||||
|
if(!(joyBMap[0]|joyBMap[1]|joyBMap[2]|joyBMap[3]))
|
||||||
|
ConfigJoystick();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BConfig(int b)
|
||||||
|
{
|
||||||
|
int c=0;
|
||||||
|
uint32 st=time(0);
|
||||||
|
|
||||||
|
while(time(0)< (st+4) )
|
||||||
|
{
|
||||||
|
if(!soundo)
|
||||||
|
UpdateJoyData();
|
||||||
|
if(joybuttons) c=joybuttons;
|
||||||
|
else if(c && !joybuttons)
|
||||||
|
{
|
||||||
|
joyBMap[b]=c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillJoysticks(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConfigJoystick(void)
|
||||||
|
{
|
||||||
|
static char *genb="** Press button for ";
|
||||||
|
|
||||||
|
printf("\n\n Joystick button configuration:\n\n");
|
||||||
|
printf(" Push and release the button to map to the virtual joystick.\n");
|
||||||
|
printf(" If you do not wish to assign a button, wait a few seconds\n");
|
||||||
|
printf(" and the configuration will continue.\n\n");
|
||||||
|
printf(" Press enter to continue...\n");
|
||||||
|
getchar();
|
||||||
|
|
||||||
|
printf("%s\"Select\".\n",genb);
|
||||||
|
BConfig(2);
|
||||||
|
|
||||||
|
printf("%s\"Start\".\n",genb);
|
||||||
|
BConfig(3);
|
||||||
|
|
||||||
|
printf("%s\"B\".\n",genb);
|
||||||
|
BConfig(1);
|
||||||
|
|
||||||
|
printf("%s\"A\".\n",genb);
|
||||||
|
BConfig(0);
|
||||||
|
|
||||||
|
printf("%s\"Rapid fire B\".\n",genb);
|
||||||
|
BConfig(5);
|
||||||
|
|
||||||
|
printf("%s\"Rapid fire A\".\n",genb);
|
||||||
|
BConfig(4);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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[6];
|
|
@ -0,0 +1,131 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pc.h>
|
||||||
|
#include <dpmi.h>
|
||||||
|
#include <go32.h>
|
||||||
|
#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);
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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 <dpmi.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
if(FCEUI_IsMovieActive()<0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
__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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,567 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/farptr.h>
|
||||||
|
#include <pc.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <dpmi.h>
|
||||||
|
#include <go32.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#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)<<format);
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ProgramDMA(void)
|
||||||
|
{
|
||||||
|
static int PPorts[8]={0x87,0x83,0x81,0x82,0,0x8b,0x89,0x8a};
|
||||||
|
uint32 tmp;
|
||||||
|
|
||||||
|
if(format)
|
||||||
|
{
|
||||||
|
outportb(0xd4,(SBDMA16&0x3)|0x4);
|
||||||
|
outportb(0xd8,0x0);
|
||||||
|
outportb(0xd6,(SBDMA16&0x3)|0x58);
|
||||||
|
tmp=((SBDMA16&3)<<2)+0xC2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outportb(0xA,SBDMA|0x4);
|
||||||
|
outportb(0xC,0x0);
|
||||||
|
outportb(0xB,SBDMA|0x58);
|
||||||
|
tmp=(SBDMA<<1)+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Size of entire buffer. */
|
||||||
|
outportb(tmp,(fragsize*2-1));
|
||||||
|
outportb(tmp,(fragsize*2-1)>>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<<format);
|
||||||
|
|
||||||
|
if(format)
|
||||||
|
memset(WaveBuffer,0,fragtotal*2);
|
||||||
|
else
|
||||||
|
memset(WaveBuffer,128,fragtotal);
|
||||||
|
|
||||||
|
WritePtr=ReadPtr=0;
|
||||||
|
|
||||||
|
if((Rate<8192) || (Rate>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<<SBIRQ));
|
||||||
|
}
|
||||||
|
if(!ResetDSP())
|
||||||
|
{
|
||||||
|
puts(" Error resetting the DSP.");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(DSPV=GetDSPVersion()))
|
||||||
|
{
|
||||||
|
puts(" Error getting the DSP version.");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" DSP Version: %d.%d\n",DSPV>>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<<SBIRQ)));
|
||||||
|
|
||||||
|
ProgramDMA();
|
||||||
|
|
||||||
|
/* Note that the speaker must always be turned on before the mode transfer
|
||||||
|
byte is sent to the DSP if we're going into high-speed mode, since
|
||||||
|
a real Sound Blaster(at least my SBPro) won't accept DSP commands(except
|
||||||
|
for the reset "command") after it goes into high-speed mode.
|
||||||
|
*/
|
||||||
|
WriteDSP(0xD1); // Turn on DAC speaker
|
||||||
|
|
||||||
|
if(DSPV>=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<<format);
|
||||||
|
return(Rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern volatile int soundjoyer;
|
||||||
|
extern volatile int soundjoyeron;
|
||||||
|
static int ssilence=0;
|
||||||
|
|
||||||
|
static void SBIRQHandler(_go32_dpmi_registers *r)
|
||||||
|
{
|
||||||
|
uint32 *src;
|
||||||
|
uint32 dest;
|
||||||
|
int32 x;
|
||||||
|
|
||||||
|
|
||||||
|
if(format)
|
||||||
|
{
|
||||||
|
uint8 status;
|
||||||
|
|
||||||
|
outportb(SBPort+4,0x82);
|
||||||
|
status=inportb(SBPort+5);
|
||||||
|
if(status&2)
|
||||||
|
inportb(SBPort+0x0F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
inportb(SBPort+0x0E);
|
||||||
|
|
||||||
|
#ifdef OLD
|
||||||
|
{
|
||||||
|
uint8 status;
|
||||||
|
|
||||||
|
outportb(SBPort+4,0x82);
|
||||||
|
status=inportb(SBPort+5);
|
||||||
|
if(status&1)
|
||||||
|
inportb(SBPort+0x0E);
|
||||||
|
else if(status&2)
|
||||||
|
inportb(SBPort+0x0F);
|
||||||
|
else
|
||||||
|
return; // Mysterious interrupt source! *eerie music*
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(hbusy)
|
||||||
|
{
|
||||||
|
outportb(0x20,0x20);
|
||||||
|
if(SBIRQ>=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)<<format);
|
||||||
|
|
||||||
|
#ifdef MOO
|
||||||
|
dest=LMBuffer+((whichbuf*fragsize)<<format);
|
||||||
|
whichbuf^=1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
_farsetsel(_dos_ds);
|
||||||
|
|
||||||
|
src=(uint32 *)(WaveBuffer+(ReadPtr<<format));
|
||||||
|
|
||||||
|
if(ssilence)
|
||||||
|
{
|
||||||
|
uint32 sby;
|
||||||
|
if(format) sby=0; /* 16-bit silence. */
|
||||||
|
else sby=0x80808080; /* 8-bit silence. */
|
||||||
|
|
||||||
|
for(x=(fragsize<<format)>>2;x;x--,dest+=4)
|
||||||
|
{
|
||||||
|
_farnspokel(dest,sby);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(x=(fragsize<<format)>>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<Count;x++)
|
||||||
|
{
|
||||||
|
while(WritePtr==ReadPtr)
|
||||||
|
if(NoBlocking)
|
||||||
|
return;
|
||||||
|
WaveBuffer[WritePtr]=(uint8)((Buffer[x])>>8)^128;
|
||||||
|
WritePtr=(WritePtr+1)&(fragtotal-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // 16 bit
|
||||||
|
{
|
||||||
|
for(x=0;x<Count;x++)
|
||||||
|
{
|
||||||
|
while(WritePtr==ReadPtr)
|
||||||
|
if(NoBlocking)
|
||||||
|
return;
|
||||||
|
((int16 *)WaveBuffer)[WritePtr]=Buffer[x];
|
||||||
|
WritePtr=(WritePtr+1)&(fragtotal-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillSB(void)
|
||||||
|
{
|
||||||
|
if(hsmode)
|
||||||
|
ResetDSP(); /* High-speed mode requires a DSP reset. */
|
||||||
|
else
|
||||||
|
WriteDSP(format?0xD9:0xDA); /* Exit auto-init DMA transfer mode. */
|
||||||
|
WriteDSP(0xD3); /* Turn speaker off. */
|
||||||
|
|
||||||
|
outportb((SBIRQ>7)?0xA1:0x21,PICMask|(1<<(SBIRQ&7)));
|
||||||
|
ResetVectors();
|
||||||
|
outportb((SBIRQ>7)?0xA1:0x21,PICMask);
|
||||||
|
KillDMABuffer();
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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);
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 1998 \Firebug\
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dpmi.h>
|
||||||
|
#include <sys/farptr.h>
|
||||||
|
#include <go32.h>
|
||||||
|
#include <pc.h>
|
||||||
|
|
||||||
|
#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" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <crt0.h>
|
||||||
|
#include <sys/farptr.h>
|
||||||
|
#include <go32.h>
|
||||||
|
|
||||||
|
#include "dos.h"
|
||||||
|
#include "dos-joystick.h"
|
||||||
|
#include "dos-video.h"
|
||||||
|
#include "dos-sound.h"
|
||||||
|
#include "../common/args.h"
|
||||||
|
#include "../common/config.h"
|
||||||
|
|
||||||
|
/* _CRT0_FLAG_LOCK_MEMORY might not always result in all memory being locked.
|
||||||
|
Bummer. I'll add code to explicitly lock the data touched by the sound
|
||||||
|
interrupt handler(and the handler itself), if necessary(though that might
|
||||||
|
be tricky...). I'll also to cover the data the keyboard
|
||||||
|
interrupt handler touches.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _crt0_startup_flags = _CRT0_FLAG_FILL_SBRK_MEMORY | _CRT0_FLAG_LOCK_MEMORY | _CRT0_FLAG_USE_DOS_SLASHES;
|
||||||
|
|
||||||
|
static int f8bit=0;
|
||||||
|
int soundo=44100;
|
||||||
|
int doptions=0;
|
||||||
|
|
||||||
|
|
||||||
|
CFGSTRUCT DriverConfig[]={
|
||||||
|
NAC("sound",soundo),
|
||||||
|
AC(doptions),
|
||||||
|
AC(f8bit),
|
||||||
|
AC(FCEUDvmode),
|
||||||
|
NACA("joybmap",joyBMap),
|
||||||
|
AC(joy),
|
||||||
|
ENDCFGSTRUCT
|
||||||
|
};
|
||||||
|
|
||||||
|
char *DriverUsage=
|
||||||
|
"-vmode x Select video mode(all are 8 bpp).\n\
|
||||||
|
1 = 256x240 6 = 256x224(with scanlines)\n\
|
||||||
|
2 = 256x256 8 = 256x224\n\
|
||||||
|
3 = 256x256(with scanlines)\n\
|
||||||
|
-vsync x Wait for the screen's vertical retrace before updating the\n\
|
||||||
|
screen. Refer to the documentation for caveats.\n\
|
||||||
|
0 = Disabled.\n\
|
||||||
|
1 = Enabled.\n\
|
||||||
|
-sound x Sound.\n\
|
||||||
|
0 = Disabled.\n\
|
||||||
|
Otherwise, x = playback rate.\n\
|
||||||
|
-f8bit x Force 8-bit sound.\n\
|
||||||
|
0 = Disabled.\n\
|
||||||
|
1 = Enabled.";
|
||||||
|
|
||||||
|
ARGPSTRUCT DriverArgs[]={
|
||||||
|
{"-vmode",0,&FCEUDvmode,0},
|
||||||
|
{"-sound",0,&soundo,0},
|
||||||
|
{"-f8bit",0,&f8bit,0},
|
||||||
|
{"-vsync",0,&doptions,DO_VSYNC},
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
void DoDriverArgs(void)
|
||||||
|
{
|
||||||
|
if(!joy) memset(joyBMap,0,sizeof(joyBMap));
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitSound(void)
|
||||||
|
{
|
||||||
|
if(soundo)
|
||||||
|
{
|
||||||
|
if(soundo==1)
|
||||||
|
soundo=44100;
|
||||||
|
soundo=InitSB(soundo,f8bit?0:1);
|
||||||
|
FCEUI_Sound(soundo);
|
||||||
|
}
|
||||||
|
return(soundo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSound(int32 *Buffer, int Count, int NoWaiting)
|
||||||
|
{
|
||||||
|
WriteSBSound(Buffer,Count,NoWaiting);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillSound(void)
|
||||||
|
{
|
||||||
|
if(soundo)
|
||||||
|
KillSB();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOSMemSet(uint32 A, uint8 V, uint32 count)
|
||||||
|
{
|
||||||
|
uint32 x;
|
||||||
|
|
||||||
|
_farsetsel(_dos_ds);
|
||||||
|
for(x=0;x<count;x++)
|
||||||
|
_farnspokeb(A+x,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *arg0;
|
||||||
|
uint8 *GetBaseDirectory(void)
|
||||||
|
{
|
||||||
|
int x=0;
|
||||||
|
uint8 *ret = 0;
|
||||||
|
|
||||||
|
if(arg0)
|
||||||
|
for(x=strlen(arg0);x>=0;x--)
|
||||||
|
{
|
||||||
|
if(arg0[x]=='/' || arg0[x]=='\\')
|
||||||
|
{
|
||||||
|
ret = malloc(x + 1);
|
||||||
|
strncpy(ret,arg0,x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ret) { x=0; ret = malloc(1); }
|
||||||
|
|
||||||
|
BaseDirectory[x]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
puts("\nStarting FCE Ultra "VERSION_STRING"...\n");
|
||||||
|
arg0=argv[0];
|
||||||
|
return(CLImain(argc,argv));
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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 "main.h"
|
||||||
|
#include "dface.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
void DOSMemSet(uint32 A, uint8 V, uint32 count);
|
||||||
|
#define DO_VSYNC 1
|
||||||
|
|
|
@ -0,0 +1,720 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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 <string.h>
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "dface.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
#include "../common/cheat.h"
|
||||||
|
|
||||||
|
/* UsrInputType[] is user-specified. InputType[] is current
|
||||||
|
(game loading can override user settings)
|
||||||
|
*/
|
||||||
|
int UsrInputType[3]={SI_GAMEPAD,SI_GAMEPAD,SIFC_NONE};
|
||||||
|
int InputType[3]={0,0,0};
|
||||||
|
static int cspec=0;
|
||||||
|
|
||||||
|
int gametype=0;
|
||||||
|
|
||||||
|
/* Necessary for proper GUI functioning(configuring when a game isn't loaded). */
|
||||||
|
void InputUserActiveFix(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=0;x<3;x++) InputType[x]=UsrInputType[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseGIInput(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
gametype=gi->type;
|
||||||
|
|
||||||
|
InputType[0]=UsrInputType[0];
|
||||||
|
InputType[1]=UsrInputType[1];
|
||||||
|
InputType[2]=UsrInputType[2];
|
||||||
|
|
||||||
|
if(gi->input[0]>=0)
|
||||||
|
InputType[0]=gi->input[0];
|
||||||
|
if(gi->input[1]>=0)
|
||||||
|
InputType[1]=gi->input[1];
|
||||||
|
if(gi->inputfc>=0)
|
||||||
|
InputType[2]=gi->inputfc;
|
||||||
|
cspec = gi->cspecial;
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
Giggles(gi->cspecial);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8 QuizKingData=0;
|
||||||
|
static uint8 HyperShotData=0;
|
||||||
|
static uint32 MahjongData=0;
|
||||||
|
static uint32 FTrainerData=0;
|
||||||
|
static uint8 TopRiderData=0;
|
||||||
|
|
||||||
|
static uint8 BWorldData[1+13+1];
|
||||||
|
|
||||||
|
static void UpdateFKB(void);
|
||||||
|
static void UpdateGamepad(void);
|
||||||
|
static void UpdateQuizKing(void);
|
||||||
|
static void UpdateHyperShot(void);
|
||||||
|
static void UpdateMahjong(void);
|
||||||
|
static void UpdateFTrainer(void);
|
||||||
|
static void UpdateTopRider(void);
|
||||||
|
|
||||||
|
static uint32 JSreturn=0;
|
||||||
|
int NoWaiting=1;
|
||||||
|
|
||||||
|
#ifndef EXTGUI
|
||||||
|
static void DoCheatSeq(void)
|
||||||
|
{
|
||||||
|
#if defined(DOS) || defined(SDL)
|
||||||
|
SilenceSound(1);
|
||||||
|
#endif
|
||||||
|
KillKeyboard();
|
||||||
|
KillVideo();
|
||||||
|
|
||||||
|
DoConsoleCheatConfig();
|
||||||
|
InitVideo(CurGame);
|
||||||
|
InitKeyboard();
|
||||||
|
#if defined(DOS) || defined(SDL)
|
||||||
|
SilenceSound(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "keyscan.h"
|
||||||
|
static char *keys=0;
|
||||||
|
static int DIPS=0;
|
||||||
|
|
||||||
|
static uint8 keyonce[MKK_COUNT];
|
||||||
|
#define KEY(__a) keys[MKK(__a)]
|
||||||
|
|
||||||
|
static int _keyonly(int a)
|
||||||
|
{
|
||||||
|
if(keys[a])
|
||||||
|
{
|
||||||
|
if(!keyonce[a])
|
||||||
|
{
|
||||||
|
keyonce[a]=1;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
keyonce[a]=0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define keyonly(__a) _keyonly(MKK(__a))
|
||||||
|
|
||||||
|
static int cidisabled=0;
|
||||||
|
|
||||||
|
static void KeyboardCommands(void)
|
||||||
|
{
|
||||||
|
int is_shift, is_alt;
|
||||||
|
|
||||||
|
keys=GetKeyboard();
|
||||||
|
|
||||||
|
if(InputType[2]==SIFC_FKB)
|
||||||
|
{
|
||||||
|
if(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_shift = KEY(LEFTSHIFT) | KEY(RIGHTSHIFT);
|
||||||
|
is_alt = KEY(LEFTALT) | KEY(RIGHTALT);
|
||||||
|
|
||||||
|
if(keyonly(F4))
|
||||||
|
{
|
||||||
|
if(is_shift) FCEUI_SetRenderDisable(-1, 2);
|
||||||
|
else FCEUI_SetRenderDisable(2, -1);
|
||||||
|
}
|
||||||
|
#ifdef SDL
|
||||||
|
if(keyonly(ENTER) && is_alt) ToggleFS();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NoWaiting&=~1;
|
||||||
|
if(KEY(GRAVE))
|
||||||
|
NoWaiting|=1;
|
||||||
|
|
||||||
|
if(gametype==GIT_FDS)
|
||||||
|
{
|
||||||
|
if(keyonly(F6)) FCEUI_FDSSelect();
|
||||||
|
if(keyonly(F8)) FCEUI_FDSInsert();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(keyonly(F9)) FCEUI_SaveSnapshot();
|
||||||
|
if(gametype!=GIT_NSF)
|
||||||
|
{
|
||||||
|
#ifndef EXTGUI
|
||||||
|
if(keyonly(F2)) DoCheatSeq();
|
||||||
|
#endif
|
||||||
|
if(keyonly(F5))
|
||||||
|
{
|
||||||
|
if(is_shift)
|
||||||
|
FCEUI_SaveMovie(NULL,0,NULL);
|
||||||
|
else
|
||||||
|
FCEUI_SaveState(NULL);
|
||||||
|
}
|
||||||
|
if(keyonly(F7))
|
||||||
|
{
|
||||||
|
if(is_shift)
|
||||||
|
FCEUI_LoadMovie(NULL,0);
|
||||||
|
else
|
||||||
|
FCEUI_LoadState(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(keyonly(F1)) FCEUI_ToggleTileView();
|
||||||
|
|
||||||
|
if(keyonly(MINUS)) DecreaseEmulationSpeed();
|
||||||
|
if(keyonly(EQUAL)) IncreaseEmulationSpeed();
|
||||||
|
if(keyonly(BACKSPACE)) FCEUI_MovieToggleFrameDisplay();
|
||||||
|
if(keyonly(BACKSLASH)) FCEUI_ToggleEmulationPause();
|
||||||
|
if(keyonly(RIGHTCONTROL)) FCEUI_FrameAdvance();
|
||||||
|
|
||||||
|
if(keyonly(F10)) FCEUI_ResetNES();
|
||||||
|
if(keyonly(F11)) FCEUI_PowerNES();
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
if(keyonly(F3)) GUI_Hide(-1);
|
||||||
|
if(KEY(F12)) GUI_RequestExit();
|
||||||
|
if(KEY(ESCAPE)) CloseGame();
|
||||||
|
#else
|
||||||
|
if(KEY(F12) || KEY(ESCAPE)) CloseGame();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(gametype==GIT_VSUNI)
|
||||||
|
{
|
||||||
|
if(keyonly(F8)) FCEUI_VSUniCoin();
|
||||||
|
if(keyonly(F6))
|
||||||
|
{
|
||||||
|
DIPS^=1;
|
||||||
|
FCEUI_VSUniToggleDIPView();
|
||||||
|
}
|
||||||
|
if(!(DIPS&1)) goto DIPSless;
|
||||||
|
if(keyonly(1)) FCEUI_VSUniToggleDIP(0);
|
||||||
|
if(keyonly(2)) FCEUI_VSUniToggleDIP(1);
|
||||||
|
if(keyonly(3)) FCEUI_VSUniToggleDIP(2);
|
||||||
|
if(keyonly(4)) FCEUI_VSUniToggleDIP(3);
|
||||||
|
if(keyonly(5)) FCEUI_VSUniToggleDIP(4);
|
||||||
|
if(keyonly(6)) FCEUI_VSUniToggleDIP(5);
|
||||||
|
if(keyonly(7)) FCEUI_VSUniToggleDIP(6);
|
||||||
|
if(keyonly(8)) FCEUI_VSUniToggleDIP(7);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static uint8 bbuf[32];
|
||||||
|
static int bbuft;
|
||||||
|
static int barcoder = 0;
|
||||||
|
|
||||||
|
if(keyonly(H)) FCEUI_NTSCSELHUE();
|
||||||
|
if(keyonly(T)) FCEUI_NTSCSELTINT();
|
||||||
|
if(KEY(KP_MINUS) || KEY(MINUS)) FCEUI_NTSCDEC();
|
||||||
|
if(KEY(KP_PLUS) || KEY(EQUAL)) FCEUI_NTSCINC();
|
||||||
|
|
||||||
|
if((InputType[2] == SIFC_BWORLD) || (cspec == SIS_DATACH))
|
||||||
|
{
|
||||||
|
if(keyonly(F8))
|
||||||
|
{
|
||||||
|
barcoder ^= 1;
|
||||||
|
if(!barcoder)
|
||||||
|
{
|
||||||
|
if(InputType[2] == SIFC_BWORLD)
|
||||||
|
{
|
||||||
|
strcpy(&BWorldData[1],bbuf);
|
||||||
|
BWorldData[0]=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FCEUI_DatachSet(bbuf);
|
||||||
|
FCEUI_DispMessage("Barcode Entered");
|
||||||
|
}
|
||||||
|
else { bbuft = 0; FCEUI_DispMessage("Enter Barcode");}
|
||||||
|
}
|
||||||
|
} else barcoder = 0;
|
||||||
|
|
||||||
|
#define SSM(x) \
|
||||||
|
{ if(barcoder) { if(bbuft < 13) {bbuf[bbuft++] = '0' + x; bbuf[bbuft] = 0;} FCEUI_DispMessage("Barcode: %s",bbuf);} \
|
||||||
|
else { \
|
||||||
|
if(is_shift) FCEUI_SelectMovie(x,1); \
|
||||||
|
else FCEUI_SelectState(x,1); \
|
||||||
|
} }
|
||||||
|
|
||||||
|
DIPSless:
|
||||||
|
if(keyonly(0)) SSM(0);
|
||||||
|
if(keyonly(1)) SSM(1);
|
||||||
|
if(keyonly(2)) SSM(2);
|
||||||
|
if(keyonly(3)) SSM(3);
|
||||||
|
if(keyonly(4)) SSM(4);
|
||||||
|
if(keyonly(5)) SSM(5);
|
||||||
|
if(keyonly(6)) SSM(6);
|
||||||
|
if(keyonly(7)) SSM(7);
|
||||||
|
if(keyonly(8)) SSM(8);
|
||||||
|
if(keyonly(9)) SSM(9);
|
||||||
|
#undef SSM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MK(x) {{BUTTC_KEYBOARD},{0},{MKK(x)},1}
|
||||||
|
#define MK2(x1,x2) {{BUTTC_KEYBOARD},{0},{MKK(x1),MKK(x2)},2}
|
||||||
|
|
||||||
|
#define MKZ() {{0},{0},{0},0}
|
||||||
|
|
||||||
|
#define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()}
|
||||||
|
|
||||||
|
ButtConfig GamePadConfig[4][10]={
|
||||||
|
/* Gamepad 1 */
|
||||||
|
{
|
||||||
|
MK(KP3), MK(KP2), MK(TAB), MK(ENTER), MK(W),MK(Z),
|
||||||
|
MK(A), MK(S), MKZ(), MKZ()
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Gamepad 2 */
|
||||||
|
GPZ(),
|
||||||
|
|
||||||
|
/* Gamepad 3 */
|
||||||
|
GPZ(),
|
||||||
|
|
||||||
|
/* Gamepad 4 */
|
||||||
|
GPZ()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void UpdateGamepad(void)
|
||||||
|
{
|
||||||
|
if(FCEUI_IsMovieActive()<0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static int rapid=0;
|
||||||
|
uint32 JS=0;
|
||||||
|
int x;
|
||||||
|
int wg;
|
||||||
|
|
||||||
|
rapid^=1;
|
||||||
|
|
||||||
|
for(wg=0;wg<4;wg++)
|
||||||
|
{
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
if(DTestButton(&GamePadConfig[wg][x]))
|
||||||
|
JS|=(1<<x)<<(wg<<3);
|
||||||
|
|
||||||
|
if(rapid)
|
||||||
|
for(x=0;x<2;x++)
|
||||||
|
if(DTestButton(&GamePadConfig[wg][8+x]))
|
||||||
|
JS|=(1<<x)<<(wg<<3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for(x=0;x<32;x+=8) /* Now, test to see if anything weird(up+down at same time)
|
||||||
|
// is happening, and correct */
|
||||||
|
// {
|
||||||
|
// if((JS & (0xC0<<x) ) == (0xC0<<x) ) JS&=~(0xC0<<x);
|
||||||
|
// if((JS & (0x30<<x) ) == (0x30<<x) ) JS&=~(0x30<<x);
|
||||||
|
// }
|
||||||
|
|
||||||
|
JSreturn=JS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtConfig powerpadsc[2][12]={
|
||||||
|
{
|
||||||
|
MK(O),MK(P),MK(BRACKET_LEFT),
|
||||||
|
MK(BRACKET_RIGHT),MK(K),MK(L),MK(SEMICOLON),
|
||||||
|
MK(APOSTROPHE),
|
||||||
|
MK(M),MK(COMMA),MK(PERIOD),MK(SLASH)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MK(O),MK(P),MK(BRACKET_LEFT),
|
||||||
|
MK(BRACKET_RIGHT),MK(K),MK(L),MK(SEMICOLON),
|
||||||
|
MK(APOSTROPHE),
|
||||||
|
MK(M),MK(COMMA),MK(PERIOD),MK(SLASH)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32 powerpadbuf[2]={0,0};
|
||||||
|
|
||||||
|
static uint32 UpdatePPadData(int w)
|
||||||
|
{
|
||||||
|
if(FCEUI_IsMovieActive()<0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32 r=0;
|
||||||
|
ButtConfig *ppadtsc=powerpadsc[w];
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<12;x++)
|
||||||
|
if(DTestButton(&ppadtsc[x])) r|=1<<x;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 MouseData[3]={0,0,0};
|
||||||
|
static uint8 fkbkeys[0x48];
|
||||||
|
|
||||||
|
void FCEUD_UpdateInput(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int t=0;
|
||||||
|
|
||||||
|
UpdatePhysicalInput();
|
||||||
|
KeyboardCommands();
|
||||||
|
|
||||||
|
for(x=0;x<2;x++)
|
||||||
|
switch(InputType[x])
|
||||||
|
{
|
||||||
|
case SI_GAMEPAD:t|=1;break;
|
||||||
|
case SI_ARKANOID:t|=2;break;
|
||||||
|
case SI_ZAPPER:t|=2;break;
|
||||||
|
case SI_POWERPADA:
|
||||||
|
case SI_POWERPADB:powerpadbuf[x]=UpdatePPadData(x);break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(InputType[2])
|
||||||
|
{
|
||||||
|
case SIFC_ARKANOID:t|=2;break;
|
||||||
|
case SIFC_SHADOW:t|=2;break;
|
||||||
|
case SIFC_FKB:if(cidisabled) UpdateFKB();break;
|
||||||
|
case SIFC_HYPERSHOT: UpdateHyperShot();break;
|
||||||
|
case SIFC_MAHJONG: UpdateMahjong();break;
|
||||||
|
case SIFC_QUIZKING: UpdateQuizKing();break;
|
||||||
|
case SIFC_FTRAINERB:
|
||||||
|
case SIFC_FTRAINERA: UpdateFTrainer();break;
|
||||||
|
case SIFC_TOPRIDER: UpdateTopRider();break;
|
||||||
|
case SIFC_OEKAKIDS:t|=2;break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(t&1)
|
||||||
|
UpdateGamepad();
|
||||||
|
|
||||||
|
if(t&2)
|
||||||
|
GetMouseData(MouseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
case SI_POWERPADB:InputDPtr=&powerpadbuf[x];break;
|
||||||
|
case SI_GAMEPAD:InputDPtr=&JSreturn;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(InputType[2])
|
||||||
|
{
|
||||||
|
case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
|
||||||
|
case SIFC_OEKAKIDS:InputDPtr=MouseData;t|=1;attrib=1;break;
|
||||||
|
case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
|
||||||
|
case SIFC_FKB:InputDPtr=fkbkeys;break;
|
||||||
|
case SIFC_HYPERSHOT:InputDPtr=&HyperShotData;break;
|
||||||
|
case SIFC_MAHJONG:InputDPtr=&MahjongData;break;
|
||||||
|
case SIFC_QUIZKING:InputDPtr=&QuizKingData;break;
|
||||||
|
case SIFC_TOPRIDER:InputDPtr=&TopRiderData;break;
|
||||||
|
case SIFC_BWORLD:InputDPtr=BWorldData;break;
|
||||||
|
case SIFC_FTRAINERA:
|
||||||
|
case SIFC_FTRAINERB:InputDPtr=&FTrainerData;break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FCEUI_SetInputFC(InputType[2],InputDPtr,attrib);
|
||||||
|
FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
|
||||||
|
|
||||||
|
if(t)
|
||||||
|
InitMouse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ButtConfig 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(DTestButton(&fkbmap[x]))
|
||||||
|
fkbkeys[x]=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ButtConfig HyperShotButtons[4]=
|
||||||
|
{
|
||||||
|
MK(Q),MK(W),MK(E),MK(R)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateHyperShot(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
HyperShotData=0;
|
||||||
|
for(x=0;x<0x4;x++)
|
||||||
|
{
|
||||||
|
if(DTestButton(&HyperShotButtons[x]))
|
||||||
|
HyperShotData|=1<<x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ButtConfig MahjongButtons[21]=
|
||||||
|
{
|
||||||
|
MK(Q),MK(W),MK(E),MK(R),MK(T),
|
||||||
|
MK(A),MK(S),MK(D),MK(F),MK(G),MK(H),MK(J),MK(K),MK(L),
|
||||||
|
MK(Z),MK(X),MK(C),MK(V),MK(B),MK(N),MK(M)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateMahjong(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
MahjongData=0;
|
||||||
|
for(x=0;x<21;x++)
|
||||||
|
{
|
||||||
|
if(DTestButton(&MahjongButtons[x]))
|
||||||
|
MahjongData|=1<<x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtConfig QuizKingButtons[6]=
|
||||||
|
{
|
||||||
|
MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateQuizKing(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
QuizKingData=0;
|
||||||
|
|
||||||
|
for(x=0;x<6;x++)
|
||||||
|
{
|
||||||
|
if(DTestButton(&QuizKingButtons[x]))
|
||||||
|
QuizKingData|=1<<x;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtConfig TopRiderButtons[8]=
|
||||||
|
{
|
||||||
|
MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y),MK(U),MK(I)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateTopRider(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
TopRiderData=0;
|
||||||
|
for(x=0;x<8;x++)
|
||||||
|
if(DTestButton(&TopRiderButtons[x]))
|
||||||
|
TopRiderData|=1<<x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtConfig FTrainerButtons[12]=
|
||||||
|
{
|
||||||
|
MK(O),MK(P),MK(BRACKET_LEFT),
|
||||||
|
MK(BRACKET_RIGHT),MK(K),MK(L),MK(SEMICOLON),
|
||||||
|
MK(APOSTROPHE),
|
||||||
|
MK(M),MK(COMMA),MK(PERIOD),MK(SLASH)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateFTrainer(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
FTrainerData=0;
|
||||||
|
|
||||||
|
for(x=0;x<12;x++)
|
||||||
|
{
|
||||||
|
if(DTestButton(&FTrainerButtons[x]))
|
||||||
|
FTrainerData|=1<<x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void subcon(char *text, ButtConfig *bc)
|
||||||
|
{
|
||||||
|
uint8 buf[256];
|
||||||
|
int wc;
|
||||||
|
|
||||||
|
for(wc=0;wc<MAXBUTTCONFIG;wc++)
|
||||||
|
{
|
||||||
|
sprintf(buf,"%s (%d)",text,wc+1);
|
||||||
|
DWaitButton(buf,bc,wc);
|
||||||
|
|
||||||
|
if(wc && bc->ButtType[wc]==bc->ButtType[wc-1] && bc->DeviceNum[wc]==bc->DeviceNum[wc-1] &&
|
||||||
|
bc->ButtonNum[wc]==bc->ButtonNum[wc-1])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bc->NumC=wc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigDevice(int which, int arg)
|
||||||
|
{
|
||||||
|
uint8 buf[256];
|
||||||
|
int x;
|
||||||
|
|
||||||
|
ButtonConfigBegin();
|
||||||
|
switch(which)
|
||||||
|
{
|
||||||
|
case FCFGD_QUIZKING:
|
||||||
|
for(x=0;x<6;x++)
|
||||||
|
{
|
||||||
|
sprintf(buf,"Quiz King Buzzer #%d", x+1);
|
||||||
|
subcon(buf,&QuizKingButtons[x]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FCFGD_HYPERSHOT:
|
||||||
|
for(x=0;x<4;x++)
|
||||||
|
{
|
||||||
|
sprintf(buf,"Hyper Shot %d: %s",((x&2)>>1)+1,(x&1)?"JUMP":"RUN");
|
||||||
|
subcon(buf,&HyperShotButtons[x]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FCFGD_POWERPAD:
|
||||||
|
for(x=0;x<12;x++)
|
||||||
|
{
|
||||||
|
sprintf(buf,"PowerPad %d: %d", (arg&1)+1,x+11);
|
||||||
|
subcon(buf,&powerpadsc[arg&1][x]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FCFGD_GAMEPAD:
|
||||||
|
{
|
||||||
|
char *str[10]={"A","B","SELECT","START","UP","DOWN","LEFT","RIGHT","Rapid A","Rapid B"};
|
||||||
|
for(x=0;x<10;x++)
|
||||||
|
{
|
||||||
|
sprintf(buf,"GamePad #%d: %s",arg+1,str[x]);
|
||||||
|
subcon(buf,&GamePadConfig[arg][x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonConfigEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CFGSTRUCT InputConfig[]={
|
||||||
|
ACA(UsrInputType),
|
||||||
|
AC(powerpadsc),
|
||||||
|
AC(QuizKingButtons),
|
||||||
|
AC(FTrainerButtons),
|
||||||
|
AC(HyperShotButtons),
|
||||||
|
AC(MahjongButtons),
|
||||||
|
AC(GamePadConfig),
|
||||||
|
AC(fkbmap),
|
||||||
|
ENDCFGSTRUCT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void InputCfg(char *text)
|
||||||
|
{
|
||||||
|
if(!strncasecmp(text,"gamepad",strlen("gamepad")))
|
||||||
|
{
|
||||||
|
ConfigDevice(FCFGD_GAMEPAD,(text[strlen("gamepad")]-'1')&3);
|
||||||
|
}
|
||||||
|
else if(!strncasecmp(text,"powerpad",strlen("powerpad")))
|
||||||
|
{
|
||||||
|
ConfigDevice(FCFGD_POWERPAD,(text[strlen("powerpad")]-'1')&1);
|
||||||
|
}
|
||||||
|
else if(!strcasecmp(text,"hypershot"))
|
||||||
|
ConfigDevice(FCFGD_HYPERSHOT,0);
|
||||||
|
else if(!strcasecmp(text,"quizking"))
|
||||||
|
ConfigDevice(FCFGD_QUIZKING,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FCExp(char *text)
|
||||||
|
{
|
||||||
|
static char *fccortab[11]={"none","arkanoid","shadow","4player","fkb","hypershot",
|
||||||
|
"mahjong","quizking","ftrainera","ftrainerb","oekakids"};
|
||||||
|
|
||||||
|
static int fccortabi[11]={SIFC_NONE,SIFC_ARKANOID,SIFC_SHADOW,
|
||||||
|
SIFC_4PLAYER,SIFC_FKB,SIFC_HYPERSHOT,SIFC_MAHJONG,SIFC_QUIZKING,
|
||||||
|
SIFC_FTRAINERA,SIFC_FTRAINERB,SIFC_OEKAKIDS};
|
||||||
|
int y;
|
||||||
|
for(y=0;y<11;y++)
|
||||||
|
if(!strcmp(fccortab[y],text))
|
||||||
|
UsrInputType[2]=fccortabi[y];
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *cortab[6]={"none","gamepad","zapper","powerpada","powerpadb","arkanoid"};
|
||||||
|
static int cortabi[6]={SI_NONE,SI_GAMEPAD,
|
||||||
|
SI_ZAPPER,SI_POWERPADA,SI_POWERPADB,SI_ARKANOID};
|
||||||
|
|
||||||
|
static void Input1(char *text)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
|
||||||
|
for(y=0;y<6;y++)
|
||||||
|
if(!strcmp(cortab[y],text))
|
||||||
|
UsrInputType[0]=cortabi[y];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Input2(char *text)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
|
||||||
|
for(y=0;y<6;y++)
|
||||||
|
if(!strcmp(cortab[y],text))
|
||||||
|
UsrInputType[1]=cortabi[y];
|
||||||
|
}
|
||||||
|
|
||||||
|
ARGPSTRUCT InputArgs[]={
|
||||||
|
{"-inputcfg",0,(void *)InputCfg,0x2000},
|
||||||
|
{"-fcexp",0,(void *)FCExp,0x2000},
|
||||||
|
{"-input1",0,(void *)Input1,0x2000},
|
||||||
|
{"-input2",0,(void *)Input2,0x2000},
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef _aosdfjk02fmasf
|
||||||
|
#define _aosdfjk02fmasf
|
||||||
|
#define MAXBUTTCONFIG 4
|
||||||
|
typedef struct {
|
||||||
|
uint8 ButtType[MAXBUTTCONFIG];
|
||||||
|
uint8 DeviceNum[MAXBUTTCONFIG];
|
||||||
|
uint16 ButtonNum[MAXBUTTCONFIG];
|
||||||
|
uint32 NumC;
|
||||||
|
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
|
||||||
|
} ButtConfig;
|
||||||
|
|
||||||
|
extern CFGSTRUCT InputConfig[];
|
||||||
|
extern ARGPSTRUCT InputArgs[];
|
||||||
|
void ParseGIInput(FCEUGI *GI);
|
||||||
|
|
||||||
|
#define BUTTC_KEYBOARD 0x00
|
||||||
|
#define BUTTC_JOYSTICK 0x01
|
||||||
|
#define BUTTC_MOUSE 0x02
|
||||||
|
|
||||||
|
#define FCFGD_GAMEPAD 1
|
||||||
|
#define FCFGD_POWERPAD 2
|
||||||
|
#define FCFGD_HYPERSHOT 3
|
||||||
|
#define FCFGD_QUIZKING 4
|
||||||
|
|
||||||
|
void InitOtherInput(void);
|
||||||
|
void InputUserActiveFix(void);
|
||||||
|
#ifdef EXTGUI
|
||||||
|
extern ButtConfig GamePadConfig[4][10];
|
||||||
|
extern ButtConfig powerpadsc[2][12];
|
||||||
|
extern ButtConfig QuizKingButtons[6];
|
||||||
|
extern ButtConfig FTrainerButtons[12];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void IncreaseEmulationSpeed(void);
|
||||||
|
void DecreaseEmulationSpeed(void);
|
||||||
|
|
||||||
|
void FCEUD_UpdateInput(void);
|
||||||
|
#endif
|
|
@ -0,0 +1,161 @@
|
||||||
|
#ifdef SDL
|
||||||
|
#include <SDL.h>
|
||||||
|
#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 MKK(k) SDLK_##k
|
||||||
|
#define MKK_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 often found 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_PAUSE 0xC5
|
||||||
|
#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
|
|
@ -0,0 +1,553 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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 <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "throttle.h"
|
||||||
|
|
||||||
|
#include "../common/cheat.h"
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
#include "dface.h"
|
||||||
|
|
||||||
|
extern int32 fps_scale;
|
||||||
|
|
||||||
|
int CloseGame(void);
|
||||||
|
|
||||||
|
static char *soundrecfn=0; /* File name of sound recording. */
|
||||||
|
|
||||||
|
static int ntsccol=0,ntschue=0,ntsctint=0;
|
||||||
|
int soundvol=100;
|
||||||
|
long soundq=0;
|
||||||
|
int _sound=1;
|
||||||
|
long soundrate=48000;
|
||||||
|
#ifdef WIN32
|
||||||
|
long soundbufsize=52;
|
||||||
|
#else
|
||||||
|
long soundbufsize=24;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FRAMESKIP
|
||||||
|
static int frameskip=0;
|
||||||
|
#endif
|
||||||
|
static int inited=0;
|
||||||
|
static int isloaded=0; // Is game loaded?
|
||||||
|
|
||||||
|
int srendlinev[2]={8,0};
|
||||||
|
int erendlinev[2]={231,239};
|
||||||
|
|
||||||
|
|
||||||
|
static uint8 *DrBaseDirectory;
|
||||||
|
|
||||||
|
int eoptions=0;
|
||||||
|
|
||||||
|
static void DriverKill(void);
|
||||||
|
static int DriverInitialize(FCEUGI *gi);
|
||||||
|
int gametype;
|
||||||
|
|
||||||
|
FCEUGI *CurGame=NULL;
|
||||||
|
|
||||||
|
static void ParseGI(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
ParseGIInput(gi);
|
||||||
|
gametype=gi->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef EXTGUI
|
||||||
|
void FCEUD_PrintError(char *s)
|
||||||
|
{
|
||||||
|
puts(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_Message(char *s)
|
||||||
|
{
|
||||||
|
fputs(s,stdout);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *cpalette=0;
|
||||||
|
static void LoadCPalette(void)
|
||||||
|
{
|
||||||
|
uint8 tmpp[192];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if(!(fp=FCEUD_UTF8fopen(cpalette,"rb")))
|
||||||
|
{
|
||||||
|
printf(" Error loading custom palette from file: %s\n",cpalette);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fread(tmpp,1,192,fp);
|
||||||
|
FCEUI_SetPaletteArray(tmpp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
#ifdef EXTGUI
|
||||||
|
extern CFGSTRUCT GUIConfig;
|
||||||
|
#endif
|
||||||
|
static CFGSTRUCT fceuconfig[]={
|
||||||
|
AC(soundrate),
|
||||||
|
AC(soundq),
|
||||||
|
AC(_sound),
|
||||||
|
AC(soundvol),
|
||||||
|
AC(soundbufsize),
|
||||||
|
ACS(cpalette),
|
||||||
|
AC(ntsctint),
|
||||||
|
AC(ntschue),
|
||||||
|
AC(ntsccol),
|
||||||
|
AC(eoptions),
|
||||||
|
ACA(srendlinev),
|
||||||
|
ACA(erendlinev),
|
||||||
|
ADDCFGSTRUCT(InputConfig),
|
||||||
|
ADDCFGSTRUCT(DriverConfig),
|
||||||
|
#ifdef EXTGUI
|
||||||
|
ADDCFGSTRUCT(GUIConfig),
|
||||||
|
#endif
|
||||||
|
ENDCFGSTRUCT
|
||||||
|
};
|
||||||
|
|
||||||
|
static void SaveConfig(void)
|
||||||
|
{
|
||||||
|
char tdir[2048];
|
||||||
|
sprintf(tdir,"%s"PSS"fceu98.cfg",DrBaseDirectory);
|
||||||
|
FCEUI_GetNTSCTH(&ntsctint, &ntschue);
|
||||||
|
SaveFCEUConfig(tdir,fceuconfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LoadConfig(void)
|
||||||
|
{
|
||||||
|
char tdir[2048];
|
||||||
|
sprintf(tdir,"%s"PSS"fceu98.cfg",DrBaseDirectory);
|
||||||
|
FCEUI_GetNTSCTH(&ntsctint, &ntschue); /* Get default settings for if
|
||||||
|
no config file exists. */
|
||||||
|
LoadFCEUConfig(tdir,fceuconfig);
|
||||||
|
InputUserActiveFix();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateDirs(void)
|
||||||
|
{
|
||||||
|
char *subs[7]={"fcs","fcm","snaps","gameinfo","sav","cheats","movie"};
|
||||||
|
char tdir[2048];
|
||||||
|
int x;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
mkdir(DrBaseDirectory);
|
||||||
|
for(x=0;x<6;x++)
|
||||||
|
{
|
||||||
|
sprintf(tdir,"%s"PSS"%s",DrBaseDirectory,subs[x]);
|
||||||
|
mkdir(tdir);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
mkdir(DrBaseDirectory,S_IRWXU);
|
||||||
|
for(x=0;x<6;x++)
|
||||||
|
{
|
||||||
|
sprintf(tdir,"%s"PSS"%s",DrBaseDirectory,subs[x]);
|
||||||
|
mkdir(tdir,S_IRWXU);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void DoArgs(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
static ARGPSTRUCT FCEUArgs[]={
|
||||||
|
{"-soundbufsize",0,&soundbufsize,0},
|
||||||
|
{"-soundrate",0,&soundrate,0},
|
||||||
|
{"-soundq",0,&soundq,0},
|
||||||
|
#ifdef FRAMESKIP
|
||||||
|
{"-frameskip",0,&frameskip,0},
|
||||||
|
#endif
|
||||||
|
{"-sound",0,&_sound,0},
|
||||||
|
{"-soundvol",0,&soundvol,0},
|
||||||
|
{"-cpalette",0,&cpalette,0x4001},
|
||||||
|
{"-soundrecord",0,&soundrecfn,0x4001},
|
||||||
|
|
||||||
|
{"-ntsccol",0,&ntsccol,0},
|
||||||
|
{"-pal",0,&eoptions,0x8000|EO_PAL},
|
||||||
|
|
||||||
|
{"-lowpass",0,&eoptions,0x8000|EO_LOWPASS},
|
||||||
|
{"-gg",0,&eoptions,0x8000|EO_GAMEGENIE},
|
||||||
|
{"-no8lim",0,&eoptions,0x8001},
|
||||||
|
{"-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,(int *)InputArgs,0,0},
|
||||||
|
{0,(int *)DriverArgs,0,0},
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseArguments(argc, argv, FCEUArgs);
|
||||||
|
if(cpalette)
|
||||||
|
{
|
||||||
|
if(cpalette[0]=='0')
|
||||||
|
if(cpalette[1]==0)
|
||||||
|
{
|
||||||
|
free(cpalette);
|
||||||
|
cpalette=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FCEUI_SetVidSystem((eoptions&EO_PAL)?1:0);
|
||||||
|
FCEUI_SetGameGenie((eoptions&EO_GAMEGENIE)?1:0);
|
||||||
|
FCEUI_SetLowPass((eoptions&EO_LOWPASS)?1:0);
|
||||||
|
|
||||||
|
FCEUI_DisableSpriteLimitation(eoptions&1);
|
||||||
|
FCEUI_SetSnapName(eoptions&EO_SNAPNAME);
|
||||||
|
|
||||||
|
for(x=0;x<2;x++)
|
||||||
|
{
|
||||||
|
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
|
||||||
|
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
|
||||||
|
}
|
||||||
|
|
||||||
|
FCEUI_SetRenderedLines(srendlinev[0],erendlinev[0],srendlinev[1],erendlinev[1]);
|
||||||
|
DoDriverArgs();
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "usage.h"
|
||||||
|
|
||||||
|
/* Loads a game, given a full path/filename. The driver code must be
|
||||||
|
initialized after the game is loaded, because the emulator code
|
||||||
|
provides data necessary for the driver code(number of scanlines to
|
||||||
|
render, what virtual input devices to use, etc.).
|
||||||
|
*/
|
||||||
|
int LoadGame(const char *path)
|
||||||
|
{
|
||||||
|
FCEUGI *tmp;
|
||||||
|
|
||||||
|
CloseGame();
|
||||||
|
if(!(tmp=FCEUI_LoadGame(path,1)))
|
||||||
|
return 0;
|
||||||
|
CurGame=tmp;
|
||||||
|
ParseGI(tmp);
|
||||||
|
RefreshThrottleFPS();
|
||||||
|
|
||||||
|
if(!DriverInitialize(tmp))
|
||||||
|
return(0);
|
||||||
|
if(soundrecfn)
|
||||||
|
{
|
||||||
|
if(!FCEUI_BeginWaveRecord(soundrecfn))
|
||||||
|
{
|
||||||
|
free(soundrecfn);
|
||||||
|
soundrecfn=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isloaded=1;
|
||||||
|
#ifdef EXTGUI
|
||||||
|
if(eoptions&EO_AUTOHIDE) GUI_Hide(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FCEUD_NetworkConnect();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Closes a game. Frees memory, and deinitializes the drivers. */
|
||||||
|
int CloseGame(void)
|
||||||
|
{
|
||||||
|
if(!isloaded) return(0);
|
||||||
|
FCEUI_CloseGame();
|
||||||
|
DriverKill();
|
||||||
|
isloaded=0;
|
||||||
|
CurGame=0;
|
||||||
|
|
||||||
|
if(soundrecfn)
|
||||||
|
FCEUI_EndWaveRecord();
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
GUI_Hide(0);
|
||||||
|
#endif
|
||||||
|
InputUserActiveFix();
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count);
|
||||||
|
|
||||||
|
void DoFun(void)
|
||||||
|
{
|
||||||
|
uint8 *gfx;
|
||||||
|
int32 *sound;
|
||||||
|
int32 ssize;
|
||||||
|
static int fskipc=0;
|
||||||
|
static int opause=0;
|
||||||
|
|
||||||
|
#ifdef FRAMESKIP
|
||||||
|
fskipc=(fskipc+1)%(frameskip+1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(NoWaiting) {gfx=0;}
|
||||||
|
FCEUI_Emulate(&gfx, &sound, &ssize, fskipc);
|
||||||
|
FCEUD_Update(gfx, sound, ssize);
|
||||||
|
|
||||||
|
if(opause!=FCEUI_EmulationPaused())
|
||||||
|
{
|
||||||
|
opause=FCEUI_EmulationPaused();
|
||||||
|
SilenceSound(opause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int CLImain(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(!(ret=FCEUI_Initialize()))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
DrBaseDirectory=GetBaseDirectory();
|
||||||
|
FCEUI_SetBaseDirectory(DrBaseDirectory);
|
||||||
|
|
||||||
|
CreateDirs();
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
if(argc==2 && !strcmp(argv[1],"-help")) // I hope no one has a game named "-help" :b
|
||||||
|
#else
|
||||||
|
if(argc<=1)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ShowUsage(argv[0]);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadConfig();
|
||||||
|
DoArgs(argc-2,&argv[1]);
|
||||||
|
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
|
||||||
|
if(cpalette)
|
||||||
|
LoadCPalette();
|
||||||
|
|
||||||
|
/* All the config files and arguments are parsed now. */
|
||||||
|
#ifdef EXTGUI
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
#else
|
||||||
|
if(!LoadGame(argv[argc-1]))
|
||||||
|
{
|
||||||
|
DriverKill();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(CurGame)
|
||||||
|
DoFun();
|
||||||
|
|
||||||
|
#if(0)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
for(x=1;x<argc;x++)
|
||||||
|
{ LoadGame(argv[x]); while(CurGame) DoFun(); }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CloseGame();
|
||||||
|
|
||||||
|
SaveConfig();
|
||||||
|
|
||||||
|
FCEUI_Kill();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DriverInitialize(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
SetSignals(CloseStuff);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialize video before all else, due to some wacko dependencies
|
||||||
|
in the SexyAL code(DirectSound) that need to be fixed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(!InitVideo(gi)) return 0;
|
||||||
|
inited|=4;
|
||||||
|
|
||||||
|
if(InitSound(gi))
|
||||||
|
inited|=1;
|
||||||
|
|
||||||
|
if(InitJoysticks())
|
||||||
|
inited|=2;
|
||||||
|
|
||||||
|
if(!InitKeyboard()) return 0;
|
||||||
|
inited|=8;
|
||||||
|
|
||||||
|
InitOtherInput();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DriverKill(void)
|
||||||
|
{
|
||||||
|
SaveConfig();
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
SetSignals(SIG_IGN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(inited&2)
|
||||||
|
KillJoysticks();
|
||||||
|
if(inited&8)
|
||||||
|
KillKeyboard();
|
||||||
|
if(inited&4)
|
||||||
|
KillVideo();
|
||||||
|
if(inited&1)
|
||||||
|
KillSound();
|
||||||
|
if(inited&16)
|
||||||
|
KillMouse();
|
||||||
|
inited=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count)
|
||||||
|
{
|
||||||
|
#ifdef NETWORK
|
||||||
|
extern int FCEUDnetplay;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ocount = Count;
|
||||||
|
// apply frame scaling to Count
|
||||||
|
Count = (Count<<8)/fps_scale;
|
||||||
|
if(Count)
|
||||||
|
{
|
||||||
|
int32 can=GetWriteSound();
|
||||||
|
static int uflow=0;
|
||||||
|
int32 tmpcan;
|
||||||
|
|
||||||
|
// don't underflow when scaling fps
|
||||||
|
if(can >= GetMaxSound() && fps_scale<=256) uflow=1; /* Go into massive underflow mode. */
|
||||||
|
|
||||||
|
if(can > Count) can=Count;
|
||||||
|
else uflow=0;
|
||||||
|
|
||||||
|
WriteSound(Buffer,can);
|
||||||
|
|
||||||
|
//if(uflow) puts("Underflow");
|
||||||
|
tmpcan = GetWriteSound();
|
||||||
|
// don't underflow when scaling fps
|
||||||
|
if(fps_scale>256 || ((tmpcan < Count*0.90) && !uflow))
|
||||||
|
{
|
||||||
|
if(XBuf && (inited&4) && !(NoWaiting & 2))
|
||||||
|
BlitScreen(XBuf);
|
||||||
|
Buffer+=can;
|
||||||
|
Count-=can;
|
||||||
|
if(Count)
|
||||||
|
{
|
||||||
|
if(NoWaiting)
|
||||||
|
{
|
||||||
|
can=GetWriteSound();
|
||||||
|
if(Count>can) Count=can;
|
||||||
|
WriteSound(Buffer,Count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(Count>0)
|
||||||
|
{
|
||||||
|
WriteSound(Buffer,(Count<ocount) ? Count : ocount);
|
||||||
|
Count -= ocount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} //else puts("Skipped");
|
||||||
|
#ifdef NETWORK
|
||||||
|
else if(!NoWaiting && FCEUDnetplay && (uflow || tmpcan >= (Count * 1.8)))
|
||||||
|
{
|
||||||
|
if(Count > tmpcan) Count=tmpcan;
|
||||||
|
while(tmpcan > 0)
|
||||||
|
{
|
||||||
|
// printf("Overwrite: %d\n", (Count <= tmpcan)?Count : tmpcan);
|
||||||
|
WriteSound(Buffer, (Count <= tmpcan)?Count : tmpcan);
|
||||||
|
tmpcan -= Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused()))
|
||||||
|
SpeedThrottle();
|
||||||
|
if(XBuf && (inited&4))
|
||||||
|
{
|
||||||
|
BlitScreen(XBuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FCEUD_UpdateInput();
|
||||||
|
//if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
|
||||||
|
// SpeedThrottle();
|
||||||
|
//if(XBuf && (inited&4))
|
||||||
|
//{
|
||||||
|
// BlitScreen(XBuf);
|
||||||
|
//}
|
||||||
|
//if(Count)
|
||||||
|
// WriteSound(Buffer,Count,NoWaiting);
|
||||||
|
//FCEUD_UpdateInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Maybe ifndef WXWINDOWS would be better? ^_^ */
|
||||||
|
#ifndef EXTGUI
|
||||||
|
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode)
|
||||||
|
{
|
||||||
|
return(fopen(fn,mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../../driver.h"
|
||||||
|
#include "../common/config.h"
|
||||||
|
#include "../common/args.h"
|
||||||
|
|
||||||
|
extern int eoptions;
|
||||||
|
#define EO_NO8LIM 1
|
||||||
|
#define EO_SUBASE 2
|
||||||
|
#define EO_CLIPSIDES 8
|
||||||
|
#define EO_SNAPNAME 16
|
||||||
|
#define EO_NOFOURSCORE 32
|
||||||
|
#define EO_NOTHROTTLE 64
|
||||||
|
#define EO_GAMEGENIE 128
|
||||||
|
#define EO_PAL 256
|
||||||
|
#define EO_LOWPASS 512
|
||||||
|
#define EO_AUTOHIDE 1024
|
||||||
|
|
||||||
|
extern int srendlinev[2],erendlinev[2];
|
||||||
|
extern int NoWaiting;
|
||||||
|
|
||||||
|
extern int soundvol;
|
||||||
|
extern long soundq;
|
||||||
|
extern int _sound;
|
||||||
|
extern long soundrate;
|
||||||
|
extern long soundbufsize;
|
||||||
|
|
||||||
|
int CLImain(int argc, char *argv[]);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
static const struct {
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int height;
|
||||||
|
unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
|
||||||
|
uint8 pixel_data[32 * 32 * 3 + 1];
|
||||||
|
} fceu_playicon = {
|
||||||
|
32, 32, 3,
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\0\0\0\0\0\0\0\0\0\\\223\373\\\223\373\267\317\373"
|
||||||
|
"\246\304\373\260\312\373\222\267\373\246\304\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\267\317\373\246\304\373\260\312\373\210\261\373\246\304\373\\\223\373\\"
|
||||||
|
"\223\373\210\261\373\222\267\373\267\317\373\241\301\373\\\223\373\\\223"
|
||||||
|
"\373\0\0\0\0\0\0\\\223\373\\\223\373\227\272\373\227\272\373\227\272\373"
|
||||||
|
"\227\272\373\227\272\373\227\272\373\\\223\373\\\223\373z`sr\242\373\227"
|
||||||
|
"\272\373\227\272\373\\\223\373\\\223\373\\\223\373\\\223\373\213\261\373"
|
||||||
|
"z\247\373\213\261\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\313i=\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40"
|
||||||
|
"\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40"
|
||||||
|
"\315Z\40\315Z\40\315Z\40\315Z\40\315Z\40\257T*\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40"
|
||||||
|
"\355\235\203\355\235\203\341\232\205\341\232\205\365\255\233\355\235\203"
|
||||||
|
"\355\235\203\350\250\232\365\255\233\355\235\203\307L\14\307L\14\307L\14"
|
||||||
|
"\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256B\12\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\315Z\40\273zc\233l_\325\225\205\325\225\205\325\225\205\273\212"
|
||||||
|
"\201\325\225\205\237qd\325\225\205\317\231\216\307L\14\307L\14\307L\14\307"
|
||||||
|
"L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256B\12\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\315Z\40\344\232\203\301\215\201\344\232\203\273\212\201\325\225"
|
||||||
|
"\205\2114\10\344\232\203\350\250\232\325\225\205\333\230\205\307L\14\307"
|
||||||
|
"L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\256"
|
||||||
|
"B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\315Z\40\2259\11}0\10\2259\11}0\10}0\10\307L\14\225"
|
||||||
|
"9\11d&\6}0\10}0\10\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14\307L\14"
|
||||||
|
"\307L\14\307L\14\307L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40\355\235\203"
|
||||||
|
"\355\233\201\355\235\203\355\235\203\355\235\203\365\255\233\355\235\203"
|
||||||
|
"\341\232\205\355\235\203\355\235\203\307L\14\365\255\233\355\235\203\365"
|
||||||
|
"\255\233\355\235\203\355\235\203\355\235\203\355\235\203\355\235\203\307"
|
||||||
|
"L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\315Z\40\325\225\205\311\221\204\311\221\204"
|
||||||
|
"\325\225\205\311\221\204\325\225\205\311\221\204\325\225\205\325\225\205"
|
||||||
|
"\311\221\204\307L\14\325\225\205\311\221\204\325\225\205\311\221\204\325"
|
||||||
|
"\225\205\311\221\204\325\225\205\311\221\204\307L\14\256B\12\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\315Z\40\325\225\205\325\225\205\325\225\205\325\225\205\325\225"
|
||||||
|
"\205\325\225\205\317\231\216\325\225\205\325\225\205\325\225\205\307L\14"
|
||||||
|
"\325\225\205\317\231\216\325\225\205\317\231\216\325\225\205\325\225\205"
|
||||||
|
"\273zc\241n_\307L\14\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0"
|
||||||
|
"\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\315Z\40\325\225\205\325"
|
||||||
|
"\225\205\325\225\205\365\255\233\333\243\231\325\225\205\333\230\205\325"
|
||||||
|
"\225\205\325\225\205\325\225\205\307L\14\325\225\205\317\223\204\325\225"
|
||||||
|
"\205\333\230\205\325\225\205\325\225\205\333\230\205\317\223\204\307L\14"
|
||||||
|
"\256B\12\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\315Z\40\325\225\205\325\225\205\325\225\205"
|
||||||
|
"\325\225\205\311\221\204\325\225\205\325\225\205\325\225\205\344\232\203"
|
||||||
|
"\273\212\201\307L\14\325\225\205\273\212\201\325\225\205\325\225\205\344"
|
||||||
|
"\232\203\273\212\201\344\232\203\273\212\201\341\232\205\256B\12\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\257T*d&\6d&\6d&\6d&\6d&\6d&\6d&\6d&\6}0\10d&\6\256B\12d&\6p+\7"
|
||||||
|
"d&\6d&\6}0\10d&\6}0\10d&\6d&\6\223@\26\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\234\243"
|
||||||
|
"\335\213\237\344\237\244\333\251\247\326\237\244\333\\\223\373\267\252\317"
|
||||||
|
"\222\241\341\267\252\317\210\237\346\241\245\332\267\252\317\246\246\327"
|
||||||
|
"\246\246\327\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0"
|
||||||
|
"\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\257hT\\\223\373\213\261\373\\\223"
|
||||||
|
"\373\241\301\373\210\261\373\246\304\373\222\267\373\241\301\373\260\312"
|
||||||
|
"\373\\\223\373\237\277\373\246\304\373\267\317\373\241\301\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\0\0\0\0\0\0\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\246\304\373\\\223\373\241"
|
||||||
|
"\301\373\210\261\373\246\304\373\222\267\373\241\301\373\260\312\373\\\223"
|
||||||
|
"\373\237\277\373\246\304\373\267\317\373\241\301\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0\0\0\0\0\\\223\373"
|
||||||
|
"\\\223\373\\\223\373D\203\270D\203\270\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\0\0"
|
||||||
|
"\0\0\0\0\\\223\373\\\223\373(\211n\0\247\0\0n\0(\211n\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\0\0\0\0\0\0\\\223\373(\211n\0\247\0\0\247\0\0\247\0\0\247\0(\211n\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\210\261\373\246\304\373\241\301\373z\247"
|
||||||
|
"\373\\\223\373\227\272\373\227\272\373\227\272\373\227\272\373\227\272\373"
|
||||||
|
"\227\272\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\0\0\0\0\0\0(\211n\0\247\0\0n\0\0\247\0\\\215\12fs\16"
|
||||||
|
"\0\247\0(\211n\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\"
|
||||||
|
"\223\373\\\223\373Z\231Z[\230SZ\231Z[\230SZ\231Z[\230S\\\223\373\0\0\0\0"
|
||||||
|
"\0\0\0\247\0\0\247\0\0\247\0\0\247\0vy\7p|\7\0\247\0\0\247\0(\211n\\\223"
|
||||||
|
"\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373"
|
||||||
|
"\\\223\373\\\223\373\\\223\373\\\223\373\\\223\373b\237L\200\317\20\200\317"
|
||||||
|
"\20\200\317\20\200\317\20\200\317\20\200\317\20[\223H\0\0\0\0\0\0\230P.\323"
|
||||||
|
"d0\230P.\323d0\221M&\313`%\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323"
|
||||||
|
"d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323d0\230P.\323"
|
||||||
|
"d0\230P.\323d0\230P.\323d0\0\0\0\0\0\0\0\0\0\237N(\225E\35\237N(\225E\35"
|
||||||
|
"\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237"
|
||||||
|
"N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N(\225E\35\237N("
|
||||||
|
"\225E\35\237N(\225E\35\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||||
|
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
* Copyright (C) 2002 Paul Kuliniewicz
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* PK: SDL joystick input stuff */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "sdl.h"
|
||||||
|
|
||||||
|
#define MAX_JOYSTICKS 32
|
||||||
|
static SDL_Joystick *Joysticks[MAX_JOYSTICKS] = {NULL};
|
||||||
|
|
||||||
|
int DTestButtonJoy(ButtConfig *bc)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<bc->NumC;x++)
|
||||||
|
{
|
||||||
|
if(bc->ButtonNum[x]&0x8000) /* Axis "button" */
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
pos = SDL_JoystickGetAxis(Joysticks[bc->DeviceNum[x]], bc->ButtonNum[x]&16383);
|
||||||
|
if ((bc->ButtonNum[x]&0x4000) && pos <= -16383)
|
||||||
|
return(1);
|
||||||
|
else if (!(bc->ButtonNum[x]&0x4000) && pos >= 16363)
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
else if(bc->ButtonNum[x]&0x2000) /* Hat "button" */
|
||||||
|
{
|
||||||
|
if( SDL_JoystickGetHat(Joysticks[bc->DeviceNum[x]],(bc->ButtonNum[x]>>8)&0x1F) & (bc->ButtonNum[x]&0xFF))
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(SDL_JoystickGetButton(Joysticks[bc->DeviceNum[x]], bc->ButtonNum[x] ))
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jinited=0;
|
||||||
|
|
||||||
|
/* Cleanup opened joysticks. */
|
||||||
|
int KillJoysticks (void)
|
||||||
|
{
|
||||||
|
int n; /* joystick index */
|
||||||
|
|
||||||
|
if(!jinited) return(0);
|
||||||
|
for (n = 0; n < MAX_JOYSTICKS; n++)
|
||||||
|
{
|
||||||
|
if (Joysticks[n] != 0)
|
||||||
|
SDL_JoystickClose(Joysticks[n]);
|
||||||
|
Joysticks[n]=0;
|
||||||
|
}
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize joysticks. */
|
||||||
|
int InitJoysticks (void)
|
||||||
|
{
|
||||||
|
int n; /* joystick index */
|
||||||
|
int total;
|
||||||
|
|
||||||
|
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||||
|
total=SDL_NumJoysticks();
|
||||||
|
if(total>MAX_JOYSTICKS) total=MAX_JOYSTICKS;
|
||||||
|
|
||||||
|
for (n = 0; n < total; n++)
|
||||||
|
{
|
||||||
|
/* Open the joystick under SDL. */
|
||||||
|
Joysticks[n] = SDL_JoystickOpen(n);
|
||||||
|
//printf("Could not open joystick %d: %s.\n",
|
||||||
|
//joy[n] - 1, SDL_GetError());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
jinited=1;
|
||||||
|
return(1);
|
||||||
|
}
|
|
@ -0,0 +1,224 @@
|
||||||
|
#include "sdl.h"
|
||||||
|
#include <SDL/SDL_net.h>
|
||||||
|
#include "sdl-netplay.h"
|
||||||
|
|
||||||
|
char *ServerHost;
|
||||||
|
|
||||||
|
static int LocalPortTCP=0xFCE;
|
||||||
|
static int LocalPortUDP=0xFCE;
|
||||||
|
static int RemotePortTCP=0xFCE;
|
||||||
|
|
||||||
|
static int RemotePortUDP; /* Not configurable, figured out during handshake. */
|
||||||
|
|
||||||
|
static TCPsocket Socket;
|
||||||
|
static UDPsocket UDPSocket;
|
||||||
|
static SDLNet_SocketSet set;
|
||||||
|
|
||||||
|
|
||||||
|
static void en32(uint8 *buf, uint32 morp)
|
||||||
|
{
|
||||||
|
buf[0]=morp;
|
||||||
|
buf[1]=morp>>8;
|
||||||
|
buf[2]=morp>>16;
|
||||||
|
buf[3]=morp>>24;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 de32(uint8 *morp)
|
||||||
|
{
|
||||||
|
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int FCEUD_NetworkConnect(void)
|
||||||
|
{
|
||||||
|
IPaddress rip;
|
||||||
|
|
||||||
|
SDLNet_Init();
|
||||||
|
|
||||||
|
if(netplay==1) /* Be a server. */
|
||||||
|
{
|
||||||
|
TCPsocket tmp;
|
||||||
|
Uint16 p=LocalPortUDP;
|
||||||
|
|
||||||
|
SDLNet_ResolveHost(&rip,NULL,LocalPortTCP);
|
||||||
|
|
||||||
|
UDPSocket=SDLNet_UDP_Open(&p);
|
||||||
|
|
||||||
|
tmp=SDLNet_TCP_Open(&rip);
|
||||||
|
Socket=SDLNet_TCP_Accept(&tmp);
|
||||||
|
|
||||||
|
memcpy(&rip,SDLNet_TCP_GetPeerAddress(Socket),sizeof(IPaddress));
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8 buf[12];
|
||||||
|
uint32 player=1;
|
||||||
|
|
||||||
|
magic=SDL_GetTicks();
|
||||||
|
|
||||||
|
SDLNet_Write32(buf,uport);
|
||||||
|
SDLNet_Write32(buf+4,1);
|
||||||
|
SDLNet_Write32(buf+8,magic);
|
||||||
|
|
||||||
|
SDLNet_TCP_Send(Socket, buf, 12);
|
||||||
|
|
||||||
|
/* Get the UDP port the client is waiting for data on. */
|
||||||
|
SDLNet_TCP_Recv(Socket, buf, 2);
|
||||||
|
RemotePortUDP=de32(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* Be a client */
|
||||||
|
{
|
||||||
|
SDLNet_ResolveHost(&rip,ServerHost,RemotePortTCP);
|
||||||
|
Socket=SDLNet_TCP_Open(&rip);
|
||||||
|
|
||||||
|
{
|
||||||
|
Uint16 p=LocalPortUDP;
|
||||||
|
uint8 buf[12];
|
||||||
|
|
||||||
|
UDPSocket=SDLNet_UDP_Open(&p);
|
||||||
|
|
||||||
|
/* Now, tell the server what local UDP port it should send to. */
|
||||||
|
en32(buf,p);
|
||||||
|
SDLNet_TCP_Send(Socket, buf, 4);
|
||||||
|
|
||||||
|
/* Get the UDP port from the server we should send data to. */
|
||||||
|
SDLNet_TCP_Recv(Socket, buf, 12);
|
||||||
|
RemotePortUDP=de32(buf);
|
||||||
|
magic=de32(buf+8);
|
||||||
|
}
|
||||||
|
set=SDLNet_AllocSocketSet(1);
|
||||||
|
SDLNet_TCP_AddSocket(set,TCPSocket);
|
||||||
|
SDLNet_UDP_AddSocket(set,UDPSocket);
|
||||||
|
} // End client connect code.
|
||||||
|
|
||||||
|
rip.port=RemotePortUDP;
|
||||||
|
SDLNet_UDP_Bind(UDPSocket, 0, &rip);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int CheckUDP(uint8 *packet, int32 len, int32 alt)
|
||||||
|
{
|
||||||
|
uint32 crc;
|
||||||
|
uint32 repcrc;
|
||||||
|
|
||||||
|
crc=FCEUI_CRC32(0,packet+4,len+8);
|
||||||
|
repcrc=de32(packet);
|
||||||
|
|
||||||
|
if(crc!=repcrc) return(0); /* CRC32 mismatch, bad packet. */
|
||||||
|
packet+=4;
|
||||||
|
|
||||||
|
if(de32(packet)!=magic) /* Magic number mismatch, bad or spoofed packet. */
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
packet+=4;
|
||||||
|
if(alt)
|
||||||
|
{
|
||||||
|
if(de32(packet)<incounter) /* Time warped packet. */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(de32(packet)!=incounter) /* Time warped packet. */
|
||||||
|
return(0);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Be careful where these MakeXXX() functions are used. */
|
||||||
|
static uint8 *MakeUDP(uint8 *data, int32 len)
|
||||||
|
{
|
||||||
|
/* UDP packet data header is 12 bytes in length. */
|
||||||
|
static uint8 buf[12+32]; // arbitrary 32.
|
||||||
|
|
||||||
|
en32(buf+4,magic);
|
||||||
|
en32(buf+8,outcounter);
|
||||||
|
memcpy(buf+12,data,len);
|
||||||
|
en32(buf,FCEUI_CRC32(0,buf+4,8+len));
|
||||||
|
return(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 *MakeTCP(uint8 *data, int32 len)
|
||||||
|
{
|
||||||
|
/* TCP packet data header is 4 bytes in length. */
|
||||||
|
static uint8 buf[4+32]; // arbitrary 32.
|
||||||
|
|
||||||
|
en32(buf,outcounter);
|
||||||
|
memcpy(buf+4,data,len);
|
||||||
|
return(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UDPHEADSIZE 12
|
||||||
|
#define TCPHEADSIZE 4
|
||||||
|
|
||||||
|
void FCEUD_NetworkClose(void)
|
||||||
|
{
|
||||||
|
SDLNet_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1 byte to server */
|
||||||
|
int FCEUD_SendDataToServer(uint8 v,uint8 cmd)
|
||||||
|
{
|
||||||
|
UDPpacket upack;
|
||||||
|
|
||||||
|
upack.channel=0;
|
||||||
|
upack.data=MakeUDP(data,1);
|
||||||
|
upack.len=upack.maxlen=UDPHEADSIZE+1;
|
||||||
|
upack.status=0;
|
||||||
|
|
||||||
|
SDLNet_UDP_Send(UDPSocket,0,&upack);
|
||||||
|
|
||||||
|
outcounter++;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_SendDataToClients(uint8 *data)
|
||||||
|
{
|
||||||
|
UDPpacket upack;
|
||||||
|
|
||||||
|
SDLNet_TCP_Send(Socket,MakeTCP(data,5),TCPHEADSIZE+5);
|
||||||
|
|
||||||
|
upack.channel=0;
|
||||||
|
upack.data=MakeUDP(data,5);
|
||||||
|
upack.len=upack.maxlen=UDPHEADSIZE+5;
|
||||||
|
upack.status=0;
|
||||||
|
|
||||||
|
SDLNet_UDP_Send(UDPSocket,0,&upack);
|
||||||
|
|
||||||
|
outcounter++;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUD_GetDataFromServer(uint8 *data)
|
||||||
|
{
|
||||||
|
uint8 buf[128];
|
||||||
|
NoWaiting&=~2;
|
||||||
|
|
||||||
|
while(SDLNet_CheckSockets(set,1)==0)
|
||||||
|
{
|
||||||
|
// do something here.
|
||||||
|
}
|
||||||
|
if(SDLNet_SocketReady(Socket))
|
||||||
|
{
|
||||||
|
SDLNet_TCP_Recv
|
||||||
|
if(de32(buf)==incounter) /* New packet, keep. */
|
||||||
|
{
|
||||||
|
unsigned long beefie;
|
||||||
|
memcpy(data,buf+TCPHEADSIZE,5);
|
||||||
|
incounter++;
|
||||||
|
|
||||||
|
if(!ioctl(Socket,FIONREAD,&beefie))
|
||||||
|
if(beefie)
|
||||||
|
NoWaiting|=2;
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(SDLNet_SocketReady(UDPSocket)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,241 @@
|
||||||
|
#define GL_GLEXT_LEGACY
|
||||||
|
#ifdef APPLEOPENGL
|
||||||
|
#include <OpenGL/gl.h>
|
||||||
|
#include <OpenGL/glu.h>
|
||||||
|
#include <OpenGL/glext.h>
|
||||||
|
#else
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glu.h>
|
||||||
|
#include <GL/glext.h>
|
||||||
|
#endif
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "sdl-opengl.h"
|
||||||
|
#include "../common/vidblit.h"
|
||||||
|
|
||||||
|
#ifndef APIENTRY
|
||||||
|
#define APIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static GLuint textures[2]={0,0}; // Normal image, scanline overlay.
|
||||||
|
|
||||||
|
static int left,right,top,bottom; // right and bottom are not inclusive.
|
||||||
|
static int scanlines;
|
||||||
|
static void *HiBuffer;
|
||||||
|
|
||||||
|
void APIENTRY (*p_glBindTexture)(GLenum target,GLuint texture);
|
||||||
|
void APIENTRY (*p_glColorTableEXT)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
|
||||||
|
void APIENTRY (*p_glTexImage2D)( GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLsizei width, GLsizei height, GLint border,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const GLvoid *pixels );
|
||||||
|
void APIENTRY (*p_glBegin)(GLenum mode);
|
||||||
|
void APIENTRY (*p_glVertex2f)(GLfloat x, GLfloat y);
|
||||||
|
void APIENTRY (*p_glTexCoord2f)(GLfloat s, GLfloat t);
|
||||||
|
void APIENTRY (*p_glEnd)(void);
|
||||||
|
void APIENTRY (*p_glEnable)(GLenum cap);
|
||||||
|
void APIENTRY (*p_glBlendFunc)(GLenum sfactor, GLenum dfactor);
|
||||||
|
const GLubyte* APIENTRY (*p_glGetString)(GLenum name);
|
||||||
|
void APIENTRY (*p_glViewport)(GLint x, GLint y,GLsizei width, GLsizei height);
|
||||||
|
void APIENTRY (*p_glGenTextures)(GLsizei n, GLuint *textures);
|
||||||
|
void APIENTRY (*p_glDeleteTextures)(GLsizei n,const GLuint *textures);
|
||||||
|
void APIENTRY (*p_glTexParameteri)(GLenum target, GLenum pname, GLint param);
|
||||||
|
void APIENTRY (*p_glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||||
|
void APIENTRY (*p_glLoadIdentity)(void);
|
||||||
|
void APIENTRY (*p_glClear)(GLbitfield mask);
|
||||||
|
void APIENTRY (*p_glMatrixMode)(GLenum mode);
|
||||||
|
void APIENTRY (*p_glDisable)(GLenum cap);
|
||||||
|
|
||||||
|
void SetOpenGLPalette(uint8 *data)
|
||||||
|
{
|
||||||
|
if(!HiBuffer)
|
||||||
|
{
|
||||||
|
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||||
|
p_glColorTableEXT(GL_TEXTURE_2D,GL_RGB,256,GL_RGBA,GL_UNSIGNED_BYTE,data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetPaletteBlitToHigh((uint8*)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlitOpenGL(uint8 *buf)
|
||||||
|
{
|
||||||
|
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||||
|
if(HiBuffer)
|
||||||
|
{
|
||||||
|
static int xo=0;
|
||||||
|
xo=(xo+1)&3;
|
||||||
|
Blit8ToHigh(buf,(uint8*)HiBuffer,256,240,256*4,1,1);
|
||||||
|
if(!xo)
|
||||||
|
p_glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,256,256, 0, GL_RGBA,GL_UNSIGNED_BYTE,
|
||||||
|
HiBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
|
||||||
|
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, 256, 256, 0,
|
||||||
|
GL_COLOR_INDEX,GL_UNSIGNED_BYTE,buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_glBegin(GL_QUADS);
|
||||||
|
p_glTexCoord2f(1.0f*left/256, 1.0f*bottom/256); // Bottom left of our picture.
|
||||||
|
p_glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||||
|
|
||||||
|
p_glTexCoord2f(1.0f*right/256, 1.0f*bottom/256); // Bottom right of our picture.
|
||||||
|
p_glVertex2f( 1.0f, -1.0f); // Bottom right of target.
|
||||||
|
|
||||||
|
p_glTexCoord2f(1.0f*right/256, 1.0f*top/256); // Top right of our picture.
|
||||||
|
p_glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||||
|
|
||||||
|
p_glTexCoord2f(1.0f*left/256, 1.0f*top/256); // Top left of our picture.
|
||||||
|
p_glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||||
|
p_glEnd();
|
||||||
|
|
||||||
|
//glDisable(GL_BLEND);
|
||||||
|
if(scanlines)
|
||||||
|
{
|
||||||
|
p_glEnable(GL_BLEND);
|
||||||
|
|
||||||
|
p_glBindTexture(GL_TEXTURE_2D, textures[1]);
|
||||||
|
p_glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
|
||||||
|
|
||||||
|
p_glBegin(GL_QUADS);
|
||||||
|
|
||||||
|
p_glTexCoord2f(1.0f*left/256, 1.0f*bottom/256); // Bottom left of our picture.
|
||||||
|
p_glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||||
|
|
||||||
|
p_glTexCoord2f(1.0f*right/256, 1.0f*bottom/256); // Bottom right of our picture.
|
||||||
|
p_glVertex2f( 1.0f, -1.0f); // Bottom right of target.
|
||||||
|
|
||||||
|
p_glTexCoord2f(1.0f*right/256, 1.0f*top/256); // Top right of our picture.
|
||||||
|
p_glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||||
|
|
||||||
|
p_glTexCoord2f(1.0f*left/256, 1.0f*top/256); // Top left of our picture.
|
||||||
|
p_glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||||
|
|
||||||
|
p_glEnd();
|
||||||
|
p_glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
SDL_GL_SwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillOpenGL(void)
|
||||||
|
{
|
||||||
|
if(textures[0])
|
||||||
|
p_glDeleteTextures(2, &textures[0]);
|
||||||
|
textures[0]=0;
|
||||||
|
if(HiBuffer)
|
||||||
|
{
|
||||||
|
free(HiBuffer);
|
||||||
|
HiBuffer=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Rectangle, left, right(not inclusive), top, bottom(not inclusive). */
|
||||||
|
|
||||||
|
int InitOpenGL(int l, int r, int t, int b, double xscale,double yscale, int efx, int ipolate,
|
||||||
|
int stretchx, int stretchy, SDL_Surface *screen)
|
||||||
|
{
|
||||||
|
const char *extensions;
|
||||||
|
|
||||||
|
#define LFG(x) if(!(p_##x = SDL_GL_GetProcAddress(#x))) return(0);
|
||||||
|
|
||||||
|
#define LFGN(x) p_##x = SDL_GL_GetProcAddress(#x)
|
||||||
|
|
||||||
|
LFG(glBindTexture);
|
||||||
|
LFGN(glColorTableEXT);
|
||||||
|
LFG(glTexImage2D);
|
||||||
|
LFG(glBegin);
|
||||||
|
LFG(glVertex2f);
|
||||||
|
LFG(glTexCoord2f);
|
||||||
|
LFG(glEnd);
|
||||||
|
LFG(glEnable);
|
||||||
|
LFG(glBlendFunc);
|
||||||
|
LFG(glGetString);
|
||||||
|
LFG(glViewport);
|
||||||
|
LFG(glGenTextures);
|
||||||
|
LFG(glDeleteTextures);
|
||||||
|
LFG(glTexParameteri);
|
||||||
|
LFG(glClearColor);
|
||||||
|
LFG(glLoadIdentity);
|
||||||
|
LFG(glClear);
|
||||||
|
LFG(glMatrixMode);
|
||||||
|
LFG(glDisable);
|
||||||
|
|
||||||
|
left=l;
|
||||||
|
right=r;
|
||||||
|
top=t;
|
||||||
|
bottom=b;
|
||||||
|
|
||||||
|
HiBuffer=0;
|
||||||
|
|
||||||
|
extensions=(const char*)p_glGetString(GL_EXTENSIONS);
|
||||||
|
|
||||||
|
if((efx&2) || !extensions || !p_glColorTableEXT || !strstr(extensions,"GL_EXT_paletted_texture"))
|
||||||
|
{
|
||||||
|
if(!(efx&2)) // Don't want to print out a warning message in this case...
|
||||||
|
FCEU_printf("Paletted texture extension not found. Using slower texture format...");
|
||||||
|
HiBuffer=malloc(4*256*256);
|
||||||
|
memset(HiBuffer,0x00,4*256*256);
|
||||||
|
#ifndef LSB_FIRST
|
||||||
|
InitBlitToHigh(4,0xFF000000,0xFF0000,0xFF00,efx&2,0);
|
||||||
|
#else
|
||||||
|
InitBlitToHigh(4,0xFF,0xFF00,0xFF0000,efx&2,0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int rw=(r-l)*xscale;
|
||||||
|
int rh=(b-t)*yscale;
|
||||||
|
int sx=(screen->w-rw)/2; // Start x
|
||||||
|
int sy=(screen->h-rh)/2; // Start y
|
||||||
|
|
||||||
|
if(stretchx) { sx=0; rw=screen->w; }
|
||||||
|
if(stretchy) { sy=0; rh=screen->h; }
|
||||||
|
p_glViewport(sx, sy, rw, rh);
|
||||||
|
}
|
||||||
|
p_glGenTextures(2, &textures[0]);
|
||||||
|
scanlines=0;
|
||||||
|
|
||||||
|
if(efx&1)
|
||||||
|
{
|
||||||
|
uint8 *buf;
|
||||||
|
int x,y;
|
||||||
|
|
||||||
|
scanlines=1;
|
||||||
|
|
||||||
|
p_glBindTexture(GL_TEXTURE_2D, textures[1]);
|
||||||
|
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||||
|
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||||
|
|
||||||
|
buf=(uint8*)malloc(256*(256*2)*4);
|
||||||
|
|
||||||
|
for(y=0;y<(256*2);y++)
|
||||||
|
for(x=0;x<256;x++)
|
||||||
|
{
|
||||||
|
buf[y*256*4+x*4]=0;
|
||||||
|
buf[y*256*4+x*4+1]=0;
|
||||||
|
buf[y*256*4+x*4+2]=0;
|
||||||
|
buf[y*256*4+x*4+3]=(y&1)?0x00:0xFF; //?0xa0:0xFF; // <-- Pretty
|
||||||
|
//buf[y*256+x]=(y&1)?0x00:0xFF;
|
||||||
|
}
|
||||||
|
p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, (scanlines==2)?256*4:512, 0,
|
||||||
|
GL_RGBA,GL_UNSIGNED_BYTE,buf);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
p_glBindTexture(GL_TEXTURE_2D, textures[0]);
|
||||||
|
|
||||||
|
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||||
|
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||||
|
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
|
||||||
|
p_glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
|
||||||
|
p_glEnable(GL_TEXTURE_2D);
|
||||||
|
p_glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black.
|
||||||
|
p_glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
|
p_glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
p_glLoadIdentity();
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
void SetOpenGLPalette(uint8 *data);
|
||||||
|
void BlitOpenGL(uint8 *buf);
|
||||||
|
void KillOpenGL(void);
|
||||||
|
int InitOpenGL(int l, int r, int t, int b, double xscale,double yscale, int efx, int ipolate,
|
||||||
|
int stretchx, int stretchy, SDL_Surface *screen);
|
||||||
|
|
|
@ -0,0 +1,373 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "sdl.h"
|
||||||
|
|
||||||
|
#ifdef USE_SEXYAL
|
||||||
|
|
||||||
|
#include "../sexyal/sexyal.h"
|
||||||
|
|
||||||
|
static SexyAL *Interface;
|
||||||
|
static SexyAL_device *Output;
|
||||||
|
static SexyAL_format format;
|
||||||
|
static SexyAL_buffering buffering;
|
||||||
|
|
||||||
|
uint32 GetMaxSound(void)
|
||||||
|
{
|
||||||
|
return(buffering.totalsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 GetWriteSound(void)
|
||||||
|
{
|
||||||
|
return(Output->CanWrite(Output));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSound(int32 *Buffer, int Count)
|
||||||
|
{
|
||||||
|
//printf("%d\n",Output->CanWrite(Output));
|
||||||
|
Output->Write(Output, Buffer, Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitSound(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
if(!_sound) return(0);
|
||||||
|
|
||||||
|
memset(&format,0,sizeof(format));
|
||||||
|
memset(&buffering,0,sizeof(buffering));
|
||||||
|
|
||||||
|
FCEUI_SetSoundVolume(soundvol);
|
||||||
|
FCEUI_SetSoundQuality(soundq);
|
||||||
|
|
||||||
|
Interface=SexyAL_Init(0);
|
||||||
|
|
||||||
|
format.sampformat=SEXYAL_FMT_PCMS32S16;
|
||||||
|
format.channels=gi->soundchan?gi->soundchan:1;
|
||||||
|
format.rate=gi->soundrate?gi->soundrate:soundrate;
|
||||||
|
buffering.fragcount=buffering.fragsize=0;
|
||||||
|
buffering.ms=soundbufsize;
|
||||||
|
|
||||||
|
FCEUI_printf("\nInitializing sound...");
|
||||||
|
if(!(Output=Interface->Open(Interface,SEXYAL_ID_UNUSED,&format,&buffering)))
|
||||||
|
{
|
||||||
|
FCEUD_PrintError("Error opening a sound device.");
|
||||||
|
Interface->Destroy(Interface);
|
||||||
|
Interface=0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(soundq && format.rate!=48000 && format.rate!=44100 && format.rate!=96000)
|
||||||
|
{
|
||||||
|
FCEUD_PrintError("Set sound playback rate neither 44100, 48000, nor 96000, but needs to be when in high-quality sound mode.");
|
||||||
|
KillSound();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(format.rate<8192 || format.rate > 96000)
|
||||||
|
{
|
||||||
|
FCEUD_PrintError("Set rate is out of range [8192-96000]");
|
||||||
|
KillSound();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
FCEUI_printf("\n Bits: %u\n Rate: %u\n Channels: %u\n Byte order: CPU %s\n Buffer size: %u sample frames(%f ms)\n",(format.sampformat>>4)*8,format.rate,format.channels,format.byteorder?"Reversed":"Native",buffering.totalsize,(double)buffering.totalsize*1000/format.rate);
|
||||||
|
|
||||||
|
format.sampformat=SEXYAL_FMT_PCMS32S16;
|
||||||
|
format.channels=gi->soundchan?gi->soundchan:1;
|
||||||
|
format.byteorder=0;
|
||||||
|
|
||||||
|
//format.rate=gi->soundrate?gi->soundrate:soundrate;
|
||||||
|
|
||||||
|
Output->SetConvert(Output,&format);
|
||||||
|
|
||||||
|
FCEUI_Sound(format.rate);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SilenceSound(int n)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int KillSound(void)
|
||||||
|
{
|
||||||
|
FCEUI_Sound(0);
|
||||||
|
if(Output)
|
||||||
|
Output->Close(Output);
|
||||||
|
if(Interface)
|
||||||
|
Interface->Destroy(Interface);
|
||||||
|
Interface=0;
|
||||||
|
if(!Output) return(0);
|
||||||
|
Output=0;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif USE_JACKACK /* Use JACK Audio Connection Kit */
|
||||||
|
|
||||||
|
#include <jack/jack.h>
|
||||||
|
#include <jack/ringbuffer.h>
|
||||||
|
|
||||||
|
static jack_port_t *output_port = NULL;
|
||||||
|
static jack_client_t *client = NULL;
|
||||||
|
static jack_ringbuffer_t *tmpbuf = NULL;
|
||||||
|
static unsigned int BufferSize;
|
||||||
|
|
||||||
|
static int process(jack_nframes_t nframes, void *arg)
|
||||||
|
{
|
||||||
|
jack_default_audio_sample_t *out = (jack_default_audio_sample_t *) jack_port_get_buffer(output_port, nframes);
|
||||||
|
size_t canread;
|
||||||
|
|
||||||
|
canread = jack_ringbuffer_read_space(tmpbuf) / sizeof(jack_default_audio_sample_t);
|
||||||
|
|
||||||
|
if(canread > nframes)
|
||||||
|
canread = nframes;
|
||||||
|
|
||||||
|
jack_ringbuffer_read(tmpbuf, out,canread * sizeof(jack_default_audio_sample_t));
|
||||||
|
nframes -= canread;
|
||||||
|
|
||||||
|
if(nframes) /* Buffer underflow. Hmm. */
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 GetMaxSound(void)
|
||||||
|
{
|
||||||
|
return(BufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 GetWriteSound(void)
|
||||||
|
{
|
||||||
|
return(jack_readbuffer_write_space / sizeof(jack_default_audio_sample_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void DeadSound(void *arg)
|
||||||
|
{
|
||||||
|
puts("AGH! Sound server hates us! Let's go on a rampage.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitSound(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
const char **ports;
|
||||||
|
|
||||||
|
client = jack_client_new("FCE Ultra");
|
||||||
|
|
||||||
|
jack_set_process_callback(client, process, 0);
|
||||||
|
jack_on_shutdown(client, DeadSound, 0);
|
||||||
|
|
||||||
|
printf("%ld\n",jack_get_sample_rate(client));
|
||||||
|
|
||||||
|
output_port = jack_port_register(client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
|
||||||
|
|
||||||
|
BufferSize = soundbufsize * soundrate / 1000;
|
||||||
|
|
||||||
|
tmpbuf = jack_ringbuffer_create(BufferSize * sizeof(jack_default_audio_sample_t));
|
||||||
|
|
||||||
|
jack_activate(client);
|
||||||
|
|
||||||
|
|
||||||
|
ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
|
||||||
|
jack_connect(client, jack_port_name(output_port), ports[0]);
|
||||||
|
free(ports);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSound(int32 *buf, int Count)
|
||||||
|
{
|
||||||
|
jack_default_audio_sample_t jbuf[Count];
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<Count;x++,buf++)
|
||||||
|
jbuf[x] = *buf;
|
||||||
|
|
||||||
|
jack_ringbuffer_write(tmpbuf, jbuf, sizeof(jack_default_audio_sample_t) * Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SilenceSound(int n)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int KillSound(void)
|
||||||
|
{
|
||||||
|
if(tmpbuf)
|
||||||
|
{
|
||||||
|
jack_ringbuffer_free(tmpbuf);
|
||||||
|
tmpbuf = NULL;
|
||||||
|
}
|
||||||
|
if(client)
|
||||||
|
{
|
||||||
|
jack_client_close(client);
|
||||||
|
client = NULL;
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* So we'll use SDL's evil sound support. Ok. */
|
||||||
|
static volatile int *Buffer = 0;
|
||||||
|
static unsigned int BufferSize;
|
||||||
|
static unsigned int BufferRead;
|
||||||
|
static unsigned int BufferWrite;
|
||||||
|
static volatile unsigned int BufferIn;
|
||||||
|
|
||||||
|
static void fillaudio(void *udata, uint8 *stream, int len)
|
||||||
|
{
|
||||||
|
int16 *tmps = (int16*)stream;
|
||||||
|
len >>= 1;
|
||||||
|
|
||||||
|
while(len)
|
||||||
|
{
|
||||||
|
int16 sample = 0;
|
||||||
|
if(BufferIn)
|
||||||
|
{
|
||||||
|
sample = Buffer[BufferRead];
|
||||||
|
BufferRead = (BufferRead + 1) % BufferSize;
|
||||||
|
BufferIn--;
|
||||||
|
}
|
||||||
|
else sample = 0;
|
||||||
|
|
||||||
|
*tmps = sample;
|
||||||
|
tmps++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitSound(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
SDL_AudioSpec spec;
|
||||||
|
if(!_sound) return(0);
|
||||||
|
|
||||||
|
memset(&spec,0,sizeof(spec));
|
||||||
|
if(SDL_InitSubSystem(SDL_INIT_AUDIO)<0)
|
||||||
|
{
|
||||||
|
puts(SDL_GetError());
|
||||||
|
KillSound();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
spec.freq = soundrate;
|
||||||
|
spec.format = AUDIO_S16SYS;
|
||||||
|
spec.channels = 1;
|
||||||
|
spec.samples = 256;
|
||||||
|
spec.callback = fillaudio;
|
||||||
|
spec.userdata = 0;
|
||||||
|
|
||||||
|
BufferSize = soundbufsize * soundrate / 1000;
|
||||||
|
|
||||||
|
BufferSize -= spec.samples * 2; /* SDL uses at least double-buffering, so
|
||||||
|
multiply by 2. */
|
||||||
|
|
||||||
|
if(BufferSize < spec.samples) BufferSize = spec.samples;
|
||||||
|
|
||||||
|
Buffer = malloc(sizeof(int) * BufferSize);
|
||||||
|
BufferRead = BufferWrite = BufferIn = 0;
|
||||||
|
|
||||||
|
//printf("SDL Size: %d, Internal size: %d\n",spec.samples,BufferSize);
|
||||||
|
|
||||||
|
if(SDL_OpenAudio(&spec,0)<0)
|
||||||
|
{
|
||||||
|
puts(SDL_GetError());
|
||||||
|
KillSound();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
SDL_PauseAudio(0);
|
||||||
|
FCEUI_Sound(soundrate);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32 GetMaxSound(void)
|
||||||
|
{
|
||||||
|
return(BufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 GetWriteSound(void)
|
||||||
|
{
|
||||||
|
return(BufferSize - BufferIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSound(int32 *buf, int Count)
|
||||||
|
{
|
||||||
|
while(Count)
|
||||||
|
{
|
||||||
|
while(BufferIn == BufferSize) SDL_Delay(1);
|
||||||
|
Buffer[BufferWrite] = *buf;
|
||||||
|
Count--;
|
||||||
|
BufferWrite = (BufferWrite + 1) % BufferSize;
|
||||||
|
BufferIn++;
|
||||||
|
buf++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SilenceSound(int n)
|
||||||
|
{
|
||||||
|
SDL_PauseAudio(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
int KillSound(void)
|
||||||
|
{
|
||||||
|
FCEUI_Sound(0);
|
||||||
|
SDL_CloseAudio();
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||||
|
if(Buffer)
|
||||||
|
{
|
||||||
|
free(Buffer);
|
||||||
|
Buffer = 0;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int mute=0;
|
||||||
|
static int soundvolume=100;
|
||||||
|
void FCEUD_SoundVolumeAdjust(int n)
|
||||||
|
{
|
||||||
|
switch(n)
|
||||||
|
{
|
||||||
|
case -1: soundvolume-=10; if(soundvolume<0) soundvolume=0; break;
|
||||||
|
case 0: soundvolume=100; break;
|
||||||
|
case 1: soundvolume+=10; if(soundvolume>150) soundvolume=150; break;
|
||||||
|
}
|
||||||
|
mute=0;
|
||||||
|
FCEUI_SetSoundVolume(soundvolume);
|
||||||
|
FCEU_DispMessage("Sound volume %d.", soundvolume);
|
||||||
|
}
|
||||||
|
void FCEUD_SoundToggle(void)
|
||||||
|
{
|
||||||
|
if(mute)
|
||||||
|
{
|
||||||
|
mute=0;
|
||||||
|
FCEUI_SetSoundVolume(soundvolume);
|
||||||
|
FCEU_DispMessage("Sound mute off.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mute=1;
|
||||||
|
FCEUI_SetSoundVolume(0);
|
||||||
|
FCEU_DispMessage("Sound mute on.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "throttle.h"
|
||||||
|
|
||||||
|
static uint64 tfreq;
|
||||||
|
static uint64 desiredfps;
|
||||||
|
|
||||||
|
static int32 fps_scale_table[]=
|
||||||
|
{ 3, 3, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 2048 };
|
||||||
|
int32 fps_scale = 256;
|
||||||
|
|
||||||
|
#define fps_table_size (sizeof(fps_scale_table)/sizeof(fps_scale_table[0]))
|
||||||
|
|
||||||
|
void RefreshThrottleFPS(void)
|
||||||
|
{
|
||||||
|
desiredfps=FCEUI_GetDesiredFPS()>>8;
|
||||||
|
desiredfps=(desiredfps*fps_scale)>>8;
|
||||||
|
tfreq=10000000;
|
||||||
|
tfreq<<=16; /* Adjustment for fps returned from FCEUI_GetDesiredFPS(). */
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeedThrottle(void)
|
||||||
|
{
|
||||||
|
static uint64 ttime,ltime=0;
|
||||||
|
|
||||||
|
waiter:
|
||||||
|
|
||||||
|
ttime=SDL_GetTicks();
|
||||||
|
ttime*=10000;
|
||||||
|
|
||||||
|
if( (ttime-ltime) < (tfreq/desiredfps) )
|
||||||
|
{
|
||||||
|
int64 delay;
|
||||||
|
delay=(tfreq/desiredfps)-(ttime-ltime);
|
||||||
|
if(delay>0)
|
||||||
|
SDL_Delay(delay/10000);
|
||||||
|
//printf("%d\n",(tfreq/desiredfps)-(ttime-ltime));
|
||||||
|
//SDL_Delay((tfreq/desiredfps)-(ttime-ltime));
|
||||||
|
goto waiter;
|
||||||
|
}
|
||||||
|
if( (ttime-ltime) >= (tfreq*4/desiredfps))
|
||||||
|
ltime=ttime;
|
||||||
|
else
|
||||||
|
ltime+=tfreq/desiredfps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IncreaseEmulationSpeed(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=1; fps_scale_table[i]<fps_scale; i++)
|
||||||
|
;
|
||||||
|
fps_scale = fps_scale_table[i+1];
|
||||||
|
|
||||||
|
RefreshThrottleFPS();
|
||||||
|
|
||||||
|
FCEU_DispMessage("emulation speed %d%%",(fps_scale*100)>>8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecreaseEmulationSpeed(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=1; fps_scale_table[i]<fps_scale; i++)
|
||||||
|
;
|
||||||
|
fps_scale = fps_scale_table[i-1];
|
||||||
|
|
||||||
|
RefreshThrottleFPS();
|
||||||
|
|
||||||
|
FCEU_DispMessage("emulation speed %d%%",(fps_scale*100)>>8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_SetEmulationSpeed(int cmd)
|
||||||
|
{
|
||||||
|
switch(cmd)
|
||||||
|
{
|
||||||
|
case EMUSPEED_SLOWEST: fps_scale=fps_scale_table[0]; break;
|
||||||
|
case EMUSPEED_SLOWER: DecreaseEmulationSpeed(); break;
|
||||||
|
case EMUSPEED_NORMAL: fps_scale=256; break;
|
||||||
|
case EMUSPEED_FASTER: IncreaseEmulationSpeed(); break;
|
||||||
|
case EMUSPEED_FASTEST: fps_scale=fps_scale_table[fps_table_size-1]; break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshThrottleFPS();
|
||||||
|
|
||||||
|
FCEU_DispMessage("emulation speed %d%%",(fps_scale*100)>>8);
|
||||||
|
}
|
|
@ -0,0 +1,432 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "sdl-opengl.h"
|
||||||
|
#include "../common/vidblit.h"
|
||||||
|
|
||||||
|
#include "sdl-icon.h"
|
||||||
|
#include "dface.h"
|
||||||
|
|
||||||
|
SDL_Surface *screen;
|
||||||
|
SDL_Surface *BlitBuf; // Used as a buffer when using hardware-accelerated blits.
|
||||||
|
SDL_Surface *IconSurface=NULL;
|
||||||
|
|
||||||
|
static int curbpp;
|
||||||
|
static int srendline,erendline;
|
||||||
|
static int tlines;
|
||||||
|
static int inited=0;
|
||||||
|
|
||||||
|
#ifdef OPENGL
|
||||||
|
extern int sdlhaveogl;
|
||||||
|
static int usingogl;
|
||||||
|
static double exs,eys;
|
||||||
|
#else
|
||||||
|
static int exs,eys;
|
||||||
|
#endif
|
||||||
|
static int eefx;
|
||||||
|
|
||||||
|
#define NWIDTH (256-((eoptions&EO_CLIPSIDES)?16:0))
|
||||||
|
#define NOFFSET (eoptions&EO_CLIPSIDES?8:0)
|
||||||
|
|
||||||
|
|
||||||
|
static int paletterefresh;
|
||||||
|
|
||||||
|
/* Return 1 if video was killed, 0 otherwise(video wasn't initialized). */
|
||||||
|
int KillVideo(void)
|
||||||
|
{
|
||||||
|
if(IconSurface)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(IconSurface);
|
||||||
|
IconSurface=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(inited&1)
|
||||||
|
{
|
||||||
|
#ifdef OPENGL
|
||||||
|
if(usingogl)
|
||||||
|
KillOpenGL();
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if(curbpp>8)
|
||||||
|
KillBlitToHigh();
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
inited&=~1;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
inited=0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sponge;
|
||||||
|
|
||||||
|
int InitVideo(FCEUGI *gi)
|
||||||
|
{
|
||||||
|
const SDL_VideoInfo *vinf;
|
||||||
|
int flags=0;
|
||||||
|
|
||||||
|
FCEUI_printf("Initializing video...");
|
||||||
|
|
||||||
|
FCEUI_GetCurrentVidSystem(&srendline,&erendline);
|
||||||
|
|
||||||
|
if(_fullscreen) sponge=Settings.specialfs;
|
||||||
|
else sponge=Settings.special;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef OPENGL
|
||||||
|
usingogl=0;
|
||||||
|
if(_opengl && sdlhaveogl && !sponge)
|
||||||
|
{
|
||||||
|
flags=SDL_OPENGL;
|
||||||
|
usingogl=1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
GUI_SetVideo(_fullscreen, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!(SDL_WasInit(SDL_INIT_VIDEO)&SDL_INIT_VIDEO))
|
||||||
|
if(SDL_InitSubSystem(SDL_INIT_VIDEO)==-1)
|
||||||
|
{
|
||||||
|
FCEUD_PrintError(SDL_GetError());
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
inited|=1;
|
||||||
|
|
||||||
|
SDL_ShowCursor(0);
|
||||||
|
tlines=erendline-srendline+1;
|
||||||
|
|
||||||
|
vinf=SDL_GetVideoInfo();
|
||||||
|
|
||||||
|
if(vinf->hw_available)
|
||||||
|
flags|=SDL_HWSURFACE;
|
||||||
|
|
||||||
|
if(_fullscreen)
|
||||||
|
flags|=SDL_FULLSCREEN;
|
||||||
|
|
||||||
|
flags|=SDL_HWPALETTE;
|
||||||
|
|
||||||
|
//flags|=SDL_DOUBLEBUF;
|
||||||
|
#ifdef OPENGL
|
||||||
|
if(usingogl)
|
||||||
|
{
|
||||||
|
FCEU_printf("\n Initializing with OpenGL(Use \"-opengl 0\" to disable).\n");
|
||||||
|
if(_doublebuf)
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if(_doublebuf && (flags&SDL_HWSURFACE))
|
||||||
|
flags|=SDL_DOUBLEBUF;
|
||||||
|
|
||||||
|
if(_fullscreen)
|
||||||
|
{
|
||||||
|
int desbpp=_bpp;
|
||||||
|
|
||||||
|
exs=_xscalefs;
|
||||||
|
eys=_yscalefs;
|
||||||
|
eefx=_efxfs;
|
||||||
|
|
||||||
|
#ifdef OPENGL
|
||||||
|
if(!usingogl) {exs=(int)exs;eys=(int)eys;}
|
||||||
|
else desbpp=0;
|
||||||
|
|
||||||
|
if(sponge)
|
||||||
|
{
|
||||||
|
exs=eys=2;
|
||||||
|
if(sponge == 3 || sponge == 4) exs = eys = 3;
|
||||||
|
eefx=0;
|
||||||
|
if(sponge == 1 || sponge == 3) desbpp = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( (usingogl && !_stretchx) || !usingogl)
|
||||||
|
#endif
|
||||||
|
if(_xres<NWIDTH*exs || exs <= 0.01)
|
||||||
|
{
|
||||||
|
FCEUD_PrintError("xscale out of bounds.");
|
||||||
|
KillVideo();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OPENGL
|
||||||
|
if( (usingogl && !_stretchy) || !usingogl)
|
||||||
|
#endif
|
||||||
|
if(_yres<tlines*eys || eys <= 0.01)
|
||||||
|
{
|
||||||
|
FCEUD_PrintError("yscale out of bounds.");
|
||||||
|
KillVideo();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
GUI_SetVideo(_fullscreen, _xres, _yres);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENGL
|
||||||
|
if(!(screen = SDL_SetVideoMode(_xres, _yres, desbpp, flags)))
|
||||||
|
#else
|
||||||
|
if(!(screen = SDL_SetVideoMode(_xres, _yres, desbpp, flags)))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
FCEUD_PrintError(SDL_GetError());
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int desbpp=0;
|
||||||
|
|
||||||
|
exs=_xscale;
|
||||||
|
eys=_yscale;
|
||||||
|
eefx=_efx;
|
||||||
|
|
||||||
|
if(sponge)
|
||||||
|
{
|
||||||
|
exs=eys=2;
|
||||||
|
if(sponge >= 3) exs=eys=3;
|
||||||
|
eefx=0;
|
||||||
|
// SDL's 32bpp->16bpp code is slighty faster than mine, at least :/
|
||||||
|
if(sponge == 1 || sponge == 3) desbpp=32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OPENGL
|
||||||
|
if(!usingogl) {exs=(int)exs;eys=(int)eys;}
|
||||||
|
if(exs <= 0.01)
|
||||||
|
{
|
||||||
|
FCEUD_PrintError("xscale out of bounds.");
|
||||||
|
KillVideo();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
if(eys <= 0.01)
|
||||||
|
{
|
||||||
|
FCEUD_PrintError("yscale out of bounds.");
|
||||||
|
KillVideo();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
GUI_SetVideo(_fullscreen, (NWIDTH*exs), tlines*eys);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
screen = SDL_SetVideoMode((NWIDTH*exs), tlines*eys, desbpp, flags);
|
||||||
|
}
|
||||||
|
curbpp=screen->format->BitsPerPixel;
|
||||||
|
if(!screen)
|
||||||
|
{
|
||||||
|
FCEUD_PrintError(SDL_GetError());
|
||||||
|
KillVideo();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
//BlitBuf=SDL_CreateRGBSurface(SDL_HWSURFACE,256,240,screen->format->BitsPerPixel,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,0);
|
||||||
|
|
||||||
|
inited=1;
|
||||||
|
|
||||||
|
FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n",screen->w,screen->h,screen->format->BitsPerPixel,_fullscreen?"full screen":"");
|
||||||
|
if(curbpp!=16 && curbpp!=24 && curbpp!=8 && curbpp!=32)
|
||||||
|
{
|
||||||
|
FCEU_printf(" Sorry, %dbpp modes are not supported by FCE Ultra. Supported bit depths are 8bpp, 16bpp, and 32bpp.\n",curbpp);
|
||||||
|
KillVideo();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gi->name)
|
||||||
|
SDL_WM_SetCaption(gi->name,gi->name);
|
||||||
|
else
|
||||||
|
SDL_WM_SetCaption("FCE Ultra","FCE Ultra");
|
||||||
|
|
||||||
|
#ifdef LSB_FIRST
|
||||||
|
IconSurface=SDL_CreateRGBSurfaceFrom((void *)fceu_playicon.pixel_data,32,32,24,32*3,0xFF,0xFF00,0xFF0000,0x00);
|
||||||
|
#else
|
||||||
|
IconSurface=SDL_CreateRGBSurfaceFrom((void *)fceu_playicon.pixel_data,32,32,24,32*3,0xFF0000,0xFF00,0xFF,0x00);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SDL_WM_SetIcon(IconSurface,0);
|
||||||
|
|
||||||
|
paletterefresh=1;
|
||||||
|
|
||||||
|
if(curbpp>8)
|
||||||
|
#ifdef OPENGL
|
||||||
|
if(!usingogl)
|
||||||
|
#endif
|
||||||
|
InitBlitToHigh(curbpp>>3,screen->format->Rmask,screen->format->Gmask,screen->format->Bmask,eefx,sponge);
|
||||||
|
#ifdef OPENGL
|
||||||
|
if(usingogl)
|
||||||
|
if(!InitOpenGL((eoptions&EO_CLIPSIDES)?8:0,256-((eoptions&EO_CLIPSIDES)?8:0),srendline,erendline+1,exs,eys,eefx,_openglip,_stretchx,_stretchy,screen))
|
||||||
|
{
|
||||||
|
FCEUD_PrintError("Error initializing OpenGL.");
|
||||||
|
KillVideo();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToggleFS(void)
|
||||||
|
{
|
||||||
|
extern FCEUGI *CurGame;
|
||||||
|
KillVideo();
|
||||||
|
_fullscreen=!_fullscreen;
|
||||||
|
|
||||||
|
if(!InitVideo(CurGame))
|
||||||
|
{
|
||||||
|
_fullscreen=!_fullscreen;
|
||||||
|
InitVideo(CurGame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_Color psdl[256];
|
||||||
|
void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
|
||||||
|
{
|
||||||
|
psdl[index].r=r;
|
||||||
|
psdl[index].g=g;
|
||||||
|
psdl[index].b=b;
|
||||||
|
|
||||||
|
paletterefresh=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_GetPalette(uint8 index, uint8 *r, uint8 *g, uint8 *b)
|
||||||
|
{
|
||||||
|
*r=psdl[index].r;
|
||||||
|
*g=psdl[index].g;
|
||||||
|
*b=psdl[index].b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RedoPalette(void)
|
||||||
|
{
|
||||||
|
#ifdef OPENGL
|
||||||
|
if(usingogl)
|
||||||
|
SetOpenGLPalette((uint8*)psdl);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if(curbpp>8)
|
||||||
|
SetPaletteBlitToHigh((uint8*)psdl);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_SetPalette(screen,SDL_PHYSPAL,psdl,0,256);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LockConsole(){}
|
||||||
|
void UnlockConsole(){}
|
||||||
|
void BlitScreen(uint8 *XBuf)
|
||||||
|
{
|
||||||
|
SDL_Surface *TmpScreen;
|
||||||
|
uint8 *dest;
|
||||||
|
int xo=0,yo=0;
|
||||||
|
|
||||||
|
if(!screen) return;
|
||||||
|
|
||||||
|
if(paletterefresh)
|
||||||
|
{
|
||||||
|
RedoPalette();
|
||||||
|
paletterefresh=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OPENGL
|
||||||
|
if(usingogl)
|
||||||
|
{
|
||||||
|
BlitOpenGL(XBuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
XBuf+=srendline*256;
|
||||||
|
|
||||||
|
if(BlitBuf) TmpScreen=BlitBuf;
|
||||||
|
else TmpScreen=screen;
|
||||||
|
|
||||||
|
if(SDL_MUSTLOCK(TmpScreen))
|
||||||
|
if(SDL_LockSurface(TmpScreen))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest=(uint8*)TmpScreen->pixels;
|
||||||
|
|
||||||
|
if(_fullscreen)
|
||||||
|
{
|
||||||
|
xo=(((TmpScreen->w-NWIDTH*exs))/2);
|
||||||
|
dest+=xo*(curbpp>>3);
|
||||||
|
if(TmpScreen->h>(tlines*eys))
|
||||||
|
{
|
||||||
|
yo=((TmpScreen->h-tlines*eys)/2);
|
||||||
|
dest+=yo*TmpScreen->pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(curbpp>8)
|
||||||
|
{
|
||||||
|
if(BlitBuf)
|
||||||
|
Blit8ToHigh(XBuf+NOFFSET,dest, NWIDTH, tlines, TmpScreen->pitch,1,1);
|
||||||
|
else
|
||||||
|
Blit8ToHigh(XBuf+NOFFSET,dest, NWIDTH, tlines, TmpScreen->pitch,exs,eys);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(BlitBuf)
|
||||||
|
Blit8To8(XBuf+NOFFSET,dest, NWIDTH, tlines, TmpScreen->pitch,1,1,0,sponge);
|
||||||
|
else
|
||||||
|
Blit8To8(XBuf+NOFFSET,dest, NWIDTH, tlines, TmpScreen->pitch,exs,eys,eefx,sponge);
|
||||||
|
}
|
||||||
|
if(SDL_MUSTLOCK(TmpScreen))
|
||||||
|
SDL_UnlockSurface(TmpScreen);
|
||||||
|
|
||||||
|
if(BlitBuf)
|
||||||
|
{
|
||||||
|
SDL_Rect srect;
|
||||||
|
SDL_Rect drect;
|
||||||
|
|
||||||
|
srect.x=0;
|
||||||
|
srect.y=0;
|
||||||
|
srect.w=NWIDTH;
|
||||||
|
srect.h=tlines;
|
||||||
|
|
||||||
|
drect.x=0;
|
||||||
|
drect.y=0;
|
||||||
|
drect.w=exs*NWIDTH;
|
||||||
|
drect.h=eys*tlines;
|
||||||
|
|
||||||
|
SDL_BlitSurface(BlitBuf, &srect,screen,&drect);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_UpdateRect(screen, xo, yo, NWIDTH*exs, tlines*eys);
|
||||||
|
|
||||||
|
if(screen->flags&SDL_DOUBLEBUF)
|
||||||
|
SDL_Flip(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 PtoV(uint16 x, uint16 y)
|
||||||
|
{
|
||||||
|
y=(double)y/eys;
|
||||||
|
x=(double)x/exs;
|
||||||
|
if(eoptions&EO_CLIPSIDES)
|
||||||
|
x+=8;
|
||||||
|
y+=srendline;
|
||||||
|
return(x|(y<<16));
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uint32 PtoV(uint16 x, uint16 y);
|
|
@ -0,0 +1,429 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "sdl-video.h"
|
||||||
|
#ifdef NETWORK
|
||||||
|
#include "unix-netplay.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DSETTINGS Settings;
|
||||||
|
CFGSTRUCT DriverConfig[]={
|
||||||
|
#ifdef OPENGL
|
||||||
|
AC(_stretchx),
|
||||||
|
AC(_stretchy),
|
||||||
|
AC(_opengl),
|
||||||
|
AC(_openglip),
|
||||||
|
#endif
|
||||||
|
AC(Settings.special),
|
||||||
|
AC(Settings.specialfs),
|
||||||
|
AC(_doublebuf),
|
||||||
|
AC(_xscale),
|
||||||
|
AC(_yscale),
|
||||||
|
AC(_xscalefs),
|
||||||
|
AC(_yscalefs),
|
||||||
|
AC(_bpp),
|
||||||
|
AC(_efx),
|
||||||
|
AC(_efxfs),
|
||||||
|
AC(_fullscreen),
|
||||||
|
AC(_xres),
|
||||||
|
AC(_yres),
|
||||||
|
#ifdef NETWORK
|
||||||
|
ACS(netplaynick),
|
||||||
|
AC(netlocalplayers),
|
||||||
|
AC(tport),
|
||||||
|
ACS(netpassword),
|
||||||
|
ACS(netgamekey),
|
||||||
|
#endif
|
||||||
|
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(Real numbers >0 with OpenGL, otherwise integers >0).\n\
|
||||||
|
-yscale(fs) x Multiply height by x(Real numbers >0 with OpenGL, otherwise integers >0).\n\
|
||||||
|
-bpp(fs) x Bits per pixel for SDL surface(and video mode in fs). 8, 16, 32.\n\
|
||||||
|
-opengl x Enable OpenGL support if x is 1.\n\
|
||||||
|
-openglip x Enable OpenGL linear interpolation if x is 1.\n\
|
||||||
|
-doublebuf x \n\
|
||||||
|
-special(fs) x Specify special scaling filter.\n\
|
||||||
|
-stretch(x/y) x Stretch to fill surface on x or y axis(fullscreen, only with OpenGL).\n\
|
||||||
|
-efx(fs) x Enable special effects. Logically OR the following together:\n\
|
||||||
|
1 = scanlines(for yscale>=2).\n\
|
||||||
|
2 = TV blur(for bpp of 16 or 32).\n\
|
||||||
|
-fs x Select full screen mode if x is non zero.\n\
|
||||||
|
-connect s Connect to server 's' for TCP/IP network play.\n\
|
||||||
|
-netnick s Set the nickname to use in network play.\n\
|
||||||
|
-netgamekey s Use key 's' to create a unique session for the game loaded.\n\
|
||||||
|
-netpassword s Password to use for connecting to the server.\n\
|
||||||
|
-netlocalplayers x Set the number of local players.\n\
|
||||||
|
-netport x Use TCP/IP port x for network play.";
|
||||||
|
|
||||||
|
ARGPSTRUCT DriverArgs[]={
|
||||||
|
#ifdef OPENGL
|
||||||
|
{"-opengl",0,&_opengl,0},
|
||||||
|
{"-openglip",0,&_openglip,0},
|
||||||
|
{"-stretchx",0,&_stretchx,0},
|
||||||
|
{"-stretchy",0,&_stretchy,0},
|
||||||
|
#endif
|
||||||
|
{"-special",0,&Settings.special,0},
|
||||||
|
{"-specialfs",0,&Settings.specialfs,0},
|
||||||
|
{"-doublebuf",0,&_doublebuf,0},
|
||||||
|
{"-bpp",0,&_bpp,0},
|
||||||
|
{"-xscale",0,&_xscale,2},
|
||||||
|
{"-yscale",0,&_yscale,2},
|
||||||
|
{"-efx",0,&_efx,0},
|
||||||
|
{"-xscalefs",0,&_xscalefs,2},
|
||||||
|
{"-yscalefs",0,&_yscalefs,2},
|
||||||
|
{"-efxfs",0,&_efxfs,0},
|
||||||
|
{"-xres",0,&_xres,0},
|
||||||
|
{"-yres",0,&_yres,0},
|
||||||
|
{"-fs",0,&_fullscreen,0},
|
||||||
|
//{"-fshack",0,&_fshack,0x4001},
|
||||||
|
#ifdef NETWORK
|
||||||
|
{"-connect",0,&netplayhost,0x4001},
|
||||||
|
{"-netport",0,&tport,0},
|
||||||
|
{"-netlocalplayers",0,&netlocalplayers,0},
|
||||||
|
{"-netnick",0,&netplaynick,0x4001},
|
||||||
|
{"-netpassword",0,&netpassword,0x4001},
|
||||||
|
#endif
|
||||||
|
{0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void SetDefaults(void)
|
||||||
|
{
|
||||||
|
Settings.special=Settings.specialfs=0;
|
||||||
|
_bpp=8;
|
||||||
|
_xres=640;
|
||||||
|
_yres=480;
|
||||||
|
_fullscreen=0;
|
||||||
|
_xscale=2.50;
|
||||||
|
_yscale=2;
|
||||||
|
_xscalefs=_yscalefs=2;
|
||||||
|
_efx=_efxfs=0;
|
||||||
|
//_fshack=_fshacksave=0;
|
||||||
|
#ifdef OPENGL
|
||||||
|
_opengl=1;
|
||||||
|
_stretchx=1;
|
||||||
|
_stretchy=0;
|
||||||
|
_openglip=1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoDriverArgs(void)
|
||||||
|
{
|
||||||
|
#ifdef BROKEN
|
||||||
|
if(_fshack)
|
||||||
|
{
|
||||||
|
if(_fshack[0]=='0')
|
||||||
|
if(_fshack[1]==0)
|
||||||
|
{
|
||||||
|
free(_fshack);
|
||||||
|
_fshack=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitMouse(void)
|
||||||
|
{
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillMouse(void){}
|
||||||
|
|
||||||
|
void GetMouseData(uint32 *d)
|
||||||
|
{
|
||||||
|
if(FCEUI_IsMovieActive()<0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int x,y;
|
||||||
|
uint32 t;
|
||||||
|
|
||||||
|
t=SDL_GetMouseState(&x,&y);
|
||||||
|
#ifdef EXTGUI
|
||||||
|
GUI_GetMouseState(&t,&x,&y);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UpdatePhysicalInput(void)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
|
||||||
|
while(SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
//case SDL_SYSWMEVENT: puts("Nifty keen");break;
|
||||||
|
//case SDL_VIDEORESIZE: puts("Okie dokie");break;
|
||||||
|
case SDL_QUIT: CloseGame();puts("Quit");break;
|
||||||
|
}
|
||||||
|
//printf("Event: %d\n",event.type);
|
||||||
|
//fflush(stdout);
|
||||||
|
}
|
||||||
|
//SDL_PumpEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 *KeyState=NULL;
|
||||||
|
char *GetKeyboard(void)
|
||||||
|
{
|
||||||
|
KeyState=SDL_GetKeyState(0);
|
||||||
|
#ifdef EXTGUI
|
||||||
|
{ char *tmp=GUI_GetKeyboard(); if(tmp) KeyState=tmp; }
|
||||||
|
#endif
|
||||||
|
return((char *)KeyState);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
/* Stupid SDL */
|
||||||
|
#ifdef main
|
||||||
|
#undef main
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EXTGUI
|
||||||
|
uint8 *GetBaseDirectory(void)
|
||||||
|
{
|
||||||
|
uint8 *ol;
|
||||||
|
uint8 *ret;
|
||||||
|
|
||||||
|
ol=getenv("HOME");
|
||||||
|
|
||||||
|
if(ol)
|
||||||
|
{
|
||||||
|
ret=malloc(strlen(ol)+1+strlen("./fceultra"));
|
||||||
|
strcpy(ret,ol);
|
||||||
|
strcat(ret,"/.fceultra");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
char *sa;
|
||||||
|
|
||||||
|
ret=malloc(MAX_PATH+1);
|
||||||
|
GetModuleFileName(NULL,ret,MAX_PATH+1);
|
||||||
|
|
||||||
|
sa=strrchr(ret,'\\');
|
||||||
|
if(sa)
|
||||||
|
*sa = 0;
|
||||||
|
#else
|
||||||
|
ret=malloc(1);
|
||||||
|
ret[0]=0;
|
||||||
|
#endif
|
||||||
|
printf("%s\n",ret);
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENGL
|
||||||
|
int sdlhaveogl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int DTestButton(ButtConfig *bc)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for(x=0;x<bc->NumC;x++)
|
||||||
|
{
|
||||||
|
if(bc->ButtType[x]==BUTTC_KEYBOARD)
|
||||||
|
{
|
||||||
|
if(KeyState[bc->ButtonNum[x]])
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
else if(bc->ButtType[x]==BUTTC_JOYSTICK)
|
||||||
|
{
|
||||||
|
if(DTestButtonJoy(bc))
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bcpv,bcpj;
|
||||||
|
|
||||||
|
int ButtonConfigBegin(void)
|
||||||
|
{
|
||||||
|
SDL_Surface *screen;
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
bcpv=KillVideo();
|
||||||
|
bcpj=KillJoysticks();
|
||||||
|
|
||||||
|
if(!(SDL_WasInit(SDL_INIT_VIDEO)&SDL_INIT_VIDEO))
|
||||||
|
if(SDL_InitSubSystem(SDL_INIT_VIDEO)==-1)
|
||||||
|
{
|
||||||
|
FCEUD_Message(SDL_GetError());
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
screen = SDL_SetVideoMode(300, 1, 8, 0);
|
||||||
|
SDL_WM_SetCaption("Button Config",0);
|
||||||
|
InitJoysticks();
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ButtonConfigEnd(void)
|
||||||
|
{
|
||||||
|
extern FCEUGI *CurGame;
|
||||||
|
KillJoysticks();
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
if(bcpv) InitVideo(CurGame);
|
||||||
|
if(bcpj) InitJoysticks();
|
||||||
|
}
|
||||||
|
|
||||||
|
int DWaitButton(const uint8 *text, ButtConfig *bc, int wb)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
static int32 LastAx[64][64];
|
||||||
|
int x,y;
|
||||||
|
|
||||||
|
SDL_WM_SetCaption(text,0);
|
||||||
|
#ifndef EXTGUI
|
||||||
|
puts(text);
|
||||||
|
#endif
|
||||||
|
for(x=0;x<64;x++)
|
||||||
|
for(y=0;y<64;y++)
|
||||||
|
LastAx[x][y]=0x100000;
|
||||||
|
|
||||||
|
while(SDL_WaitEvent(&event))
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case SDL_KEYDOWN:bc->ButtType[wb]=BUTTC_KEYBOARD;
|
||||||
|
bc->DeviceNum[wb]=0;
|
||||||
|
bc->ButtonNum[wb]=event.key.keysym.sym;
|
||||||
|
return(1);
|
||||||
|
case SDL_JOYBUTTONDOWN:bc->ButtType[wb]=BUTTC_JOYSTICK;
|
||||||
|
bc->DeviceNum[wb]=event.jbutton.which;
|
||||||
|
bc->ButtonNum[wb]=event.jbutton.button;
|
||||||
|
return(1);
|
||||||
|
case SDL_JOYHATMOTION:if(event.jhat.value != SDL_HAT_CENTERED)
|
||||||
|
{
|
||||||
|
bc->ButtType[wb]=BUTTC_JOYSTICK;
|
||||||
|
bc->DeviceNum[wb]=event.jhat.which;
|
||||||
|
bc->ButtonNum[wb]=0x2000|((event.jhat.hat&0x1F)<<8)|event.jhat.value;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_JOYAXISMOTION:
|
||||||
|
if(LastAx[event.jaxis.which][event.jaxis.axis]==0x100000)
|
||||||
|
{
|
||||||
|
if(abs(event.jaxis.value)<1000)
|
||||||
|
LastAx[event.jaxis.which][event.jaxis.axis]=event.jaxis.value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(abs(LastAx[event.jaxis.which][event.jaxis.axis]-event.jaxis.value)>=8192)
|
||||||
|
{
|
||||||
|
bc->ButtType[wb]=BUTTC_JOYSTICK;
|
||||||
|
bc->DeviceNum[wb]=event.jaxis.which;
|
||||||
|
bc->ButtonNum[wb]=0x8000|(event.jaxis.axis)|((event.jaxis.value<0)?0x4000:0);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EXTGUI
|
||||||
|
int FCEUSDLmain(int argc, char *argv[])
|
||||||
|
#else
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
FCEUD_Message("\nStarting FCE Ultra "FCEU_VERSION"...\n");
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
/* Taken from win32 sdl_main.c */
|
||||||
|
SDL_SetModuleHandle(GetModuleHandle(NULL));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(SDL_Init(SDL_INIT_VIDEO)) /* SDL_INIT_VIDEO Needed for (joystick config) event processing? */
|
||||||
|
{
|
||||||
|
printf("Could not initialize SDL: %s.\n", SDL_GetError());
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OPENGL
|
||||||
|
#ifdef APPLEOPENGL
|
||||||
|
sdlhaveogl = 1; /* Stupid something... Hack. */
|
||||||
|
#else
|
||||||
|
if(!SDL_GL_LoadLibrary(0)) sdlhaveogl=1;
|
||||||
|
else sdlhaveogl=0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SetDefaults();
|
||||||
|
|
||||||
|
{
|
||||||
|
int ret=CLImain(argc,argv);
|
||||||
|
SDL_Quit();
|
||||||
|
return(ret?0:-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint64 FCEUD_GetTime(void)
|
||||||
|
{
|
||||||
|
return(SDL_GetTicks());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 FCEUD_GetTimeFreq(void)
|
||||||
|
{
|
||||||
|
return(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// dummy functions
|
||||||
|
|
||||||
|
#define DUMMY(f) void f(void) {FCEU_DispMessage("Not implemented.");}
|
||||||
|
DUMMY(FCEUD_HideMenuToggle)
|
||||||
|
DUMMY(FCEUD_TurboOn)
|
||||||
|
DUMMY(FCEUD_TurboOff)
|
||||||
|
DUMMY(FCEUD_SaveStateAs)
|
||||||
|
DUMMY(FCEUD_LoadStateFrom)
|
||||||
|
DUMMY(FCEUD_MovieRecordTo)
|
||||||
|
DUMMY(FCEUD_MovieReplayFrom)
|
||||||
|
DUMMY(FCEUD_ToggleStatusIcon)
|
||||||
|
DUMMY(FCEUD_AviRecordTo)
|
||||||
|
DUMMY(FCEUD_AviStop)
|
||||||
|
void FCEUI_AviVideoUpdate(const unsigned char* buffer) {FCEU_DispMessage("Not implemented.");}
|
||||||
|
int FCEUD_ShowStatusIcon(void) {FCEU_DispMessage("Not implemented."); return 0; }
|
||||||
|
int FCEUI_AviIsRecording(void) {return 0;}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include <SDL.h>
|
||||||
|
#include "main.h"
|
||||||
|
#include "dface.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
int DTestButtonJoy(ButtConfig *bc);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int xres;
|
||||||
|
int yres;
|
||||||
|
double xscale,yscale;
|
||||||
|
double xscalefs,yscalefs;
|
||||||
|
int efx,efxfs;
|
||||||
|
int bpp;
|
||||||
|
int fullscreen;
|
||||||
|
int doublebuf;
|
||||||
|
char *fshack;
|
||||||
|
char *fshacksave;
|
||||||
|
#ifdef OPENGL
|
||||||
|
int opengl;
|
||||||
|
int openglip;
|
||||||
|
int stretchx,stretchy;
|
||||||
|
#endif
|
||||||
|
int special,specialfs;
|
||||||
|
} DSETTINGS;
|
||||||
|
|
||||||
|
extern DSETTINGS Settings;
|
||||||
|
|
||||||
|
#define _doublebuf Settings.doublebuf
|
||||||
|
#define _bpp Settings.bpp
|
||||||
|
#define _xres Settings.xres
|
||||||
|
#define _yres Settings.yres
|
||||||
|
#define _fullscreen Settings.fullscreen
|
||||||
|
#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 _fshack Settings.fshack
|
||||||
|
#define _fshacksave Settings.fshacksave
|
||||||
|
|
||||||
|
#ifdef OPENGL
|
||||||
|
#define _opengl Settings.opengl
|
||||||
|
#define _openglip Settings.openglip
|
||||||
|
#define _stretchx Settings.stretchx
|
||||||
|
#define _stretchy Settings.stretchy
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include "main.h"
|
||||||
|
#include "throttle.h"
|
||||||
|
|
||||||
|
static uint64 tfreq;
|
||||||
|
static uint64 desiredfps;
|
||||||
|
|
||||||
|
void RefreshThrottleFPS(void)
|
||||||
|
{
|
||||||
|
desiredfps=FCEUI_GetDesiredFPS()>>8;
|
||||||
|
tfreq=1000000;
|
||||||
|
tfreq<<=16; /* Adjustment for fps returned from FCEUI_GetDesiredFPS(). */
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64 GetCurTime(void)
|
||||||
|
{
|
||||||
|
uint64 ret;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
gettimeofday(&tv,0);
|
||||||
|
ret=(uint64)tv.tv_sec*1000000;
|
||||||
|
ret+=tv.tv_usec;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeedThrottle(void)
|
||||||
|
{
|
||||||
|
static uint64 ttime,ltime=0;
|
||||||
|
|
||||||
|
waiter:
|
||||||
|
|
||||||
|
ttime=GetCurTime();
|
||||||
|
|
||||||
|
if( (ttime-ltime) < (tfreq/desiredfps) )
|
||||||
|
goto waiter;
|
||||||
|
if( (ttime-ltime) >= (tfreq*4/desiredfps))
|
||||||
|
ltime=ttime;
|
||||||
|
else
|
||||||
|
ltime+=tfreq/desiredfps;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
void RefreshThrottleFPS(void);
|
||||||
|
void SpeedThrottle(void);
|
|
@ -0,0 +1,292 @@
|
||||||
|
#ifdef NETWORK
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* 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 <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "main.h"
|
||||||
|
#include "dface.h"
|
||||||
|
#include "unix-netplay.h"
|
||||||
|
|
||||||
|
#include "../../md5.h"
|
||||||
|
|
||||||
|
#ifndef socklen_t
|
||||||
|
#define socklen_t int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SOL_TCP
|
||||||
|
#define SOL_TCP IPPROTO_TCP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
char *netplayhost=0;
|
||||||
|
char *netplaynick=0;
|
||||||
|
char *netgamekey = 0;
|
||||||
|
char *netpassword = 0;
|
||||||
|
int netlocalplayers = 1;
|
||||||
|
|
||||||
|
int Port=0xFCE;
|
||||||
|
int FCEUDnetplay=0;
|
||||||
|
|
||||||
|
int tport=0xFCE;
|
||||||
|
|
||||||
|
static int Socket=-1;
|
||||||
|
|
||||||
|
static void en32(uint8 *buf, uint32 morp)
|
||||||
|
{
|
||||||
|
buf[0]=morp;
|
||||||
|
buf[1]=morp>>8;
|
||||||
|
buf[2]=morp>>16;
|
||||||
|
buf[3]=morp>>24;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
static uint32 de32(uint8 *morp)
|
||||||
|
{
|
||||||
|
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
int FCEUD_NetworkConnect(void)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sockin; /* I want to play with fighting robots. */
|
||||||
|
struct hostent *phostentb;
|
||||||
|
unsigned long hadr;
|
||||||
|
int TSocket;
|
||||||
|
int netdivisor;
|
||||||
|
|
||||||
|
if(!netplayhost) return(0);
|
||||||
|
|
||||||
|
if( (TSocket=socket(AF_INET,SOCK_STREAM,0))==-1)
|
||||||
|
{
|
||||||
|
puts("Error creating stream socket.");
|
||||||
|
FCEUD_NetworkClose();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int tcpopt = 1;
|
||||||
|
#ifdef BEOS
|
||||||
|
if(setsockopt(TSocket, SOL_SOCKET, TCP_NODELAY, &tcpopt, sizeof(int)))
|
||||||
|
#else
|
||||||
|
if(setsockopt(TSocket, SOL_TCP, TCP_NODELAY, &tcpopt, sizeof(int)))
|
||||||
|
#endif
|
||||||
|
puts("Nodelay fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sockin,0,sizeof(sockin));
|
||||||
|
sockin.sin_family=AF_INET;
|
||||||
|
|
||||||
|
hadr=inet_addr(netplayhost);
|
||||||
|
|
||||||
|
if(hadr!=INADDR_NONE)
|
||||||
|
sockin.sin_addr.s_addr=hadr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
puts("*** Looking up host name...");
|
||||||
|
if(!(phostentb=gethostbyname((const char *)netplayhost)))
|
||||||
|
{
|
||||||
|
puts("Error getting host network information.");
|
||||||
|
close(TSocket);
|
||||||
|
FCEUD_NetworkClose();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
memcpy(&sockin.sin_addr,phostentb->h_addr,phostentb->h_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
sockin.sin_port=htons(tport);
|
||||||
|
puts("*** Connecting to remote host...");
|
||||||
|
if(connect(TSocket,(struct sockaddr *)&sockin,sizeof(sockin))==-1)
|
||||||
|
{
|
||||||
|
puts("Error connecting to remote host.");
|
||||||
|
close(TSocket);
|
||||||
|
FCEUD_NetworkClose();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
Socket=TSocket;
|
||||||
|
puts("*** Sending initialization data to server...");
|
||||||
|
{
|
||||||
|
uint8 *sendbuf;
|
||||||
|
uint8 buf[5];
|
||||||
|
uint32 sblen;
|
||||||
|
|
||||||
|
sblen = 4 + 16 + 16 + 64 + 1 + (netplaynick?strlen(netplaynick):0);
|
||||||
|
sendbuf = malloc(sblen);
|
||||||
|
memset(sendbuf, 0, sblen);
|
||||||
|
|
||||||
|
en32(sendbuf, sblen - 4);
|
||||||
|
|
||||||
|
if(netgamekey)
|
||||||
|
{
|
||||||
|
struct md5_context md5;
|
||||||
|
uint8 md5out[16];
|
||||||
|
|
||||||
|
md5_starts(&md5);
|
||||||
|
md5_update(&md5, CurGame->MD5, 16);
|
||||||
|
md5_update(&md5, netgamekey, strlen(netgamekey));
|
||||||
|
md5_finish(&md5, md5out);
|
||||||
|
memcpy(sendbuf + 4, md5out, 16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memcpy(sendbuf + 4, CurGame->MD5, 16);
|
||||||
|
|
||||||
|
if(netpassword)
|
||||||
|
{
|
||||||
|
struct md5_context md5;
|
||||||
|
uint8 md5out[16];
|
||||||
|
|
||||||
|
md5_starts(&md5);
|
||||||
|
md5_update(&md5, netpassword, strlen(netpassword));
|
||||||
|
md5_finish(&md5, md5out);
|
||||||
|
memcpy(sendbuf + 4 + 16, md5out, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(sendbuf + 4 + 16 + 16, 0, 64);
|
||||||
|
|
||||||
|
sendbuf[4 + 16 + 16 + 64] = netlocalplayers;
|
||||||
|
|
||||||
|
if(netplaynick)
|
||||||
|
memcpy(sendbuf + 4 + 16 + 16 + 64 + 1,netplaynick,strlen(netplaynick));
|
||||||
|
|
||||||
|
send(Socket, sendbuf, sblen, 0);
|
||||||
|
free(sendbuf);
|
||||||
|
|
||||||
|
recv(Socket, buf, 1, MSG_WAITALL);
|
||||||
|
netdivisor = buf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("*** Connection established.");
|
||||||
|
|
||||||
|
FCEUDnetplay = 1;
|
||||||
|
FCEUI_NetplayStart(netlocalplayers, netdivisor);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int FCEUD_SendData(void *data, uint32 len)
|
||||||
|
{
|
||||||
|
int check;
|
||||||
|
if(!ioctl(fileno(stdin),FIONREAD,&check))
|
||||||
|
if(check)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
char *f;
|
||||||
|
fgets(buf,1024,stdin);
|
||||||
|
if((f=strrchr(buf,'\n')))
|
||||||
|
*f=0;
|
||||||
|
FCEUI_NetplayText(buf);
|
||||||
|
}
|
||||||
|
send(Socket, data, len ,0);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FCEUD_RecvData(void *data, uint32 len)
|
||||||
|
{
|
||||||
|
NoWaiting&=~2;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
fd_set funfun;
|
||||||
|
struct timeval popeye;
|
||||||
|
|
||||||
|
popeye.tv_sec=0;
|
||||||
|
popeye.tv_usec=100000;
|
||||||
|
|
||||||
|
FD_ZERO(&funfun);
|
||||||
|
FD_SET(Socket,&funfun);
|
||||||
|
|
||||||
|
switch(select(Socket + 1,&funfun,0,0,&popeye))
|
||||||
|
{
|
||||||
|
case 0: continue;
|
||||||
|
case -1:return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(FD_ISSET(Socket,&funfun))
|
||||||
|
{
|
||||||
|
if(recv(Socket,data,len,MSG_WAITALL) == len)
|
||||||
|
{
|
||||||
|
//unsigned long beefie;
|
||||||
|
|
||||||
|
FD_ZERO(&funfun);
|
||||||
|
FD_SET(Socket, &funfun);
|
||||||
|
|
||||||
|
popeye.tv_sec = popeye.tv_usec = 0;
|
||||||
|
if(select(Socket + 1, &funfun, 0, 0, &popeye) == 1)
|
||||||
|
//if(!ioctl(Socket,FIONREAD,&beefie))
|
||||||
|
// if(beefie)
|
||||||
|
{
|
||||||
|
NoWaiting|=2;
|
||||||
|
//puts("Yaya");
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FCEUD_NetworkClose(void)
|
||||||
|
{
|
||||||
|
if(Socket>0)
|
||||||
|
{
|
||||||
|
#ifdef BEOS
|
||||||
|
closesocket(Socket);
|
||||||
|
#else
|
||||||
|
close(Socket);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Socket=-1;
|
||||||
|
|
||||||
|
if(FCEUDnetplay)
|
||||||
|
FCEUI_NetplayStop();
|
||||||
|
FCEUDnetplay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FCEUD_NetplayText(uint8 *text)
|
||||||
|
{
|
||||||
|
char *tot = malloc(strlen(text) + 1);
|
||||||
|
char *tmp;
|
||||||
|
strcpy(tot, text);
|
||||||
|
tmp = tot;
|
||||||
|
|
||||||
|
while(*tmp)
|
||||||
|
{
|
||||||
|
if(*tmp < 0x20) *tmp = ' ';
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
puts(tot);
|
||||||
|
free(tot);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifdef NETWORK
|
||||||
|
extern char *netplaynick;
|
||||||
|
extern char *netplayhost;
|
||||||
|
extern char *netpassword;
|
||||||
|
extern char *netgamekey;
|
||||||
|
extern int tport;
|
||||||
|
extern int netlocalplayers;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* FCE Ultra - NES/Famicom Emulator
|
||||||
|
*
|
||||||
|
* Copyright notice for this file:
|
||||||
|
* Copyright (C) 2002 Xodnizel
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ShowUsage(char *prog)
|
||||||
|
{
|
||||||
|
printf("\nUsage is as follows:\n%s <options> filename\n\n",prog);
|
||||||
|
puts("Options:");
|
||||||
|
puts(DriverUsage);
|
||||||
|
puts("-cpalette x Load a custom global palette from file x.\n\
|
||||||
|
-ntsccol x Emulate an NTSC's TV's colors.\n\
|
||||||
|
0 = Disabled.\n\
|
||||||
|
1 = Enabled.\n\
|
||||||
|
-pal x Emulate a PAL NES if x is 1.\n\
|
||||||
|
-sound x Sound.\n\
|
||||||
|
0 = Disabled.\n\
|
||||||
|
Otherwise, x = playback rate.\n\
|
||||||
|
-soundvol x Sound volume. x is an integral percentage value.\n\
|
||||||
|
-soundq x Sets sound quality.\n\
|
||||||
|
0 = Low quality.\n\
|
||||||
|
1 = High quality.\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\
|
||||||
|
-inputcfg s Configure virtual input device \"s\".\n\
|
||||||
|
-nofs x Disables Four-Score emulation if x is 1.\n\
|
||||||
|
-gg x Enable Game Genie emulation if x is 1.\n\
|
||||||
|
-no8lim x Disables the 8 sprites per scanline limitation.\n\
|
||||||
|
0 = Limitation enabled.\n\
|
||||||
|
1 = Limitation disabled.\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.");
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue