reorganize and cleanup a bunch of input code. still in preparation for more general support of all input devices in movies.

This commit is contained in:
zeromus 2008-06-07 08:18:04 +00:00
parent 8e546b1bed
commit 3ea76ba08d
11 changed files with 447 additions and 384 deletions

View File

@ -68,33 +68,42 @@ void FCEUI_NTSCINC(void);
void FCEUI_GetNTSCTH(int *tint, int *hue);
void FCEUI_SetNTSCTH(int n, int tint, int hue);
void FCEUI_SetInput(int port, int type, void *ptr, int attrib);
void FCEUI_SetInputFC(int type, void *ptr, int attrib);
void FCEUI_DisableFourScore(int s);
//input device types for the standard joystick port
enum ESI
{
SI_NONE = 0,
SI_GAMEPAD = 1,
SI_ZAPPER = 2,
SI_POWERPADA = 3,
SI_POWERPADB = 4,
SI_ARKANOID = 5,
SI_MOUSE = 6 //mbg merge 7/17/06 added
};
//input device types for the expansion port
enum ESIFC
{
SIFC_NONE = 0,
SIFC_ARKANOID = 1,
SIFC_SHADOW = 2,
SIFC_4PLAYER = 3,
SIFC_FKB = 4,
SIFC_SUBORKB = 5,
SIFC_HYPERSHOT = 6,
SIFC_MAHJONG = 7,
SIFC_QUIZKING = 8,
SIFC_FTRAINERA = 9,
SIFC_FTRAINERB = 10,
SIFC_OEKAKIDS = 11,
SIFC_BWORLD = 12,
SIFC_TOPRIDER = 13,
};
void FCEUI_SetInput(int port, ESI type, void *ptr, int attrib);
void FCEUI_SetInputFC(ESIFC type, void *ptr, int attrib);
void FCEUI_DisableFourScore(bool disabled);
void FCEUI_UseInputPreset(int preset);
#define SI_NONE 0
#define SI_GAMEPAD 1
#define SI_ZAPPER 2
#define SI_POWERPADA 3
#define SI_POWERPADB 4
#define SI_ARKANOID 5
#define SI_MOUSE 6 //mbg merge 7/17/06 added
#define SIFC_NONE 0
#define SIFC_ARKANOID 1
#define SIFC_SHADOW 2
#define SIFC_4PLAYER 3
#define SIFC_FKB 4
#define SIFC_SUBORKB 5
#define SIFC_HYPERSHOT 6
#define SIFC_MAHJONG 7
#define SIFC_QUIZKING 8
#define SIFC_FTRAINERA 9
#define SIFC_FTRAINERB 10
#define SIFC_OEKAKIDS 11
#define SIFC_BWORLD 12
#define SIFC_TOPRIDER 13
#define SIS_NONE 0
#define SIS_DATACH 1

View File

@ -1,5 +1,5 @@
extern char* MovieToLoad;
extern char* StateToLoad;
extern int replayReadOnlySetting;
extern bool replayReadOnlySetting;
extern int replayStopFrameSetting;
char *ParseArgies(int argc, char *argv[]);

View File

@ -38,9 +38,8 @@
LPDIRECTINPUT7 lpDI=0;
/* UsrInputType[] is user-specified. InputType[] is current
(game loading can override user settings)
*/
//UsrInputType[] is user-specified. InputType[] is current
// (game/savestate/movie loading can override user settings)
int UsrInputType[3]={SI_GAMEPAD,SI_GAMEPAD,SIFC_NONE};
int InputType[3]={0,0,0};
@ -50,17 +49,15 @@ int gametype=0;
int InitDInput(void)
{
HRESULT ddrval;
HRESULT ddrval;
//mbg merge 7/17/06 changed:
//ddrval=DirectInputCreateEx(fceu_hInstance,DIRECTINPUT_VERSION,&IID_IDirectInput7,(LPVOID *)&lpDI,0);
ddrval=DirectInputCreateEx(fceu_hInstance,DIRECTINPUT_VERSION,IID_IDirectInput7,(LPVOID *)&lpDI,0);
if(ddrval!=DI_OK)
{
FCEUD_PrintError("DirectInput: Error creating DirectInput object.");
return 0;
}
return 1;
ddrval=DirectInputCreateEx(fceu_hInstance,DIRECTINPUT_VERSION,IID_IDirectInput7,(LPVOID *)&lpDI,0);
if(ddrval!=DI_OK)
{
FCEUD_PrintError("DirectInput: Error creating DirectInput object.");
return 0;
}
return 1;
}
static void PresetExport(int preset);
static void PresetImport(int preset);
@ -69,45 +66,45 @@ static uint32 MouseData[3];
static int screenmode=0;
void InputScreenChanged(int fs)
{
int x;
if(GameInfo)
{
for(x=0;x<2;x++)
if(InputType[x]==SI_ZAPPER)
FCEUI_SetInput(x,SI_ZAPPER,MouseData,fs);
if(InputType[2]==SIFC_SHADOW)
FCEUI_SetInputFC(SIFC_SHADOW,MouseData,fs);
}
screenmode=fs;
int x;
if(GameInfo)
{
for(x=0;x<2;x++)
if(InputType[x]==SI_ZAPPER)
FCEUI_SetInput(x,SI_ZAPPER,MouseData,fs);
if(InputType[2]==SIFC_SHADOW)
FCEUI_SetInputFC(SIFC_SHADOW,MouseData,fs);
}
screenmode=fs;
}
/* Necessary for proper GUI functioning(configuring when a game isn't loaded). */
//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];
int x;
for(x=0;x<3;x++) InputType[x]=UsrInputType[x];
}
void ParseGIInput(FCEUGI *gi)
{
InputType[0]=UsrInputType[0];
InputType[1]=UsrInputType[1];
InputType[2]=UsrInputType[2];
if(gi)
{
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;
gametype=gi->type;
InputType[0]=UsrInputType[0];
InputType[1]=UsrInputType[1];
InputType[2]=UsrInputType[2];
InitOtherInput();
}
else cspec=gametype=0;
if(gi)
{
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;
gametype=gi->type;
InitOtherInput();
}
else cspec=gametype=0;
}
@ -407,7 +404,7 @@ void InitOtherInput(void)
attrib=screenmode;
break;
}
FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
FCEUI_SetInput(x,(ESI)InputType[x],InputDPtr,attrib);
}
attrib=0;
@ -428,8 +425,8 @@ void InitOtherInput(void)
case SIFC_FTRAINERB:InputDPtr=&FTrainerData;break;
}
FCEUI_SetInputFC(InputType[2],InputDPtr,attrib);
FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
FCEUI_SetInputFC((ESIFC)InputType[2],InputDPtr,attrib);
FCEUI_DisableFourScore((eoptions&EO_NOFOURSCORE)!=0);
}
ButtConfig fkbmap[0x48]=

