From ca472ee6aed57821e3a0f75eb34a5e120e8ad3f5 Mon Sep 17 00:00:00 2001 From: "Jason W. Thompson" Date: Sat, 18 Jul 2020 23:32:29 -0500 Subject: [PATCH] Add Real Zapper support Adds a two button controller that can be used to represent the states of a real Zapper. --- src/drivers/win/input.cpp | 47 ++++++++++++++++++++++++++++++++-- src/drivers/win/res.rc | 15 +++++++++++ src/git.h | 6 +++-- src/input.cpp | 4 +++ src/input/realzapper.cpp | 48 +++++++++++++++++++++++++++++++++++ vc/vc14_fceux.vcxproj | 1 + vc/vc14_fceux.vcxproj.filters | 3 +++ 7 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 src/input/realzapper.cpp diff --git a/src/drivers/win/input.cpp b/src/drivers/win/input.cpp index 3420e8b9..e56fe8cb 100644 --- a/src/drivers/win/input.cpp +++ b/src/drivers/win/input.cpp @@ -438,6 +438,35 @@ static uint32 UpdateVirtualBoyData(int w) return r; } +// Holds the button configurations for the "Real" Zapper. +// Two collections of two buttons. +// One for each controller port. +// The defaults shouldn't matter since this is intended to be configured by the user to match their custom hardware. +ButtConfig realzappersc[2][2] = { + { + MK(A), MK(B) + }, + { + MK(A), MK(B) + } +}; + +// buffer to hold the state of the zapper. +static uint32 realzapperbuf[2]; + +// Determines if the zapper trigger is pressed and/or if it's sensing light based on the button config and return +// the result as a two bit value. +static uint32 UpdateRealZapperData(int w) +{ + uint32 r = 0; + ButtConfig* realzappertsc = realzappersc[w]; + int x; + + for (x = 0; x < 2; x++) + if (DTestButton(&realzappertsc[x])) r |= 1 << x; + + return r; +} static uint8 fkbkeys[0x48]; static uint8 suborkbkeys[0x65]; @@ -488,7 +517,10 @@ void FCEUD_UpdateInput() case SI_VIRTUALBOY: virtualboybuf[x]=UpdateVirtualBoyData(x); break; - } + case SI_REAL_ZAPPER: + realzapperbuf[x] = UpdateRealZapperData(x); + break; + } switch(InputType[2]) { @@ -584,6 +616,9 @@ void InitInputPorts(bool fourscore) case SI_VIRTUALBOY: InputDPtr=&virtualboybuf[i]; break; + case SI_REAL_ZAPPER: + InputDPtr = &realzapperbuf[i]; + break; } FCEUI_SetInput(i,(ESI)InputType[i],InputDPtr,attrib); } @@ -835,6 +870,7 @@ CFGSTRUCT InputConfig[]={ AC(fkbmap), AC(suborkbmap), AC(virtualboysc), + AC(realzappersc), ENDCFGSTRUCT }; @@ -870,6 +906,10 @@ void InitInputStuff(void) for(x=0; x<2; x++) for(y=0; y<14; y++) JoyClearBC(&virtualboysc[x][y]); + + for (x = 0; x < 2; x++) + for (y = 0; y < 2; y++) + JoyClearBC(&realzappersc[x][y]); } static char *MakeButtString(ButtConfig *bc) @@ -1206,7 +1246,7 @@ const unsigned int NUMBER_OF_PORTS = 2; const unsigned int NUMBER_OF_NES_DEVICES = SI_COUNT + 1; const static unsigned int NUMBER_OF_FAMICOM_DEVICES = SIFC_COUNT + 1; //these are unfortunate lists. they match the ESI and ESIFC enums -static const int configurable_nes[NUMBER_OF_NES_DEVICES]= { 0, 1, 0, 1, 1, 0, 0, 1, 0, 1 }; +static const int configurable_nes[NUMBER_OF_NES_DEVICES]= { 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1 }; static const int configurable_fam[NUMBER_OF_FAMICOM_DEVICES]= { 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0 }; const unsigned int FAMICOM_POSITION = 2; @@ -1539,6 +1579,9 @@ INT_PTR CALLBACK InputConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP case SI_VIRTUALBOY: DoTBConfig(hwndDlg, text, "VIRTUALBOYDIALOG", virtualboysc[which], 14); break; + case SI_REAL_ZAPPER: + DoTBConfig(hwndDlg, text, "REALZAPPERDIALOG", realzappersc[which], 2); + break; } } diff --git a/src/drivers/win/res.rc b/src/drivers/win/res.rc index 3daca457..593057a3 100644 --- a/src/drivers/win/res.rc +++ b/src/drivers/win/res.rc @@ -1102,6 +1102,17 @@ BEGIN PUSHBUTTON "A", 313,162,19,32,12 END +REALZAPPERDIALOG DIALOGEX 4, 109, 129, 116 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Zapper Configuration" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN +DEFPUSHBUTTON "Close", BTN_CLOSE, 13, 94, 56, 14 +GROUPBOX "Zapper", 312, 8, 7, 118, 75, WS_GROUP +PUSHBUTTON "Trigger", 300, 15, 38, 30, 12 +PUSHBUTTON "Light Sensor", 301, 14, 19, 98, 12 +END + QUIZKINGDIALOG DIALOG 30, 123, 160, 74 STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "quiz king" @@ -2473,6 +2484,10 @@ BEGIN BEGIN END + "REALZAPPERDIALOG", DIALOG + BEGIN + END + "QUIZKINGDIALOG", DIALOG BEGIN END diff --git a/src/git.h b/src/git.h index 7a955d5f..e7ed6d90 100644 --- a/src/git.h +++ b/src/git.h @@ -39,8 +39,9 @@ enum ESI SI_SNES = 7, SI_SNES_MOUSE = 8, SI_VIRTUALBOY = 9, + SI_REAL_ZAPPER = 10, - SI_COUNT = SI_VIRTUALBOY + SI_COUNT = SI_REAL_ZAPPER }; inline const char* ESI_Name(ESI esi) @@ -56,7 +57,8 @@ inline const char* ESI_Name(ESI esi) "Subor Mouse", "SNES Pad", "SNES Mouse", - "Virtual Boy" + "Virtual Boy", + "Real Zapper" }; if(esi >= SI_NONE && esi <= SI_COUNT) diff --git a/src/input.cpp b/src/input.cpp index 7318b0f9..7906897c 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -65,6 +65,7 @@ extern INPUTC *FCEU_InitArkanoid(int w); extern INPUTC *FCEU_InitMouse(int w); extern INPUTC *FCEU_InitSNESMouse(int w); extern INPUTC *FCEU_InitVirtualBoy(int w); +extern INPUTC *FCEU_InitRealZapper(int w); extern INPUTCFC *FCEU_InitArkanoidFC(void); extern INPUTCFC *FCEU_InitSpaceShadow(void); @@ -483,6 +484,9 @@ static void SetInputStuff(int port) case SI_VIRTUALBOY: joyports[port].driver=FCEU_InitVirtualBoy(port); break; + case SI_REAL_ZAPPER: + joyports[port].driver = FCEU_InitRealZapper(port); + break; case SI_NONE: case SI_UNSET: joyports[port].driver=&DummyJPort; diff --git a/src/input/realzapper.cpp b/src/input/realzapper.cpp new file mode 100644 index 00000000..93d80594 --- /dev/null +++ b/src/input/realzapper.cpp @@ -0,0 +1,48 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "share.h" + +static uint32 realZapperStrobe[2]; +static uint32 realZapperData[2]; + +static uint8 ReadRealZapper(int w) +{ + return realZapperData[w]; +} + +static void StrobeRealZapper(int w) +{ + realZapperStrobe[w] = 0; +} + +void UpdateRealZapper(int w, void* data, int arg) +{ + // In the '(*(uint32*)data)' variable, bit 0 holds the trigger value and bit 1 holds the light sense value. + // Ultimately this needs to be converted from 0000 00lt to 000t l000 where l is the light bit and t + // is the trigger bit. + realZapperData[w] = ((((*(uint32*)data) & 1) << 4) | + (((*(uint32*)data) & 2) << 2)); +} + +static INPUTC RealZapperCtrl = { ReadRealZapper,0,StrobeRealZapper,UpdateRealZapper,0,0 }; + +INPUTC* FCEU_InitRealZapper(int w) +{ + realZapperStrobe[w] = realZapperData[w] = 0; + return(&RealZapperCtrl); +} diff --git a/vc/vc14_fceux.vcxproj b/vc/vc14_fceux.vcxproj index 54d4ed15..910c729e 100644 --- a/vc/vc14_fceux.vcxproj +++ b/vc/vc14_fceux.vcxproj @@ -710,6 +710,7 @@ + diff --git a/vc/vc14_fceux.vcxproj.filters b/vc/vc14_fceux.vcxproj.filters index e8870620..eb74f269 100644 --- a/vc/vc14_fceux.vcxproj.filters +++ b/vc/vc14_fceux.vcxproj.filters @@ -1105,6 +1105,9 @@ input + + input +