View File

@ -69,4 +69,4 @@ extern int FCEUD_CommandMapping[EMUCMD_MAX];
#endif
#endif
#endif

View File

@ -684,7 +684,7 @@ int main(int argc,char *argv[])
if(GameInfo && MovieToLoad)
{
FCEUI_LoadMovie(MovieToLoad, replayReadOnlySetting, replayStopFrameSetting);
FCEUI_LoadMovie(MovieToLoad, replayReadOnlySetting!=0, replayStopFrameSetting!=0);
free(MovieToLoad);
MovieToLoad = NULL;
}

View File

@ -9,7 +9,7 @@ bool autoInfo1003 = true; //This is a hacky variable that checks when dialog 100
extern FCEUGI *GameInfo;
//retains the state of the readonly checkbox and stopframe value
int replayReadOnlySetting;
bool replayReadOnlySetting;
int replayStopFrameSetting = 0;
void RefreshThrottleFPS();
@ -104,7 +104,7 @@ void UpdateReplayDialog(HWND hwndDlg)
// remember the previous setting for the read-only checkbox
if(IsWindowEnabled(GetDlgItem(hwndDlg, IDC_CHECK_READONLY)))
replayReadOnlySetting = (SendDlgItemMessage(hwndDlg, IDC_CHECK_READONLY, BM_GETCHECK, 0, 0) == BST_CHECKED) ? 1 : 0;
replayReadOnlySetting = (SendDlgItemMessage(hwndDlg, IDC_CHECK_READONLY, BM_GETCHECK, 0, 0) == BST_CHECKED);
if(fn)
{
@ -475,7 +475,7 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
// TODO: warn the user when they open a movie made with a different ROM
char* fn=GetReplayPath(hwndDlg);
//char TempArray[16]; //mbg merge 7/17/06 removed
replayReadOnlySetting = (SendDlgItemMessage(hwndDlg, IDC_CHECK_READONLY, BM_GETCHECK, 0, 0) == BST_CHECKED) ? 1 : 0;
replayReadOnlySetting = (SendDlgItemMessage(hwndDlg, IDC_CHECK_READONLY, BM_GETCHECK, 0, 0) == BST_CHECKED);
char offset1Str[32]={0};

View File

@ -1,23 +1,23 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 1998 BERO
* 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
*/
*
* Copyright notice for this file:
* Copyright (C) 1998 BERO
* 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>
#include <string.h>
@ -31,6 +31,7 @@
#include "movie.h"
#include "state.h"
#include "input/zapper.h"
//#include "input/basic.h"
#include "input.h"
#include "vsuni.h"
@ -39,9 +40,11 @@
// qfox: For UpdateExternalButton(), called when the
// botmode state changes, to update a label in gui.
#ifdef WIN32
#include "drivers/win/basicbot.h"
#include "drivers/win/basicbot.h"
#endif // WIN32
//it is easier to declare these input drivers extern here than include a bunch of files
//-------------
extern INPUTC *FCEU_InitZapper(int w);
extern INPUTC *FCEU_InitPowerpadA(int w);
extern INPUTC *FCEU_InitPowerpadB(int w);
@ -59,6 +62,7 @@ extern INPUTCFC *FCEU_InitFamilyTrainerB(void);
extern INPUTCFC *FCEU_InitOekaKids(void);
extern INPUTCFC *FCEU_InitTopRider(void);
extern INPUTCFC *FCEU_InitBarcodeWorld(void);
//---------------
static uint8 joy_readbit[2];
static uint8 joy[4]={0,0,0,0};
@ -69,78 +73,42 @@ static int BotMode = 0;
static uint32 BotPointer = 0; //mbg merge 7/18/06 changed to uint32
#endif
/* This function is a quick hack to get the NSF player to use emulated gamepad
input.
*/
//This function is a quick hack to get the NSF player to use emulated gamepad input.
uint8 FCEU_GetJoyJoy(void)
{
return(joy[0]|joy[1]|joy[2]|joy[3]);
return(joy[0]|joy[1]|joy[2]|joy[3]);
}
extern uint8 coinon;
static int FSDisable=0; /* Set to 1 if NES-style four-player adapter is disabled. */
static int JPAttrib[2]={0,0};
static int JPType[2]={0,0};
static void *InputDataPtr[2];
static bool FSDisable=false; // Set to true if NES-style four-player adapter is disabled.
static int JPAttribFC=0;
static int JPTypeFC=0;
static void *InputDataPtrFC;
void (*InputScanlineHook)(uint8 *bg, uint8 *spr, uint32 linets, int final);
static INPUTC DummyJPort={0,0,0,0,0};
static INPUTC *JPorts[2]={&DummyJPort,&DummyJPort};
static INPUTCFC *FCExp=0;
static uint8 ReadGPVS(int w)
static struct JOYPORT
{
uint8 ret=0;
int attrib;
ESI type;
void* ptr;
INPUTC* driver;
} joyports[2];
if(joy_readbit[w]>=8)
ret=1;
else
{
ret = ((joy[w]>>(joy_readbit[w]))&1);
if(!fceuindbg)
joy_readbit[w]++;
}
return ret;
}
static uint8 ReadGP(int w)
static struct FCPORT
{
uint8 ret;
int attrib;
ESIFC type;
void* ptr;
INPUTCFC* driver;
} portFC;
if(joy_readbit[w]>=8)
ret = ((joy[2+w]>>(joy_readbit[w]&7))&1);
else
ret = ((joy[w]>>(joy_readbit[w]))&1);
if(joy_readbit[w]>=16) ret=0;
if(FSDisable)
{
if(joy_readbit[w]>=8) ret|=1;
}
else
{
if(joy_readbit[w]==19-w) ret|=1;
}
if(!fceuindbg)
joy_readbit[w]++;
return ret;
}
static DECLFR(JPRead)
{
uint8 ret=0;
if(JPorts[A&1]->Read)
ret|=JPorts[A&1]->Read(A&1);
ret|=joyports[A&1].driver->Read(A&1);
if(FCExp)
if(FCExp->Read)
ret=FCExp->Read(A&1,ret);
if(portFC.driver)
ret = portFC.driver->Read(A&1,ret);
ret|=X.DB&0xC0;
return(ret);
@ -148,31 +116,29 @@ static DECLFR(JPRead)
static DECLFW(B4016)
{
if(FCExp)
if(FCExp->Write)
FCExp->Write(V&7);
if(portFC.driver)
portFC.driver->Write(V&7);
if(JPorts[0]->Write)
JPorts[0]->Write(V&1);
if(JPorts[1]->Write)
JPorts[1]->Write(V&1);
for(int i=0;i<2;i++)
joyports[i].driver->Write(V&1);
if((LastStrobe&1) && (!(V&1)))
{
/* This strobe code is just for convenience. If it were
with the code in input / *.c, it would more accurately represent
what's really going on. But who wants accuracy? ;)
Seriously, though, this shouldn't be a problem.
*/
if(JPorts[0]->Strobe)
JPorts[0]->Strobe(0);
if(JPorts[1]->Strobe)
JPorts[1]->Strobe(1);
if(FCExp)
if(FCExp->Strobe)
FCExp->Strobe();
}
LastStrobe=V&0x1;
if((LastStrobe&1) && (!(V&1)))
{
//old comment:
//This strobe code is just for convenience. If it were
//with the code in input / *.c, it would more accurately represent
//what's really going on. But who wants accuracy? ;)
//Seriously, though, this shouldn't be a problem.
//new comment:
//mbg 6/7/08 - I guess he means that the input drivers could track the strobing themselves
//I dont see why it is unreasonable here.
for(int i=0;i<2;i++)
joyports[i].driver->Strobe(0);
if(portFC.driver)
portFC.driver->Strobe();
}
LastStrobe=V&0x1;
}
static void StrobeGP(int w)
@ -180,6 +146,77 @@ static void StrobeGP(int w)
joy_readbit[w]=0;
}
//a main joystick port driver representing the case where nothing is plugged in
static INPUTC DummyJPort={0,0,0,0,0};
//and an expansion port driver for the same ting
static INPUTCFC DummyPortFC={0,0,0,0,0};
//--------4 player driver for expansion port--------
static uint8 F4ReadBit[2];
static void StrobeFami4(void)
{
F4ReadBit[0]=F4ReadBit[1]=0;
}
static uint8 ReadFami4(int w, uint8 ret)
{
ret&=1;
ret |= ((joy[2+w]>>(F4ReadBit[w]))&1)<<1;
if(F4ReadBit[w]>=8) ret|=2;
else F4ReadBit[w]++;
return(ret);
}
static INPUTCFC FAMI4C={ReadFami4,0,StrobeFami4,0,0,0};
//------------------
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
static uint8 ReadGPVS(int w)
{
uint8 ret=0;
if(joy_readbit[w]>=8)
ret=1;
else
{
ret = ((joy[w]>>(joy_readbit[w]))&1);
if(!fceuindbg)
joy_readbit[w]++;
}
return ret;
}
//basic joystick port driver
static uint8 ReadGP(int w)
{
uint8 ret;
if(joy_readbit[w]>=8)
ret = ((joy[2+w]>>(joy_readbit[w]&7))&1);
else
ret = ((joy[w]>>(joy_readbit[w]))&1);
if(joy_readbit[w]>=16) ret=0;
if(FSDisable)
{
if(joy_readbit[w]>=8) ret|=1;
}
else
{
if(joy_readbit[w]==19-w) ret|=1;
}
if(!fceuindbg)
joy_readbit[w]++;
return ret;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^6
static INPUTC GPC={ReadGP,0,StrobeGP,0,0,0};
static INPUTC GPCVS={ReadGPVS,0,StrobeGP,0,0,0};
@ -191,22 +228,18 @@ int FCEU_BotMode()
void FCEU_SetBotMode(int x)
{
BotMode = x;
#ifdef WIN32
// qfox: update gui in basicbot
UpdateExternalButton();
#endif // WIN32
#ifdef WIN32
// qfox: update gui in basicbot
UpdateExternalButton();
#endif // WIN32
}
void FCEU_DrawInput(uint8 *buf)
{
int x;
for(x=0;x<2;x++)
if(JPorts[x]->Draw)
JPorts[x]->Draw(x,buf,JPAttrib[x]);
if(FCExp)
if(FCExp->Draw)
FCExp->Draw(buf,JPAttribFC);
for(int pad=0;pad<2;pad++)
joyports[pad].driver->Draw(pad,buf,joyports[pad].attrib);
if(portFC.driver)
portFC.driver->Draw(buf,portFC.attrib);
}
void FCEU_UpdateBot()
@ -252,33 +285,28 @@ void FCEU_UpdateInput(void)
{
if(!FCEUMOV_Mode(MOVIEMODE_PLAY) && !BotMode)
{
int x;
for(x=0;x<2;x++)
for(int port=0;port<2;port++)
{
switch(JPType[x])
switch(joyports[port].type)
{
case SI_GAMEPAD:
if(!x)
if(port==0)
{
joy[0]=*(uint32 *)InputDataPtr[0];
joy[2]=*(uint32 *)InputDataPtr[0] >> 16;
joy[0]=*(uint32 *)joyports[0].ptr;
joy[2]=*(uint32 *)joyports[0].ptr >> 16;
}
else
{
joy[1]=*(uint32 *)InputDataPtr[1] >>8;
joy[3]=*(uint32 *)InputDataPtr[1] >>24;
joy[1]=*(uint32 *)joyports[1].ptr >>8;
joy[3]=*(uint32 *)joyports[1].ptr >>24;
}
break;
default:
if(JPorts[x]->Update)
JPorts[x]->Update(x,InputDataPtr[x],JPAttrib[x]);
joyports[port].driver->Update(port,joyports[port].ptr,joyports[port].attrib);
break;
}
}
if(FCExp)
if(FCExp->Update)
FCExp->Update(InputDataPtrFC,JPAttribFC);
portFC.driver->Update(portFC.ptr,portFC.attrib);
}
if(GameInfo->type==GIT_VSUNI)
@ -295,157 +323,168 @@ void FCEU_UpdateInput(void)
static DECLFR(VSUNIRead0)
{
uint8 ret=0;
uint8 ret=0;
if(JPorts[0]->Read)
ret|=(JPorts[0]->Read(0))&1;
ret|=(joyports[0].driver->Read(0))&1;
ret|=(vsdip&3)<<3;
if(coinon)
ret|=0x4;
return ret;
ret|=(vsdip&3)<<3;
if(coinon)
ret|=0x4;
return ret;
}
static DECLFR(VSUNIRead1)
{
uint8 ret=0;
uint8 ret=0;
if(JPorts[1]->Read)
ret|=(JPorts[1]->Read(1))&1;
ret|=vsdip&0xFC;
return ret;
ret|=(joyports[1].driver->Read(1))&1;
ret|=vsdip&0xFC;
return ret;
}
static void SLHLHook(uint8 *bg, uint8 *spr, uint32 linets, int final)
{
int x;
for(x=0;x<2;x++)
if(JPorts[x]->SLHook)
JPorts[x]->SLHook(x,bg,spr,linets,final);
if(FCExp)
if(FCExp->SLHook)
FCExp->SLHook(bg,spr,linets,final);
//calls from the ppu;
//calls the SLHook for any driver that needs it
void InputScanlineHook(uint8 *bg, uint8 *spr, uint32 linets, int final)
{
for(int port=0;port<2;port++)
joyports[port].driver->SLHook(port,bg,spr,linets,final);
portFC.driver->SLHook(bg,spr,linets,final);
}
static void CheckSLHook(void)
//binds JPorts[pad] to the driver specified in JPType[pad]
static void SetInputStuff(int port)
{
InputScanlineHook=0;
if(JPorts[0]->SLHook || JPorts[1]->SLHook)
InputScanlineHook=SLHLHook;
if(FCExp)
if(FCExp->SLHook)
InputScanlineHook=SLHLHook;
switch(joyports[port].type)
{
case SI_GAMEPAD:
if(GameInfo->type==GIT_VSUNI)
joyports[port].driver = &GPCVS;
else
joyports[port].driver= &GPC;
break;
case SI_ARKANOID:
joyports[port].driver=FCEU_InitArkanoid(port);
break;
case SI_ZAPPER:
joyports[port].driver=FCEU_InitZapper(port);
break;
case SI_POWERPADA:
joyports[port].driver=FCEU_InitPowerpadA(port);
break;
case SI_POWERPADB:
joyports[port].driver=FCEU_InitPowerpadB(port);
break;
case SI_NONE:
joyports[port].driver=&DummyJPort;
break;
}
}
static void SetInputStuff(int x)
static void SetInputStuffFC()
{
switch(JPType[x])
{
case SI_GAMEPAD:
if(GameInfo->type==GIT_VSUNI)
JPorts[x] = &GPCVS;
else
JPorts[x]=&GPC;
break;
case SI_ARKANOID:JPorts[x]=FCEU_InitArkanoid(x);break;
case SI_ZAPPER:JPorts[x]=FCEU_InitZapper(x);break;
case SI_POWERPADA:JPorts[x]=FCEU_InitPowerpadA(x);break;
case SI_POWERPADB:JPorts[x]=FCEU_InitPowerpadB(x);break;
case SI_NONE:JPorts[x]=&DummyJPort;break;
}
CheckSLHook();
switch(portFC.type)
{
case SIFC_NONE:
portFC.driver=&DummyPortFC;
break;
case SIFC_ARKANOID:
portFC.driver=FCEU_InitArkanoidFC();
break;
case SIFC_SHADOW:
portFC.driver=FCEU_InitSpaceShadow();
break;
case SIFC_OEKAKIDS:
portFC.driver=FCEU_InitOekaKids();
break;
case SIFC_4PLAYER:
portFC.driver=&FAMI4C;
memset(&F4ReadBit,0,sizeof(F4ReadBit));
break;
case SIFC_FKB:
portFC.driver=FCEU_InitFKB();
break;
case SIFC_SUBORKB:
portFC.driver=FCEU_InitSuborKB();
break;
case SIFC_HYPERSHOT:
portFC.driver=FCEU_InitHS();
break;
case SIFC_MAHJONG:
portFC.driver=FCEU_InitMahjong();
break;
case SIFC_QUIZKING:
portFC.driver=FCEU_InitQuizKing();
break;
case SIFC_FTRAINERA:
portFC.driver=FCEU_InitFamilyTrainerA();
break;
case SIFC_FTRAINERB:
portFC.driver=FCEU_InitFamilyTrainerB();
break;
case SIFC_BWORLD:
portFC.driver=FCEU_InitBarcodeWorld();
break;
case SIFC_TOPRIDER:
portFC.driver=FCEU_InitTopRider();
break;
}
}
static uint8 F4ReadBit[2];
static void StrobeFami4(void)
void FCEUI_SetInput(int port, ESI type, void *ptr, int attrib)
{
F4ReadBit[0]=F4ReadBit[1]=0;
joyports[port].attrib = attrib;
joyports[port].type = type;
joyports[port].ptr = ptr;
SetInputStuff(port);
}
static uint8 ReadFami4(int w, uint8 ret)
void FCEUI_SetInputFC(ESIFC type, void *ptr, int attrib)
{
ret&=1;
ret |= ((joy[2+w]>>(F4ReadBit[w]))&1)<<1;
if(F4ReadBit[w]>=8) ret|=2;
else F4ReadBit[w]++;
return(ret);
}
static INPUTCFC FAMI4C={ReadFami4,0,StrobeFami4,0,0,0};
static void SetInputStuffFC(void)
{
switch(JPTypeFC)
{
case SIFC_NONE:FCExp=0;break;
case SIFC_ARKANOID:FCExp=FCEU_InitArkanoidFC();break;
case SIFC_SHADOW:FCExp=FCEU_InitSpaceShadow();break;
case SIFC_OEKAKIDS:FCExp=FCEU_InitOekaKids();break;
case SIFC_4PLAYER:FCExp=&FAMI4C;memset(&F4ReadBit,0,sizeof(F4ReadBit));break;
case SIFC_FKB:FCExp=FCEU_InitFKB();break;
case SIFC_SUBORKB:FCExp=FCEU_InitSuborKB();break;
case SIFC_HYPERSHOT:FCExp=FCEU_InitHS();break;
case SIFC_MAHJONG:FCExp=FCEU_InitMahjong();break;
case SIFC_QUIZKING:FCExp=FCEU_InitQuizKing();break;
case SIFC_FTRAINERA:FCExp=FCEU_InitFamilyTrainerA();break;
case SIFC_FTRAINERB:FCExp=FCEU_InitFamilyTrainerB();break;
case SIFC_BWORLD:FCExp=FCEU_InitBarcodeWorld();break;
case SIFC_TOPRIDER:FCExp=FCEU_InitTopRider();break;
}
CheckSLHook();
}
void InitializeInput(void)
{
memset(joy_readbit,0,sizeof(joy_readbit));
memset(joy,0,sizeof(joy));
LastStrobe = 0;
if(GameInfo->type==GIT_VSUNI)
{
SetReadHandler(0x4016,0x4016,VSUNIRead0);
SetReadHandler(0x4017,0x4017,VSUNIRead1);
}
else
SetReadHandler(0x4016,0x4017,JPRead);
SetWriteHandler(0x4016,0x4016,B4016);
SetInputStuff(0);
SetInputStuff(1);
portFC.attrib = attrib;
portFC.type = type;
portFC.ptr = ptr;
SetInputStuffFC();
}
void FCEUI_SetInput(int port, int type, void *ptr, int attrib)
//initializes the input system to power-on state
void InitializeInput(void)
{
JPAttrib[port]=attrib;
JPType[port]=type;
InputDataPtr[port]=ptr;
SetInputStuff(port);
memset(joy_readbit,0,sizeof(joy_readbit));
memset(joy,0,sizeof(joy));
LastStrobe = 0;
if(GameInfo->type==GIT_VSUNI)
{
SetReadHandler(0x4016,0x4016,VSUNIRead0);
SetReadHandler(0x4017,0x4017,VSUNIRead1);
}
else
SetReadHandler(0x4016,0x4017,JPRead);
SetWriteHandler(0x4016,0x4016,B4016);
//force the port drivers to be setup
SetInputStuff(0);
SetInputStuff(1);
SetInputStuffFC();
}
void FCEUI_DisableFourScore(int s)
{
FSDisable=s;
}
void FCEUI_SetInputFC(int type, void *ptr, int attrib)
void FCEUI_DisableFourScore(bool disabled)
{
JPAttribFC=attrib;
JPTypeFC=type;
InputDataPtrFC=ptr;
SetInputStuffFC();
FSDisable = disabled;
}
SFORMAT FCEUCTRL_STATEINFO[]={
{ joy_readbit, 2, "JYRB"},
{ joy, 4, "JOYS"},
{ &LastStrobe, 1, "LSTS"},
{ 0 }
};
{ joy_readbit, 2, "JYRB"},
{ joy, 4, "JOYS"},
{ &LastStrobe, 1, "LSTS"},
{ 0 }
};
void FCEU_DoSimpleCommand(int cmd)
{
@ -471,59 +510,55 @@ void FCEU_DoSimpleCommand(int cmd)
void FCEU_QSimpleCommand(int cmd)
{
if(FCEUnetplay)
FCEUNET_SendCommand(cmd, 0);
else
{
FCEU_DoSimpleCommand(cmd);
if(FCEUMOV_Mode(MOVIEMODE_RECORD))
FCEUMOV_AddCommand(cmd);
}
if(FCEUnetplay)
FCEUNET_SendCommand(cmd, 0);
else
{
FCEU_DoSimpleCommand(cmd);
if(FCEUMOV_Mode(MOVIEMODE_RECORD))
FCEUMOV_AddCommand(cmd);
}
}
void FCEUI_FDSSelect(void)
{
FCEU_QSimpleCommand(FCEUNPCMD_FDSSELECT);
FCEU_QSimpleCommand(FCEUNPCMD_FDSSELECT);
}
//mbg merge 7/17/06 changed to void fn(void) to make it an EMUCMDFN
void FCEUI_FDSInsert(void)
{
FCEU_QSimpleCommand(FCEUNPCMD_FDSINSERT);
//return(1);
FCEU_QSimpleCommand(FCEUNPCMD_FDSINSERT);
//return(1);
}
/*
int FCEUI_FDSEject(void)
{
FCEU_QSimpleCommand(FCEUNPCMD_FDSEJECT);
return(1);
FCEU_QSimpleCommand(FCEUNPCMD_FDSEJECT);
return(1);
}
*/
void FCEUI_VSUniToggleDIP(int w)
{
FCEU_QSimpleCommand(FCEUNPCMD_VSUNIDIP0 + w);
FCEU_QSimpleCommand(FCEUNPCMD_VSUNIDIP0 + w);
}
void FCEUI_VSUniCoin(void)
{
FCEU_QSimpleCommand(FCEUNPCMD_VSUNICOIN);
FCEU_QSimpleCommand(FCEUNPCMD_VSUNICOIN);
}
/**
* Resets the NES
**/
//Resets the NES
void FCEUI_ResetNES(void)
{
FCEU_QSimpleCommand(FCEUNPCMD_RESET);
}
/**
* Powers off the NES
**/
//Powers off the NES
void FCEUI_PowerNES(void)
{
FCEU_QSimpleCommand(FCEUNPCMD_POWER);
FCEU_QSimpleCommand(FCEUNPCMD_POWER);
}
const char* FCEUI_CommandTypeNames[]=
@ -604,7 +639,7 @@ struct EMUCMDTABLE FCEUI_CommandTable[]=
{ EMUCMD_LOAD_STATE_SLOT_8, EMUCMDTYPE_STATE, CommandStateLoad, 0, 0, "Load State from Slot 8", },
{ EMUCMD_LOAD_STATE_SLOT_9, EMUCMDTYPE_STATE, CommandStateLoad, 0, 0, "Load State from Slot 9", },
/* { EMUCMD_MOVIE_SLOT_0, EMUCMDTYPE_MOVIE, CommandMovieSelectSlot, 0, 0, "Movie Slot 0", },
/* { EMUCMD_MOVIE_SLOT_0, EMUCMDTYPE_MOVIE, CommandMovieSelectSlot, 0, 0, "Movie Slot 0", },
{ EMUCMD_MOVIE_SLOT_1, EMUCMDTYPE_MOVIE, CommandMovieSelectSlot, 0, 0, "Movie Slot 1", },
{ EMUCMD_MOVIE_SLOT_2, EMUCMDTYPE_MOVIE, CommandMovieSelectSlot, 0, 0, "Movie Slot 2", },
{ EMUCMD_MOVIE_SLOT_3, EMUCMDTYPE_MOVIE, CommandMovieSelectSlot, 0, 0, "Movie Slot 3", },
@ -618,7 +653,7 @@ struct EMUCMDTABLE FCEUI_CommandTable[]=
{ EMUCMD_MOVIE_SLOT_PREV, EMUCMDTYPE_MOVIE, CommandMovieSelectSlot, 0, 0, "Previous Movie Slot", },
{ EMUCMD_MOVIE_RECORD, EMUCMDTYPE_MOVIE, CommandMovieRecord, 0, 0, "Record Movie", },*/
{ EMUCMD_MOVIE_RECORD_TO, EMUCMDTYPE_MOVIE, FCEUD_MovieRecordTo, 0, 0, "Record Movie To...", },
/* { EMUCMD_MOVIE_RECORD_SLOT_0, EMUCMDTYPE_MOVIE, CommandMovieRecord, 0, 0, "Record Movie to Slot 0", },
/* { EMUCMD_MOVIE_RECORD_SLOT_0, EMUCMDTYPE_MOVIE, CommandMovieRecord, 0, 0, "Record Movie to Slot 0", },
{ EMUCMD_MOVIE_RECORD_SLOT_1, EMUCMDTYPE_MOVIE, CommandMovieRecord, 0, 0, "Record Movie to Slot 1", },
{ EMUCMD_MOVIE_RECORD_SLOT_2, EMUCMDTYPE_MOVIE, CommandMovieRecord, 0, 0, "Record Movie to Slot 2", },
{ EMUCMD_MOVIE_RECORD_SLOT_3, EMUCMDTYPE_MOVIE, CommandMovieRecord, 0, 0, "Record Movie to Slot 3", },
@ -630,7 +665,7 @@ struct EMUCMDTABLE FCEUI_CommandTable[]=
{ EMUCMD_MOVIE_RECORD_SLOT_9, EMUCMDTYPE_MOVIE, CommandMovieRecord, 0, 0, "Record Movie to Slot 9", },
{ EMUCMD_MOVIE_REPLAY, EMUCMDTYPE_MOVIE, CommandMovieReplay, 0, 0, "Replay Movie", },*/
{ EMUCMD_MOVIE_REPLAY_FROM, EMUCMDTYPE_MOVIE, FCEUD_MovieReplayFrom, 0, 0, "Replay Movie From...", },
/* { EMUCMD_MOVIE_REPLAY_SLOT_0, EMUCMDTYPE_MOVIE, CommandMovieReplay, 0, 0, "Replay Movie from Slot 0", },
/* { EMUCMD_MOVIE_REPLAY_SLOT_0, EMUCMDTYPE_MOVIE, CommandMovieReplay, 0, 0, "Replay Movie from Slot 0", },
{ EMUCMD_MOVIE_REPLAY_SLOT_1, EMUCMDTYPE_MOVIE, CommandMovieReplay, 0, 0, "Replay Movie from Slot 1", },
{ EMUCMD_MOVIE_REPLAY_SLOT_2, EMUCMDTYPE_MOVIE, CommandMovieReplay, 0, 0, "Replay Movie from Slot 2", },
{ EMUCMD_MOVIE_REPLAY_SLOT_3, EMUCMDTYPE_MOVIE, CommandMovieReplay, 0, 0, "Replay Movie from Slot 3", },
@ -640,7 +675,7 @@ struct EMUCMDTABLE FCEUI_CommandTable[]=
{ EMUCMD_MOVIE_REPLAY_SLOT_7, EMUCMDTYPE_MOVIE, CommandMovieReplay, 0, 0, "Replay Movie from Slot 7", },
{ EMUCMD_MOVIE_REPLAY_SLOT_8, EMUCMDTYPE_MOVIE, CommandMovieReplay, 0, 0, "Replay Movie from Slot 8", },
{ EMUCMD_MOVIE_REPLAY_SLOT_9, EMUCMDTYPE_MOVIE, CommandMovieReplay, 0, 0, "Replay Movie from Slot 9", },
*/
*/
{ EMUCMD_MOVIE_PLAY_FROM_BEGINNING, EMUCMDTYPE_MOVIE, FCEUI_MoviePlayFromBeginning, 0, 0, "Play Movie From Beginning", },
{ EMUCMD_MOVIE_STOP, EMUCMDTYPE_MOVIE, FCEUI_StopMovie, 0, 0, "Stop Movie", },
{ EMUCMD_MOVIE_READONLY_TOGGLE, EMUCMDTYPE_MOVIE, FCEUI_MovieToggleReadOnly, 0, 0, "Toggle Read-Only", },
@ -730,7 +765,7 @@ static void CommandSelectSaveSlot(void)
static void CommandStateSave(void)
{
// FCEU_PrintError("execcmd=%d, EMUCMD_SAVE_STATE_SLOT_0=%d, EMUCMD_SAVE_STATE_SLOT_9=%d", execcmd,EMUCMD_SAVE_STATE_SLOT_0,EMUCMD_SAVE_STATE_SLOT_9);
// FCEU_PrintError("execcmd=%d, EMUCMD_SAVE_STATE_SLOT_0=%d, EMUCMD_SAVE_STATE_SLOT_9=%d", execcmd,EMUCMD_SAVE_STATE_SLOT_0,EMUCMD_SAVE_STATE_SLOT_9);
if(execcmd >= EMUCMD_SAVE_STATE_SLOT_0 && execcmd <= EMUCMD_SAVE_STATE_SLOT_9)
{
int oldslot=FCEUI_SelectState(execcmd-EMUCMD_SAVE_STATE_SLOT_0, 0);
@ -755,12 +790,12 @@ static void CommandStateLoad(void)
/*static void CommandMovieRecord(void)
{
FCEUI_SaveMovie(0, 0);
FCEUI_SaveMovie(0, 0);
}
static void CommandMovieReplay(void)
{
FCEUI_LoadMovie(0, 0, 0);
FCEUI_LoadMovie(0, 0, 0);
}*/
static void CommandSoundAdjust(void)

View File

@ -1,22 +1,42 @@
#ifndef _INPUT_H_
#define _INPUT_H_
typedef struct {
uint8 (*Read)(int w);
void (*Write)(uint8 v);
void (*Strobe)(int w);
void (*Update)(int w, void *data, int arg);
void (*SLHook)(int w, uint8 *bg, uint8 *spr, uint32 linets, int final);
void (*Draw)(int w, uint8 *buf, int arg);
//The interface for standard joystick port device drivers
typedef struct
{
//these methods call the function pointers (or not, if they are null)
uint8 Read(int w) { if(_Read) return _Read(w); else return 0; }
void Write(uint8 w) { if(_Write) _Write(w); }
void Strobe(int w) { if(_Strobe) _Strobe(w); }
void Update(int w, void *data, int arg) { if(_Update) _Update(w,data,arg); }
void SLHook(int w, uint8 *bg, uint8 *spr, uint32 linets, int final) { if(_SLHook) _SLHook(w,bg,spr,linets,final); }
void Draw(int w, uint8 *buf, int arg) { if(_Draw) _Draw(w,buf,arg); }
uint8 (*_Read)(int w);
void (*_Write)(uint8 v);
void (*_Strobe)(int w);
void (*_Update)(int w, void *data, int arg);
void (*_SLHook)(int w, uint8 *bg, uint8 *spr, uint32 linets, int final);
void (*_Draw)(int w, uint8 *buf, int arg);
} INPUTC;
typedef struct {
uint8 (*Read)(int w, uint8 ret);
void (*Write)(uint8 v);
void (*Strobe)(void);
void (*Update)(void *data, int arg);
void (*SLHook)(uint8 *bg, uint8 *spr, uint32 linets, int final);
void (*Draw)(uint8 *buf, int arg);
//The interface for the expansion port device drivers
typedef struct
{
//these methods call the function pointers (or not, if they are null)
uint8 Read(int w, uint8 ret) { if(_Read) return _Read(w,ret); else return ret; }
void Write(uint8 v) { if(_Write) _Write(v); }
void Strobe() { if(_Strobe) _Strobe(); }
void Update(void *data, int arg) { if(_Update) _Update(data,arg); }
void SLHook(uint8 *bg, uint8 *spr, uint32 linets, int final) { if(_SLHook) _SLHook(bg,spr,linets,final); }
void Draw(uint8 *buf, int arg) { if(_Draw) _Draw(buf,arg); }
uint8 (*_Read)(int w, uint8 ret);
void (*_Write)(uint8 v);
void (*_Strobe)();
void (*_Update)(void *data, int arg);
void (*_SLHook)(uint8 *bg, uint8 *spr, uint32 linets, int final);
void (*_Draw)(uint8 *buf, int arg);
} INPUTCFC;
void FCEU_DrawInput(uint8 *buf);
@ -26,7 +46,9 @@ void FCEU_SetBotMode(int x);
void InitializeInput(void);
void FCEU_UpdateBot(void);
extern void (*PStrobe[2])(void);
extern void (*InputScanlineHook)(uint8 *bg, uint8 *spr, uint32 linets, int final);
//called from PPU on scanline events.
extern void InputScanlineHook(uint8 *bg, uint8 *spr, uint32 linets, int final);
void FCEU_DoSimpleCommand(int cmd);

View File

@ -1,9 +1,9 @@
#include "../types.h"
#include "../input.h"
#include "../fceu.h"
#include "../ppu.h"
#include "../x6502.h"
#include "../palette.h"
#include "types.h"
#include "input.h"
#include "fceu.h"
#include "ppu.h"
#include "x6502.h"
#include "palette.h"
void FCEU_DrawCursor(uint8 *buf, int xc, int yc);
void FCEU_DrawGunSight(uint8 *buf, int xc, int yc);

View File

@ -383,17 +383,17 @@ static int tofix=0;
static void ResetRL(uint8 *target)
{
memset(target,0xFF,256);
if(InputScanlineHook)
InputScanlineHook(0,0,0,0);
Plinef=target;
Pline=target;
firsttile=0;
linestartts=timestamp*48+X.count;
tofix=0;
FCEUPPU_LineUpdate();
tofix=1;
memset(target,0xFF,256);
InputScanlineHook(0,0,0,0);
Plinef=target;
Pline=target;
firsttile=0;
linestartts=timestamp*48+X.count;
tofix=0;
FCEUPPU_LineUpdate();
tofix=1;
}
static uint8 sprlinebuf[256+8];
void FCEUPPU_LineUpdate(void)
@ -555,7 +555,7 @@ static void RefreshLine(int lastpixel)
tofix=0;
}
if(InputScanlineHook && (lastpixel-16)>=0)
if((lastpixel-16)>=0)
{
InputScanlineHook(Plinef,spork?sprlinebuf:0,linestartts,lasttile*8-16);
}
@ -694,7 +694,7 @@ static void RefreshLine(int lastpixel)
CheckSpriteHit(lastpixel); /* This only works right because
of a hack earlier in this function.
*/
if(InputScanlineHook && (lastpixel-16)>=0)
if((lastpixel-16)>=0)
{
InputScanlineHook(Plinef,spork?sprlinebuf:0,linestartts,lasttile*8-16);
}

View File

@ -129,7 +129,7 @@
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="../src/drivers/win/zlib;../src/drivers/win/directx"
AdditionalIncludeDirectories="../src/drivers/win/zlib;../src/drivers/win/directx;../src"
PreprocessorDefinitions="WIN32;NDEBUG;MSVC;_CRT_SECURE_NO_DEPRECATE;_WIN32_WINDOWS=0x0410;WINVER=0x0410;NETWORK;LSB_FIRST;_USE_32BIT_TIME_T;FCEUDEF_DEBUGGER;_USE_SHARED_MEMORY_;NOMINMAX"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
@ -1448,7 +1448,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="copy /y ..\src\drivers\win\help\fceux.chm $(OutDir)"
CommandLine="copy /y ..\src\drivers\win\help\fceux.chm $(OutDir)&#x0D;&#x0A;"
Outputs="$(OutDir)\fceux.chm"
/>
</FileConfiguration>