diff --git a/trunk/src/boards/transformer.cpp b/trunk/src/boards/transformer.cpp index 0f9c4a60..9a4b85aa 100644 --- a/trunk/src/boards/transformer.cpp +++ b/trunk/src/boards/transformer.cpp @@ -23,7 +23,8 @@ static uint8 *WRAM = NULL; static uint32 WRAMSIZE; -unsigned int *GetKeyboard(void); // FIXME: 10/28 - now implemented in SDL as well. should we rename this to a FCEUI_* function? +unsigned int *GetKeyboardAutorepeated(void); // FIXME: 10/28 - now implemented in SDL as well. should we rename this to a FCEUI_* function? + // Rpahut: don't. no actual game use or will ever use PC keyboard; even this transformer thing itself is quite questionable static unsigned int *TransformerKeys, oldkeys[256]; static int TransformerCycleCount, TransformerChar = 0; @@ -33,7 +34,7 @@ static void TransformerIRQHook(int a) { if (TransformerCycleCount >= 1000) { uint32 i; TransformerCycleCount -= 1000; - TransformerKeys = GetKeyboard(); + TransformerKeys = GetKeyboardAutorepeated(); for (i = 0; i < 256; i++) { if (oldkeys[i] != TransformerKeys[i]) { diff --git a/trunk/src/driver.h b/trunk/src/driver.h index 84b4af68..96650da2 100644 --- a/trunk/src/driver.h +++ b/trunk/src/driver.h @@ -82,6 +82,7 @@ void FCEUI_SetInputFourscore(bool attachFourscore); bool FCEUI_GetInputFourscore(); //tells whether the microphone is used bool FCEUI_GetInputMicrophone(); +void FCEUI_SetInputMicrophone(bool set); void FCEUI_UseInputPreset(int preset); @@ -287,11 +288,6 @@ void FCEUI_SetAviDisableMovieMessages(bool disable); void FCEUD_AviRecordTo(void); void FCEUD_AviStop(void); -///A callback that the emu core uses to poll the state of a given emulator command key -typedef int TestCommandState(int cmd); -///Signals the emu core to poll for emulator commands and take actions -void FCEUI_HandleEmuCommands(TestCommandState* testfn); - //Emulation speed enum EMUSPEED_SET diff --git a/trunk/src/drivers/common/input.cpp b/trunk/src/drivers/common/input.cpp new file mode 100644 index 00000000..25d646ff --- /dev/null +++ b/trunk/src/drivers/common/input.cpp @@ -0,0 +1,51 @@ +#include "drivers/common/input.h" +#include "utils/bitflags.h" + + +bool btncfg_::IsAxisButton(uint8 which) const { + return (ButtType[which] == BT_JOYSTICK && FL_TEST(ButtonNum[which], ISAXIS_MASK) != 0); +} + +bool btncfg_::IsAxisNegative(uint8 which) const { + assert(ButtType[which] == BT_JOYSTICK); + return (FL_TEST(ButtonNum[which], ISAXISNEG_MASK) != 0); +} + +uint8 btncfg_::GetAxisIdx(uint8 which) const { + assert(ButtType[which] == BT_JOYSTICK); + return FL_TEST(ButtonNum[which], AXISIDX_MASK); +} + +bool btncfg_::IsPovButton(uint8 which) const { + return (ButtType[which] == BT_JOYSTICK && FL_TEST(ButtonNum[which], ISPOVBTN_MASK) != 0); +} + +uint8 btncfg_::GetPovDir(uint8 which) const { + assert(ButtType[which] == BT_JOYSTICK); + return FL_TEST(ButtonNum[which], POVDIR_MASK); +} + +uint8 btncfg_::GetPovController(uint8 which) const { + assert(ButtType[which] == BT_JOYSTICK); + return (FL_TEST(ButtonNum[which], POVCONTROLLER_MASK) >> 4); +} + +uint8 btncfg_::GetJoyButton(uint8 which) const { + assert(ButtType[which] == BT_JOYSTICK); + return FL_TEST(ButtonNum[which], JOYBTN_MASK); +} + +uint16 btncfg_::GetScanCode(uint8 which) const { + assert(ButtType[which] == BT_KEYBOARD); + return ButtonNum[which]; +} + +void btncfg_::AssignScanCode(uint8 which, uint16 scode) { + assert(ButtType[which] == BT_KEYBOARD); + ButtonNum[which] = scode; +} + +void btncfg_::AssignJoyButton(uint8 which, uint16 btnnum) { + assert(ButtType[which] == BT_JOYSTICK); + ButtonNum[which] = btnnum; +} diff --git a/trunk/src/drivers/common/input.h b/trunk/src/drivers/common/input.h new file mode 100644 index 00000000..62dcd57b --- /dev/null +++ b/trunk/src/drivers/common/input.h @@ -0,0 +1,85 @@ +/* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef COMMON_INPUT_H +#define COMMON_INPUT_H + +#ifdef WIN32 +#include +typedef GUID JOYINSTANCEID; +#else +typedef const char* JOYINSTANCEID; // TODO SDL joystick name +#endif + +#include "types.h" + + +#define MAXBUTTCONFIG 4 + +/* BtnConfig + Mapping of hardware buttons/keys/axes to single virtual 'button'. + Can contain up to MAXBUTTCONFIG hardware keys associated with button. +*/ +typedef struct btncfg_ { +public: + typedef enum { + BT_UNSET = -1, + BT_KEYBOARD = 0, + BT_JOYSTICK + } ButtonType; + +public: + ButtonType ButtType[MAXBUTTCONFIG]; // device type + uint8 DeviceNum[MAXBUTTCONFIG]; // device index + uint16 ButtonNum[MAXBUTTCONFIG]; // button information + uint32 NumC; // number of hardware keys defined in this config + JOYINSTANCEID DeviceInstance[MAXBUTTCONFIG]; // platform-specific device identifier + // TODO must lookup DeviceNum internally based on JOYINSTANCEID; don't use DeviceNum + // directly as it might and will change from session to session + +public: + // ButtonNum masks + static const uint32 ISAXIS_MASK = 0x8000; + static const uint32 ISAXISNEG_MASK = 0x4000; + static const uint32 AXISIDX_MASK = 0x3; + static const uint32 ISPOVBTN_MASK = 0x2000; + static const uint32 POVDIR_MASK = 0x3; + static const uint32 POVCONTROLLER_MASK = 0x10; + static const uint32 JOYBTN_MASK = 0xf7; + +public: + bool IsAxisButton(uint8 which) const; + bool IsAxisNegative(uint8 which) const; + uint8 GetAxisIdx(uint8 which) const; + + bool IsPovButton(uint8 which) const; + uint8 GetPovDir(uint8 which) const; + uint8 GetPovController(uint8 which) const; + + uint8 GetJoyButton(uint8 which) const; + + uint16 GetScanCode(uint8 which) const; + +public: + void AssignScanCode(uint8 which, uint16 scode); + void AssignJoyButton(uint8 which, uint16 btnnum); +} BtnConfig; + +#endif // COMMON_INPUT_H diff --git a/trunk/src/drivers/sdl/config.cpp b/trunk/src/drivers/sdl/config.cpp index 0dbb2a92..76c7fa6a 100644 --- a/trunk/src/drivers/sdl/config.cpp +++ b/trunk/src/drivers/sdl/config.cpp @@ -291,12 +291,12 @@ InitConfig() } } - // QuizKing - prefix = "SDL.Input.QuizKing."; - config->addOption(prefix + "DeviceType", DefaultQuizKingDevice); + // PartyTap + prefix = "SDL.Input.QuizKing."; // TODO correct device name is "PartyTap" + config->addOption(prefix + "DeviceType", DefaultPartyTapDevice); config->addOption(prefix + "DeviceNum", 0); - for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) { - config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]); + for(unsigned int j = 0; j < PARTYTAP_NUM_BUTTONS; j++) { + config->addOption(prefix + PartyTapNames[j], DefaultPartyTap[j]); } // HyperShot diff --git a/trunk/src/drivers/sdl/input.cpp b/trunk/src/drivers/sdl/input.cpp index c371b2fe..36a32143 100644 --- a/trunk/src/drivers/sdl/input.cpp +++ b/trunk/src/drivers/sdl/input.cpp @@ -103,16 +103,16 @@ ParseGIInput (FCEUGI * gi) } -static uint8 QuizKingData = 0; +static uint8 PartyTapData = 0; static uint8 HyperShotData = 0; static uint32 MahjongData = 0; static uint32 FTrainerData = 0; static uint8 TopRiderData = 0; -static uint8 BWorldData[1 + 13 + 1]; +static uint8 BBattlerData[1 + 13 + 1]; static void UpdateFKB (void); static void UpdateGamepad (void); -static void UpdateQuizKing (void); +static void UpdatePartyTap (void); static void UpdateHyperShot (void); static void UpdateMahjong (void); static void UpdateFTrainer (void); @@ -426,10 +426,13 @@ void FCEUD_LoadStateFrom () FCEUI_LoadState (fname.c_str ()); } +#ifdef KEYBOARDTRANSFORMER_SPECIFIC /** * Hook for transformer board +* !!!Special feature, do not use for anything besides 'Keyboard +* Transformer' board */ -unsigned int *GetKeyboard(void) +unsigned int *GetKeyboardAutorepeated(void) { int size = 256; #if SDL_VERSION_ATLEAST(2, 0, 0) @@ -439,6 +442,7 @@ unsigned int *GetKeyboard(void) #endif return (unsigned int*)(keystate); } +#endif // KEYBOARDTRANSFORMER_SPECIFIC /** * Parse keyboard commands and execute accordingly. @@ -823,17 +827,17 @@ static void KeyboardCommands () if (_keyonly (Hotkeys[HK_INCREASE_SPEED])) FCEUI_NTSCINC (); - if ((CurInputType[2] == SIFC_BWORLD) || (cspec == SIS_DATACH)) + if ((CurInputType[2] == SIFC_BBATTLER) || (cspec == SIS_DATACH)) { if (keyonly (F8)) { barcoder ^= 1; if (!barcoder) { - if (CurInputType[2] == SIFC_BWORLD) + if (CurInputType[2] == SIFC_BBATTLER) { - strcpy ((char *) &BWorldData[1], (char *) bbuf); - BWorldData[0] = 1; + strcpy ((char *) &BBattlerData[1], (char *) bbuf); + BBattlerData[0] = 1; } else { @@ -1064,7 +1068,7 @@ ButtonConfigEnd () * Tests to see if a specified button is currently pressed. */ static int -DTestButton (ButtConfig * bc) +DTestButton (BtnConfig * bc) { int x; @@ -1099,7 +1103,7 @@ DTestButton (ButtConfig * bc) #define MKZ() {{0},{0},{0},0} #define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()} -ButtConfig GamePadConfig[4][10] = { +BtnConfig GamePadConfig[4][10] = { #if SDL_VERSION_ATLEAST(2, 0, 0) /* Gamepad 1 */ {MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER), @@ -1205,7 +1209,7 @@ UpdateGamepad(void) JSreturn = JS; } -static ButtConfig powerpadsc[2][12] = { +static BtnConfig powerpadsc[2][12] = { { MK (O), MK (P), MK (BRACKET_LEFT), MK (BRACKET_RIGHT), MK (K), MK (L), MK (SEMICOLON), @@ -1233,7 +1237,7 @@ UpdatePPadData (int w) } uint32 r = 0; - ButtConfig *ppadtsc = powerpadsc[w]; + BtnConfig *ppadtsc = powerpadsc[w]; int x; // update each of the 12 buttons @@ -1303,8 +1307,8 @@ void FCEUD_UpdateInput () case SIFC_MAHJONG: UpdateMahjong (); break; - case SIFC_QUIZKING: - UpdateQuizKing (); + case SIFC_PARTYTAP: + UpdatePartyTap (); break; case SIFC_FTRAINERB: case SIFC_FTRAINERA: @@ -1348,7 +1352,7 @@ void FCEUD_SetInput (bool fourscore, bool microphone, ESI port0, ESI port1, CurInputType[2] = fcexp; } - replaceP2StartWithMicrophone = microphone; + FCEUI_SetInputMicrophone(microphone); InitInputInterface (); } @@ -1418,14 +1422,14 @@ void InitInputInterface () case SIFC_MAHJONG: InputDPtr = &MahjongData; break; - case SIFC_QUIZKING: - InputDPtr = &QuizKingData; + case SIFC_PARTYTAP: + InputDPtr = &PartyTapData; break; case SIFC_TOPRIDER: InputDPtr = &TopRiderData; break; - case SIFC_BWORLD: - InputDPtr = BWorldData; + case SIFC_BBATTLER: + InputDPtr = BBattlerData; break; case SIFC_FTRAINERA: case SIFC_FTRAINERB: @@ -1438,7 +1442,7 @@ void InitInputInterface () } -static ButtConfig fkbmap[0x48] = { +static BtnConfig 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), @@ -1475,7 +1479,7 @@ static void UpdateFKB () } } -static ButtConfig HyperShotButtons[4] = { +static BtnConfig HyperShotButtons[4] = { MK (Q), MK (W), MK (E), MK (R) }; @@ -1497,7 +1501,7 @@ UpdateHyperShot () } } -static ButtConfig MahjongButtons[21] = { +static BtnConfig 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) @@ -1521,30 +1525,30 @@ UpdateMahjong () } } -static ButtConfig QuizKingButtons[6] = { +static BtnConfig PartyTapButtons[6] = { MK (Q), MK (W), MK (E), MK (R), MK (T), MK (Y) }; /** - * Update the status of the QuizKing input device. + * Update the status of the PartyTap input device. */ static void -UpdateQuizKing () +UpdatePartyTap () { int x; - QuizKingData = 0; + PartyTapData = 0; for (x = 0; x < 6; x++) { - if (DTestButton (&QuizKingButtons[x])) + if (DTestButton (&PartyTapButtons[x])) { - QuizKingData |= 1 << x; + PartyTapData |= 1 << x; } } } -static ButtConfig TopRiderButtons[8] = { +static BtnConfig TopRiderButtons[8] = { MK (Q), MK (W), MK (E), MK (R), MK (T), MK (Y), MK (U), MK (I) }; @@ -1565,7 +1569,7 @@ UpdateTopRider () } } -static ButtConfig FTrainerButtons[12] = { +static BtnConfig FTrainerButtons[12] = { MK (O), MK (P), MK (BRACKET_LEFT), MK (BRACKET_RIGHT), MK (K), MK (L), MK (SEMICOLON), MK (APOSTROPHE), @@ -1596,7 +1600,7 @@ UpdateFTrainer () * @param bc the NES gamepad's button config * @param which the index of the button */ -const char * ButtonName (const ButtConfig * bc, int which) +const char * ButtonName (const BtnConfig * bc, int which) { static char name[256]; @@ -1658,7 +1662,7 @@ const char * ButtonName (const ButtConfig * bc, int which) * Waits for a button input and returns the information as to which * button was pressed. Used in button configuration. */ -int DWaitButton (const uint8 * text, ButtConfig * bc, int wb) +int DWaitButton (const uint8 * text, BtnConfig * bc, int wb) { SDL_Event event; static int32 LastAx[64][64]; @@ -1765,7 +1769,7 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb) * possible settings for each input button. */ void -ConfigButton (char *text, ButtConfig * bc) +ConfigButton (char *text, BtnConfig * bc) { uint8 buf[256]; int wc; @@ -1808,22 +1812,22 @@ void ConfigDevice (int which, int arg) ButtonConfigBegin (); switch (which) { - case FCFGD_QUIZKING: + case FCFGD_PARTYTAP: prefix = "SDL.Input.QuizKing."; for (x = 0; x < 6; x++) { sprintf (buf, "Quiz King Buzzer #%d", x + 1); - ConfigButton (buf, &QuizKingButtons[x]); + ConfigButton (buf, &PartyTapButtons[x]); - g_config->setOption (prefix + QuizKingNames[x], - QuizKingButtons[x].ButtonNum[0]); + g_config->setOption (prefix + PartyTapNames[x], + PartyTapButtons[x].ButtonNum[0]); } - if (QuizKingButtons[0].ButtType[0] == BUTTC_KEYBOARD) + if (PartyTapButtons[0].ButtType[0] == BUTTC_KEYBOARD) { g_config->setOption (prefix + "DeviceType", "Keyboard"); } - else if (QuizKingButtons[0].ButtType[0] == BUTTC_JOYSTICK) + else if (PartyTapButtons[0].ButtType[0] == BUTTC_JOYSTICK) { g_config->setOption (prefix + "DeviceType", "Joystick"); } @@ -1832,7 +1836,7 @@ void ConfigDevice (int which, int arg) g_config->setOption (prefix + "DeviceType", "Unknown"); } g_config->setOption (prefix + "DeviceNum", - QuizKingButtons[0].DeviceNum[0]); + PartyTapButtons[0].DeviceNum[0]); break; case FCFGD_HYPERSHOT: prefix = "SDL.Input.HyperShot."; @@ -1964,7 +1968,7 @@ void InputCfg (const std::string & text) } else if (text.find ("quizking") != std::string::npos) { - ConfigDevice (FCFGD_QUIZKING, 0); + ConfigDevice (FCFGD_PARTYTAP, 0); } } else @@ -2007,7 +2011,7 @@ UpdateInput (Config * config) } else if (device.find ("QuizKing") != std::string::npos) { - UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_QUIZKING; + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_PARTYTAP; } else if (device.find ("HyperShot") != std::string::npos) { @@ -2047,7 +2051,7 @@ UpdateInput (Config * config) } else if (device.find ("BWorld") != std::string::npos) { - UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_BWORLD; + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_BBATTLER; } else if (device.find ("4Player") != std::string::npos) { @@ -2134,7 +2138,7 @@ UpdateInput (Config * config) } } - // QuizKing + // PartyTap prefix = "SDL.Input.QuizKing."; config->getOption (prefix + "DeviceType", &device); if (device.find ("Keyboard") != std::string::npos) @@ -2150,14 +2154,14 @@ UpdateInput (Config * config) type = 0; } config->getOption (prefix + "DeviceNum", &devnum); - for (unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) + for (unsigned int j = 0; j < PARTYTAP_NUM_BUTTONS; j++) { - config->getOption (prefix + QuizKingNames[j], &button); + config->getOption (prefix + PartyTapNames[j], &button); - QuizKingButtons[j].ButtType[0] = type; - QuizKingButtons[j].DeviceNum[0] = devnum; - QuizKingButtons[j].ButtonNum[0] = button; - QuizKingButtons[j].NumC = 1; + PartyTapButtons[j].ButtType[0] = type; + PartyTapButtons[j].DeviceNum[0] = devnum; + PartyTapButtons[j].ButtonNum[0] = button; + PartyTapButtons[j].NumC = 1; } // HyperShot @@ -2318,11 +2322,11 @@ const int DefaultPowerPad[POWERPAD_NUM_DEVICES][POWERPAD_NUM_BUTTONS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; -// QuizKing defaults -const char *QuizKingNames[QUIZKING_NUM_BUTTONS] = +// PartyTap defaults +const char *PartyTapNames[PARTYTAP_NUM_BUTTONS] = { "0", "1", "2", "3", "4", "5" }; -const char *DefaultQuizKingDevice = "Keyboard"; -const int DefaultQuizKing[QUIZKING_NUM_BUTTONS] = +const char *DefaultPartyTapDevice = "Keyboard"; +const int DefaultPartyTap[PARTYTAP_NUM_BUTTONS] = { SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y }; // HyperShot defaults diff --git a/trunk/src/drivers/sdl/input.h b/trunk/src/drivers/sdl/input.h index bd3d4994..e409d7cf 100644 --- a/trunk/src/drivers/sdl/input.h +++ b/trunk/src/drivers/sdl/input.h @@ -10,44 +10,40 @@ typedef struct { uint16 ButtonNum[MAXBUTTCONFIG]; uint32 NumC; //uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */ -} ButtConfig; +} BtnConfig; extern int NoWaiting; -extern CFGSTRUCT InputConfig[]; -extern ARGPSTRUCT InputArgs[]; extern int Hotkeys[]; void ParseGIInput(FCEUGI *GI); void setHotKeys(); int ButtonConfigBegin(); void ButtonConfigEnd(); -void ConfigButton(char *text, ButtConfig *bc); -int DWaitButton(const uint8 *text, ButtConfig *bc, int wb); +void ConfigButton(char *text, BtnConfig *bc); +int DWaitButton(const uint8 *text, BtnConfig *bc, int wb); #define BUTTC_KEYBOARD 0x00 #define BUTTC_JOYSTICK 0x01 -#define BUTTC_MOUSE 0x02 +#define BUTTC_MOUSE 0x02 // FIXME not used #define FCFGD_GAMEPAD 1 #define FCFGD_POWERPAD 2 #define FCFGD_HYPERSHOT 3 -#define FCFGD_QUIZKING 4 +#define FCFGD_PARTYTAP 4 #define SDL_FCEU_HOTKEY_EVENT SDL_USEREVENT void InitInputInterface(void); void InputUserActiveFix(void); -extern bool replaceP2StartWithMicrophone; -extern ButtConfig GamePadConfig[4][10]; -//extern ButtConfig powerpadsc[2][12]; -//extern ButtConfig QuizKingButtons[6]; -//extern ButtConfig FTrainerButtons[12]; +extern BtnConfig GamePadConfig[4][10]; +//extern BtnConfig powerpadsc[2][12]; +//extern BtnConfig FTrainerButtons[12]; void IncreaseEmulationSpeed(void); void DecreaseEmulationSpeed(void); -int DTestButtonJoy(ButtConfig *bc); +int DTestButtonJoy(BtnConfig *bc); void FCEUD_UpdateInput(void); @@ -55,6 +51,6 @@ void UpdateInput(Config *config); void InputCfg(const std::string &); std::string GetUserText(const char* title); -const char* ButtonName(const ButtConfig* bc, int which); +const char* ButtonName(const BtnConfig* bc, int which); #endif diff --git a/trunk/src/drivers/sdl/main.h b/trunk/src/drivers/sdl/main.h index fc9fefd5..a0398228 100644 --- a/trunk/src/drivers/sdl/main.h +++ b/trunk/src/drivers/sdl/main.h @@ -59,11 +59,11 @@ extern const char *PowerPadNames[POWERPAD_NUM_BUTTONS]; extern const char *DefaultPowerPadDevice[POWERPAD_NUM_DEVICES]; extern const int DefaultPowerPad[POWERPAD_NUM_DEVICES][POWERPAD_NUM_BUTTONS]; -// QuizKing defaults -#define QUIZKING_NUM_BUTTONS 6 -extern const char *QuizKingNames[QUIZKING_NUM_BUTTONS]; -extern const char *DefaultQuizKingDevice; -extern const int DefaultQuizKing[QUIZKING_NUM_BUTTONS]; +// PartyTap defaults +#define PARTYTAP_NUM_BUTTONS 6 +extern const char *PartyTapNames[PARTYTAP_NUM_BUTTONS]; +extern const char *DefaultPartyTapDevice; +extern const int DefaultPartyTap[PARTYTAP_NUM_BUTTONS]; // HyperShot defaults #define HYPERSHOT_NUM_BUTTONS 4 diff --git a/trunk/src/drivers/sdl/sdl-joystick.cpp b/trunk/src/drivers/sdl/sdl-joystick.cpp index 690b012b..34015364 100644 --- a/trunk/src/drivers/sdl/sdl-joystick.cpp +++ b/trunk/src/drivers/sdl/sdl-joystick.cpp @@ -39,7 +39,7 @@ static int s_jinited = 0; * Tests if the given button is active on the joystick. */ int -DTestButtonJoy(ButtConfig *bc) +DTestButtonJoy(BtnConfig *bc) { int x; diff --git a/trunk/src/drivers/sdl/sdl.cpp b/trunk/src/drivers/sdl/sdl.cpp index d23e5a64..ccf4186a 100644 --- a/trunk/src/drivers/sdl/sdl.cpp +++ b/trunk/src/drivers/sdl/sdl.cpp @@ -73,6 +73,8 @@ int mutecapture; static int noconfig; // -Video Modes Tag- : See --special +// TODO proper name for 'quizking' device is 'partytap' +// TODO proper name for 'bworld' is 'barcodebattler' ('bbattler') static const char *DriverUsage= "Option Value Description\n" "--pal {0|1} Use PAL timing.\n" @@ -617,7 +619,7 @@ int main(int argc, char *argv[]) int t; g_config->getOption("SDL.Input.FamicomPad2.EnableMic", &t); if(t) - replaceP2StartWithMicrophone = t; + FCEUI_SetInputMicrophone(t); } // update the input devices diff --git a/trunk/src/drivers/win/args.cpp b/trunk/src/drivers/win/args.cpp index 81d088a5..ba16248b 100644 --- a/trunk/src/drivers/win/args.cpp +++ b/trunk/src/drivers/win/args.cpp @@ -21,7 +21,8 @@ #include "main.h" #include "args.h" #include "common.h" -#include "../common/args.h" +#include "drivers/common/args.h" +#include "drivers/win/input.h" char* MovieToLoad = 0; //Loads a movie file on startup char* StateToLoad = 0; //Loads a savestate on startup (after a movie is loaded, if any) @@ -55,7 +56,7 @@ char *ParseArgies(int argc, char *argv[]) {"-stopframe",0,&replayStopFrameSetting,0}, {"-framedisplay",0,&frame_display,0}, {"-inputdisplay",0,&input_display,0}, - {"-allowUDLR",0,&allowUDLR,0}, + {"-allowUDLR",0,&_FIXME_GetAllowUDLRVar(),0}, {"-stopmovie",0,&pauseAfterPlayback,0}, {"-shutmovie",0,&closeFinishedMovie,0}, {"-bginput",0,&EnableBackgroundInput,0}, diff --git a/trunk/src/drivers/win/aviout.cpp b/trunk/src/drivers/win/aviout.cpp index 705449a5..5038a18d 100644 --- a/trunk/src/drivers/win/aviout.cpp +++ b/trunk/src/drivers/win/aviout.cpp @@ -7,7 +7,6 @@ #include "drivers/win/video.h" //extern WAVEFORMATEX wf; -//extern int soundo; extern int soundrate; diff --git a/trunk/src/drivers/win/common.h b/trunk/src/drivers/win/common.h index 191c117f..93b2cf80 100644 --- a/trunk/src/drivers/win/common.h +++ b/trunk/src/drivers/win/common.h @@ -29,7 +29,7 @@ extern HWND hAppWnd; extern HINSTANCE fceu_hInstance; -extern int NoWaiting; +extern int skipVSync; extern int eoptions; diff --git a/trunk/src/drivers/win/config.cpp b/trunk/src/drivers/win/config.cpp index 17198463..50f650fc 100644 --- a/trunk/src/drivers/win/config.cpp +++ b/trunk/src/drivers/win/config.cpp @@ -39,17 +39,16 @@ #include "ramwatch.h" #include "debugger.h" #include "taseditor/taseditor_config.h" +#include "drivers/win/input.h" #include "../../state.h" //adelikat: For bool backupSavestates extern CFGSTRUCT NetplayConfig[]; extern CFGSTRUCT InputConfig[]; -extern CFGSTRUCT HotkeyConfig[]; -extern int autoHoldKey, autoHoldClearKey; +extern CFGSTRUCT CommandsConfig[]; extern int frameAdvance_Delay; extern int EnableAutosave, AutosaveQty, AutosaveFrequency; extern int AFon, AFoff, AutoFireOffset; -extern int DesynchAutoFire; extern bool lagCounterDisplay; extern bool frameAdvanceLagSkip; extern int ClipSidesOffset; @@ -66,7 +65,6 @@ extern int CurrentState; extern bool pauseWhileActive; //adelikat: Cheats dialog extern bool enableHUDrecording; extern bool disableMovieMessages; -extern bool replaceP2StartWithMicrophone; extern bool SingleInstanceOnly; extern bool Show_FPS; extern bool oldInputDisplay; @@ -187,7 +185,7 @@ static CFGSTRUCT fceuconfig[] = NAC("genie",genie), NAC("fs",_FIXME_getFullscreenVar()), NAC("vgamode",_FIXME_getVModeIdxVar()), - NAC("sound",soundo), + NAC("sound",isSoundEnabled), NAC("sicon",status_icon), AC(newppu), @@ -229,7 +227,7 @@ static CFGSTRUCT fceuconfig[] = NAC("eoptions",eoptions), NACA("cpalette",cpalette), - NACA("InputType",InputType), + NACA("InputType",_FIXME_GetInputPortsArr()), NAC("vmcx",_FIXME_getCustomVideoModeVar().width), NAC("vmcy",_FIXME_getCustomVideoModeVar().height), @@ -254,11 +252,11 @@ static CFGSTRUCT fceuconfig[] = AC(ffbskip), ADDCFGSTRUCT(NetplayConfig), - ADDCFGSTRUCT(InputConfig), - ADDCFGSTRUCT(HotkeyConfig), + {0, _FIXME_GetInputConfigVar(), 0}, + {0, _FIXME_GetCommandsConfigVar(), 0}, - AC(autoHoldKey), - AC(autoHoldClearKey), + AC(_FIXME_GetAddAutoholdsKeyVar()), + AC(_FIXME_GetClearAutoholdsKeyVar()), AC(frame_display), AC(rerecord_display), AC(input_display), @@ -274,7 +272,7 @@ static CFGSTRUCT fceuconfig[] = AC(AutosaveFrequency), AC(frameAdvanceLagSkip), AC(debuggerAutoload), - AC(allowUDLR), + NAC("allowUDLR", _FIXME_GetAllowUDLRVar()), AC(symbDebugEnabled), AC(debuggerSaveLoadDEBFiles), AC(debuggerDisplayROMoffsets), @@ -341,7 +339,7 @@ static CFGSTRUCT fceuconfig[] = AC(AFon), AC(AFoff), AC(AutoFireOffset), - AC(DesynchAutoFire), + NAC("DesynchAutoFire", _FIXME_GetDesynchAutoFireVar()), AC(taseditorConfig.windowX), AC(taseditorConfig.windowY), AC(taseditorConfig.windowWidth), @@ -441,7 +439,7 @@ static CFGSTRUCT fceuconfig[] = AC(pauseWhileActive), AC(enableHUDrecording), AC(disableMovieMessages), - AC(replaceP2StartWithMicrophone), + NAC("replaceP2StartWithMicrophone", _FIXME_GetReplaceP2StartWithMicrophoneVar()), AC(SingleInstanceOnly), AC(Show_FPS), diff --git a/trunk/src/drivers/win/config.h b/trunk/src/drivers/win/config.h index 6606f695..33554200 100644 --- a/trunk/src/drivers/win/config.h +++ b/trunk/src/drivers/win/config.h @@ -4,5 +4,3 @@ // setting was changed by it, which spawns auxillary functions intended to push new values through void SaveConfig(const char *filename); void LoadConfig(const char *filename); - -extern int InputType[3]; diff --git a/trunk/src/drivers/win/directinput/directInput.cpp b/trunk/src/drivers/win/directinput/directInput.cpp new file mode 100644 index 00000000..cb8ed04b --- /dev/null +++ b/trunk/src/drivers/win/directinput/directInput.cpp @@ -0,0 +1,92 @@ +#include "directinput.h" + + +static LPDIRECTINPUT7 directInputHandle = NULL; + + +bool directinput::Create(HINSTANCE appInst) { + HRESULT status = DirectInputCreateEx(appInst, + DIRECTINPUT_VERSION, + IID_IDirectInput7, + (LPVOID *)&directInputHandle, + NULL); + + if(FAILED(status)) { + directInputHandle = NULL; + return false; + } + + return true; +} + +bool directinput::IsCreated() { + return (directInputHandle != NULL); +} + +void directinput::Destroy() { + if(directInputHandle) { + IDirectInput7_Release(directInputHandle); + directInputHandle = NULL; + } +} + +LPDIRECTINPUT7 directinput::GetDirectInputHandle() { + return directInputHandle; +} + +LPDIRECTINPUTDEVICE7 directinput::CreateDevice(REFGUID guid) { + if(directInputHandle != NULL) { + LPDIRECTINPUTDEVICE7 device; + // create device + if(DI_OK == IDirectInput7_CreateDeviceEx(directInputHandle, guid, IID_IDirectInputDevice7, (LPVOID *)&device, 0)) { + // assign suitable data format + LPCDIDATAFORMAT fmt = (guid == GUID_SysKeyboard)? &c_dfDIKeyboard:&c_dfDIJoystick2; + if(DI_OK == IDirectInputDevice7_SetDataFormat(device, fmt)) { + return device; + } + IDirectInputDevice7_Release(device); + } + } + + return NULL; +} + +void directinput::DestroyDevice(LPDIRECTINPUTDEVICE7 device) { + if(device != NULL) { + IDirectInputDevice7_Unacquire(device); + IDirectInputDevice7_Release(device); + } +} + +bool directinput::Acquire(LPDIRECTINPUTDEVICE7 device) { + HRESULT status = DIERR_INPUTLOST; + while(status == DIERR_INPUTLOST || status == DIERR_NOTACQUIRED) { + status = IDirectInputDevice7_Acquire(device); + } + // at this point whatever the status is we can't do anything else + // to acquire device + + return SUCCEEDED(status); +} + +bool directinput::SetCoopLevel(LPDIRECTINPUTDEVICE7 device, HWND window, bool allowBackgroundAccess) { + IDirectInputDevice7_Unacquire(device); + DWORD flags = DISCL_NONEXCLUSIVE | ((allowBackgroundAccess)? DISCL_BACKGROUND:DISCL_FOREGROUND); + return (DI_OK == IDirectInputDevice7_SetCooperativeLevel(device, window, flags)); +} + +bool directinput::GetState(LPDIRECTINPUTDEVICE7 device, DWORD size, LPVOID data) { + HRESULT status = IDirectInputDevice7_Poll(device); + if(status != DI_OK && status != DI_NOEFFECT) { + Acquire(device); + status = IDirectInputDevice7_Poll(device); + } + + status = IDirectInputDevice7_GetDeviceState(device, size, data); + if(status != DI_OK) { + memset(data, 0, size); + return false; + } + + return true; +} diff --git a/trunk/src/drivers/win/directinput/directinput.h b/trunk/src/drivers/win/directinput/directinput.h new file mode 100644 index 00000000..38c9c270 --- /dev/null +++ b/trunk/src/drivers/win/directinput/directinput.h @@ -0,0 +1,28 @@ +#ifndef DIRECTINPUT_H +#define DIRECTINPUT_H + +#include "drivers/win/common.h" +#include "dinput.h" + + +namespace directinput { + bool Create(HINSTANCE appInst); + bool IsCreated(void); + void Destroy(void); + LPDIRECTINPUT7 GetDirectInputHandle(void); + + LPDIRECTINPUTDEVICE7 CreateDevice(REFGUID guid); + void DestroyDevice(LPDIRECTINPUTDEVICE7 device); + + bool Acquire(LPDIRECTINPUTDEVICE7 device); + + // Set cooperative level on a device instance + // device must be acquired after call to this + bool SetCoopLevel(LPDIRECTINPUTDEVICE7 device, HWND window, bool allowBackgroundAccess); + + // Will acquire device if necessary, poll it and get state + // if getting state fails wipes data to 0 and returns false + bool GetState(LPDIRECTINPUTDEVICE7 device, DWORD size, LPVOID data); +}; + +#endif // DIRECTINPUT_H diff --git a/trunk/src/drivers/win/directinput/joystick.cpp b/trunk/src/drivers/win/directinput/joystick.cpp new file mode 100644 index 00000000..b6848409 --- /dev/null +++ b/trunk/src/drivers/win/directinput/joystick.cpp @@ -0,0 +1,153 @@ +/* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + DirectInput joystick wrapper/helper +*/ + +#include +#include + +#include "drivers/win/directinput/joystick.h" +#include "drivers/win/window.h" +#include "drivers/win/directinput/directinput.h" + + +#define MAXJOYSTICKS 0xFF + +/* Joystick GUID stored in BtnConfig is sufficient to look up the +device it is referring to, so we'll use GUID when working with +configs and leave indexes for the enumeration cases */ +struct compareGUID_ { + bool operator()(GUID a, GUID b) const { + return (memcmp(&a, &b, sizeof(GUID)) < 0); + } +}; + +typedef std::map GUID2IDXMAP; +static GUID2IDXMAP guidToIdx; + +static std::vector devices; + + +static void GetJoyRange(LPDIRECTINPUTDEVICE7 device, directinput::joystick::JOY_RANGE& ranges) { + memset(&ranges, 0, sizeof(directinput::joystick::JOY_RANGE)); + + DIPROPRANGE props; + memset(&props, 0, sizeof(DIPROPRANGE)); + props.diph.dwSize = sizeof(DIPROPRANGE); + props.diph.dwHeaderSize = sizeof(DIPROPHEADER); + props.diph.dwHow = DIPH_BYOFFSET; + + props.diph.dwObj = DIJOFS_X; + HRESULT status = IDirectInputDevice7_GetProperty(device, DIPROP_RANGE, &props.diph); + if(status == DI_OK || status == S_FALSE) { + ranges.base[0] = props.lMin; + ranges.range[0] = props.lMax - props.lMin; + } + + props.diph.dwObj = DIJOFS_Y; + status = IDirectInputDevice7_GetProperty(device, DIPROP_RANGE, &props.diph); + if(status == DI_OK || status == S_FALSE) { + ranges.base[1] = props.lMin; + ranges.range[1] = props.lMax - props.lMin; + } + + props.diph.dwObj = DIJOFS_Z; + status = IDirectInputDevice7_GetProperty(device, DIPROP_RANGE, &props.diph); + if(status == DI_OK || status == S_FALSE) { + ranges.base[2] = props.lMin; + ranges.range[2] = props.lMax - props.lMin; + } +} + +static BOOL CALLBACK OnJoystickFound_cb(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) { + if(devices.size() < MAXJOYSTICKS-1) { + directinput::joystick::DEVICE* device = new directinput::joystick::DEVICE(); + if(device != NULL) { + device->handle = directinput::CreateDevice(lpddi->guidInstance); + if(device->handle != NULL) { + if(directinput::SetCoopLevel(device->handle, *(HWND *)pvRef, false)) { + // NOTE hardcoded foreground access mode; as enumeration is done once on startup applying actual mode here is meaningless + GetJoyRange(device->handle, device->ranges); + + device->guid = lpddi->guidInstance; + guidToIdx.insert( std::pair(lpddi->guidInstance, devices.size()) ); + + directinput::Acquire(device->handle); + + device->isValid = true; + devices.push_back(device); + + return DIENUM_CONTINUE; + } + + directinput::DestroyDevice(device->handle); + device->handle = NULL; + } + + delete device; + } + } + else { + // no room left for more joysticks + return DIENUM_STOP; + } + + return DIENUM_CONTINUE; +} + +void directinput::joystick::InitDevices() { + HWND hwnd = GetMainHWND(); + LPDIRECTINPUT7 di = directinput::GetDirectInputHandle(); + IDirectInput7_EnumDevices(di, DIDEVTYPE_JOYSTICK, OnJoystickFound_cb, (LPVOID *)&hwnd, DIEDFL_ATTACHEDONLY); +} + +void directinput::joystick::ReleaseDevices() { + std::vector::reverse_iterator i; + while(1) { + i = devices.rbegin(); + if(i == devices.rend()) break; + else { + directinput::DestroyDevice((*i)->handle); + delete (*i); + devices.pop_back(); + } + } +} + +directinput::joystick::DEVIDX directinput::joystick::GetDeviceCount() { + return devices.size(); +} + +directinput::joystick::DEVICE* directinput::joystick::GetDevice(directinput::joystick::DEVIDX idx) { + if(idx < devices.size()) { + return devices[idx]; + } + + return NULL; +} + +directinput::joystick::DEVICE* directinput::joystick::GetDevice(GUID guid) { + GUID2IDXMAP::iterator i = guidToIdx.find(guid); + if(i == guidToIdx.end()) return NULL; + + return devices[i->second]; +} diff --git a/trunk/src/drivers/win/directinput/joystick.h b/trunk/src/drivers/win/directinput/joystick.h new file mode 100644 index 00000000..31c37e80 --- /dev/null +++ b/trunk/src/drivers/win/directinput/joystick.h @@ -0,0 +1,51 @@ +#ifndef DIRECTINPUTJOYSTICK_H +#define DIRECTINPUTJOYSTICK_H + +#include "drivers/win/common.h" +#include "dinput.h" + + +namespace directinput { +namespace joystick { + typedef struct { + LONG base[3]; // base values for three axes + LONG range[3]; // ranges for three axes + } JOY_RANGE; + + typedef struct joystick_ { + LPDIRECTINPUTDEVICE7 handle; + GUID guid; + DIJOYSTATE2 state; + bool isUpdated; + bool isValid; + JOY_RANGE ranges; + + joystick_() + : handle(NULL) + , isUpdated(false) + , isValid(false) + {} + } DEVICE; + + typedef uint8 DEVIDX; + + + // Init/release actual devices + void InitDevices(void); + void ReleaseDevices(void); + + + // Returns joystick with specified GUID + // or NULL if joystick cannot be found + DEVICE* GetDevice(GUID guid); + + // Returns number of joysticks available + DEVIDX GetDeviceCount(void); + + // Returns joystick at specified index + // or NULL if index is out of valid range + DEVICE* GetDevice(DEVIDX idx); +}; +}; + +#endif DIRECTINPUTJOYSTICK_H diff --git a/trunk/src/drivers/win/input.cpp b/trunk/src/drivers/win/input.cpp index 43848db9..f2872c73 100644 --- a/trunk/src/drivers/win/input.cpp +++ b/trunk/src/drivers/win/input.cpp @@ -1,1746 +1,773 @@ /* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ +* +* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ -// For commctrl.h below -#define _WIN32_IE 0x0550 +#include +#include +#include -#include "../../version.h" +#ifdef WIN32 +#include "directinput/directinput.h" +#include "drivers/win/inputConfigUI.h" +#else +TODO +#endif #include "common.h" -#include "dinput.h" -#include -#include - -#include "video.h" #include "input.h" #include "keyboard.h" #include "joystick.h" -#include "gui.h" #include "fceu.h" #include "movie.h" #include "window.h" -#include "sound.h" #include "keyscan.h" +#include "../../input/gamepad.h" +#include "../../input/fkb.h" +#include "../../input/suborkb.h" +#include "../../input/powerpad.h" +#include "../../input/hypershot.h" +#include "../../input/mahjong.h" +#include "../../input/quiz.h" // aka partytap +#include "../../input/toprider.h" +#include "../../input/ftrainer.h" +#include "utils/bitflags.h" -LPDIRECTINPUT7 lpDI=0; -void InitInputPorts(bool fourscore); +static uint32 GamepadData = 0; // button state flags, byte per gamepad +static uint32 GamepadPrevRawData = 0; // prevous RAW gamepad state, for internal use +static uint32 PowerPadData[2]; // powerpad state +static uint8 fkbkeys[NUMKEYS_FAMIKB]; // famicom keyboard state +static uint8 suborkbkeys[NUMKEYS_SUBORKB]; // subor keyboard state +static uint8 PartyTapData = 0; // button state flags (6 bits) +static uint8 HyperShotData = 0; // button state flags (4 bits) +static uint32 MahjongData = 0; // button state flags (21 bits) +static uint32 FTrainerData = 0; // button state flags (12 bits) +static uint8 TopRiderData = 0; // button state flags (8 bits) +static uint8 BBattlerData[1+13+1]; // FIXME never initialized or updated -VSYNCMODE tempwinsync = SYNCMODE_NONE; //Temp variable used by turbo to turn of sync settings -int tempsoundquality = 0; //Temp variable used by turbo to turn of sound quality settings -extern int soundquality; -extern bool replaceP2StartWithMicrophone; -//UsrInputType[] is user-specified. InputType[] is current -// (game/savestate/movie loading can override user settings) +#include "inputDevKeyMap.h" // insert device key maps -//int UsrInputType[3]={SI_GAMEPAD,SI_GAMEPAD,SIFC_NONE}; -int InputType[3]={SI_GAMEPAD,SI_NONE,SIFC_NONE}; +#define NUMPRESETS 3 +static BtnConfig GamePadPresets[3][GPAD_COUNT][GPAD_NUMKEYS] = {{GPAD_NOCFG(),GPAD_NOCFG(),GPAD_NOCFG(),GPAD_NOCFG()}, +{GPAD_NOCFG(),GPAD_NOCFG(),GPAD_NOCFG(),GPAD_NOCFG()}, +{GPAD_NOCFG(),GPAD_NOCFG(),GPAD_NOCFG(),GPAD_NOCFG()}}; -int InitDInput(void) -{ - HRESULT ddrval; +static bool inputEmuKeyboard = false; // process emulated keyboard flag +static int allowUDLR = 0; // allow U+D, L+R on d-pad +static int DesynchAutoFire = 0; // turbo A and B not at same time - 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); +static int addBtnToAutoholdsKey = 0; // key assigned to enable adding pressed buttons to autoholds +static int clearAllAutoholdsKey = 0; // key assigned to clear all prevously added autoholds + +static uint8 gpadAutoHoldMask[GPAD_COUNT] = {0, 0, 0, 0}; // flags for button autoholds + // if a bit is set, corresponding button will be pressed when assigned key is + // released, and released when assigned key is pressed +static bool addPressedButtonsToAutohold = false; +static bool clearAutoholdButtons = false; + +static CFGSTRUCT CommandsConfig[] = { + "CommandMapping", _FIXME_GetCommandMappingVar(), _FIXME_GetCommandMappingVarSize(), + ENDCFGSTRUCT +}; + +static CFGSTRUCT InputConfig[] = { + AC(PowerPadConfig), + AC(PartyTapConfig), + AC(FamiTrainerConfig), + AC(HyperShotConfig), + AC(MahjongConfig), + AC(GamePadConfig), + NAC("GamePadPreset1", GamePadPresets[0]), + NAC("GamePadPreset2", GamePadPresets[1]), + NAC("GamePadPreset3", GamePadPresets[2]), + AC(FamiKeyBoardConfig), + AC(SuborKeyBoardConfig), + ENDCFGSTRUCT +}; static uint32 MouseData[3]; -//force the input types suggested by the game -void ParseGIInput(FCEUGI *gi) -{ - if(gi) - { - if(gi->input[0]!=SI_UNSET) - InputType[0]=gi->input[0]; - if(gi->input[1]!=SI_UNSET) - InputType[1]=gi->input[1]; - if(gi->inputfc!=SIFC_UNSET) - InputType[2]=gi->inputfc; - InitInputPorts((eoptions & EO_FOURSCORE)!=0); +// FIXME: union hack to satisfy current config code, which requres InputPorts to be int[3] +typedef union inputports_ { + int InputPorts_configAdapter[3]; + struct { + ESI inputPorts[2]; // types of peripherals plugged into normal ports + ESIFC inputPortEx; // type of peripheral plugged into expansion port + }; + + inputports_() { + inputPorts[0] = SI_GAMEPAD; + inputPorts[1] = SI_NONE; + inputPortEx = SIFC_NONE; } +} InputPorts; +static InputPorts inputPorts; + +ESI GetPluggedIn(int port) { + assert(port >= 0 && port < 2); + return inputPorts.inputPorts[port]; } - -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 UpdateSuborKB(void); -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=0; -bool turbo = false; - -#include "keyscan.h" -static unsigned int *keys=0; -static unsigned int *keys_nr=0; -static int DIPS=0; - -//#define KEY(__a) keys_nr[MKK(__a)] - -int cidisabled=0; -int allowUDLR=0; - -#define MK(x) {{BUTTC_KEYBOARD},{0},{MKK(x)},1} -#define MC(x) {{BUTTC_KEYBOARD},{0},{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(F), MK(D), MK(S), MK(ENTER), MK(BL_CURSORUP), - MK(BL_CURSORDOWN),MK(BL_CURSORLEFT),MK(BL_CURSORRIGHT) - }, - - //Gamepad 2 - GPZ(), - - //Gamepad 3 - GPZ(), - - //Gamepad 4 - GPZ() -}; - -ButtConfig GamePadPreset1[4][10]={GPZ(),GPZ(),GPZ(),GPZ()}; -ButtConfig GamePadPreset2[4][10]={GPZ(),GPZ(),GPZ(),GPZ()}; -ButtConfig GamePadPreset3[4][10]={GPZ(),GPZ(),GPZ(),GPZ()}; -char *InputPresetDir = 0; - -extern int rapidAlternator; // for auto-fire / autofire -int DesynchAutoFire=0; // A and B not at same time -uint32 JSAutoHeld=0, JSAutoHeldAffected=0; // for auto-hold -uint8 autoHoldOn=0, autoHoldReset=0, autoHoldRefire=0; // for auto-hold - -void SetAutoFireDesynch(int DesynchOn) -{ - if(DesynchOn) - { - DesynchAutoFire = 1; - } - else - { - DesynchAutoFire = 0; - } +void SetPluggedIn(int port, ESI device) { + assert(port >= 0 && port < 2); + inputPorts.inputPorts[port] = device; } -int GetAutoFireDesynch() -{ - return DesynchAutoFire; +ESIFC GetPluggedInEx() { + return inputPorts.inputPortEx; } -// Test button state using current keyboard data. -// Clone of DTestButton, but uses local variables. -int DTestButtonImmediate(ButtConfig *bc) +void SetPluggedInEx(ESIFC device) { + inputPorts.inputPortEx = device; +} + +//Initializes the emulator with the current input port configuration +static void ApplyInputPorts() { - uint32 x;//mbg merge 7/17/06 changed to uint + bool useFourscore = (FL_TEST(eoptions, EO_FOURSCORE) != 0); + // normal ports + if(useFourscore) { + FCEUI_SetInput(0, SI_GAMEPAD, &GamepadData, 0); + FCEUI_SetInput(1, SI_GAMEPAD, &GamepadData, 0); + } + else { + for(int i=0; i<2; ++i) { + void* inputDataPtr = NULL; + switch(inputPorts.inputPorts[i]) { + case SI_POWERPADA: + case SI_POWERPADB: + inputDataPtr = &PowerPadData[i]; + break; + case SI_GAMEPAD: + inputDataPtr = &GamepadData; + break; + case SI_ARKANOID: + inputDataPtr = MouseData; + break; + case SI_ZAPPER: + inputDataPtr = MouseData; + break; + } + FCEUI_SetInput(i, inputPorts.inputPorts[i], inputDataPtr, 0); + } + } + FCEUI_SetInputFourscore(useFourscore); - static unsigned int *keys_im=GetKeyboard_nr(); + // expansion port + void* inputDataPtr = NULL; + switch(inputPorts.inputPortEx) { + case SIFC_SHADOW: + case SIFC_OEKAKIDS: + case SIFC_ARKANOID: + inputDataPtr = MouseData; + break; + case SIFC_FKB: + inputDataPtr = fkbkeys; + break; + case SIFC_PEC586KB: + case SIFC_SUBORKB: + inputDataPtr = suborkbkeys; + break; + case SIFC_HYPERSHOT: + inputDataPtr = &HyperShotData; + break; + case SIFC_MAHJONG: + inputDataPtr = &MahjongData; + break; + case SIFC_PARTYTAP: + inputDataPtr = &PartyTapData; + break; + case SIFC_TOPRIDER: + inputDataPtr = &TopRiderData; + break; + case SIFC_BBATTLER: + inputDataPtr = BBattlerData; + break; + case SIFC_FTRAINERA: + case SIFC_FTRAINERB: + inputDataPtr = &FTrainerData; + break; + } - for(x=0;xNumC;x++) - { - if(bc->ButtType[x]==BUTTC_KEYBOARD) - { - if(keys_im[bc->ButtonNum[x]]) - { - return(1); + FCEUI_SetInputFC(inputPorts.inputPortEx, inputDataPtr, 0); +} + +// Bring up the input configuration dialog +void ConfigInput() +{ + driver::input::ui::RootDialog(); + + // if a game is running, apply new configuration + if(GameInfo) ApplyInputPorts(); +} + +static int TestCommandState_cb(EMUCMD cmd); + +bool InitInputDriver() +{ + if(!directinput::Create(fceu_hInstance)) { + FCEUD_PrintError("DirectInput: Error creating DirectInput object."); + return false; + } + + driver::input::keyboard::Init(); + driver::input::joystick::Init(); + + FCEUI_SetTestCommandHotkeyCallback(TestCommandState_cb); + + return true; +} + +void KillInputDriver() +{ + if(directinput::IsCreated()) { + driver::input::joystick::Kill(); + driver::input::keyboard::Kill(); + directinput::Destroy(); + } + + FCEUI_SetTestCommandHotkeyCallback(NULL); +} + +void SetInputKeyboard(bool on) { + inputEmuKeyboard = on; +} + +bool GetInputKeyboard() { + return inputEmuKeyboard; +} + +void SetAutoFireDesynch(bool DesynchOn) +{ + DesynchAutoFire = (DesynchOn)? 1:0; +} + +bool GetAutoFireDesynch() +{ + return (DesynchAutoFire != 0); +} + +bool GetAllowUDLR() { + return (allowUDLR != 0); +} + +void SetAllowUDLR(bool allow) { + allowUDLR = (allow)? 1:0; +} + +int GetAutoholdsAddKey() { + return addBtnToAutoholdsKey; +} + +void SetAutoholdsAddKey(int k) { + addBtnToAutoholdsKey = k; +} + +int GetAutoholdsClearKey() { + return clearAllAutoholdsKey; +} + +void SetAutoholdsClearKey(int k) { + clearAllAutoholdsKey = k; +} + +BtnConfig* GetGamePadConfig() { + return &(GamePadConfig[0][0]); +} + +BtnConfig* GetPowerPadConfig() { + return &(PowerPadConfig[0][0]); +} + +BtnConfig* GetFamiTrainerConfig() { + return FamiTrainerConfig; +} + +BtnConfig* GetFamiKeyBoardConfig() { + return FamiKeyBoardConfig; +} + +BtnConfig* GetSuborKeyBoardConfig() { + return SuborKeyBoardConfig; +} + +BtnConfig* GetMahjongConfig() { + return MahjongConfig; +} + +BtnConfig* GetPartyTapConfig() { + return PartyTapConfig; +} + +uint8 const (& GetAutoHoldMask(void))[4] { + return gpadAutoHoldMask; +} + +// Test if a button listed in config is pressed +// Returns 1 if button is pressed, zero otherwise +static int TestButton(BtnConfig *bc) +{ + if(driver::input::keyboard::TestButton(bc) || driver::input::joystick::TestButton(bc)) { + return 1; + } + + return 0; +} + +uint32 GetGamepadPressedPhysical() +{ + uint8 gpadState[4] = {0,}; + + for(int gpadIdx=0; gpadIdxNumC;x++) - { - if(bc->ButtType[x]==BUTTC_KEYBOARD) - { - if(keys_nr[bc->ButtonNum[x]]) - { - return(1); - } - } - } - if(DTestButtonJoy(bc)) return(1); - return(0); -} - -void UpdateGamepad() +// Update gamepad state data +static void UpdateGamepad() { if(FCEUMOV_Mode(MOVIEMODE_PLAY)) return; - uint32 JS=0; - int x; - int wg; - if(FCEUMOV_Mode(MOVIEMODE_RECORD)) - AutoFire(); + uint8 gpadState[GPAD_COUNT] = {0,}; - for(wg=0;wg<4;wg++) - { - for(x=0;x<8;x++) - if(DTestButton(&GamePadConfig[wg][x])) - JS|=(1<> (gpadIdx*8)) & 0xFF, btnMask)) { + // button just went down + FL_FROMBOOL(gpadAutoHoldMask[gpadIdx], btnMask, !FL_TEST(gpadAutoHoldMask[gpadIdx], btnMask)); // toggle bit + } } } - // if(rapidAlternator) - for(x=0;x<2;x++) - if(DTestButton(&GamePadConfig[wg][8+x])) - JS|=((1<':' ', (c&0x20)?'v':' ', - (c&0x01)?'A':' ', (c&0x02)?'B':' ', (c&0x08)?'S':' ', (c&0x04)?'s':' ', - (c&0x4000)?'<':' ', (c&0x1000)?'^':' ', (c&0x8000)?'>':' ', (c&0x2000)?'v':' ', - (c&0x0100)?'A':' ', (c&0x0200)?'B':' ', (c&0x0800)?'S':' ', (c&0x0400)?'s':' ', - (c&0x400000)?'<':' ', (c&0x100000)?'^':' ', (c&0x800000)?'>':' ', (c&0x200000)?'v':' ', - (c&0x010000)?'A':' ', (c&0x020000)?'B':' ', (c&0x080000)?'S':' ', (c&0x040000)?'s':' ', - (c&0x40000000)?'<':' ', (c&0x10000000)?'^':' ', (c&0x80000000)?'>':' ', (c&0x20000000)?'v':' ', - (c&0x01000000)?'A':' ', (c&0x02000000)?'B':' ', (c&0x08000000)?'S':' ', (c&0x04000000)?'s':' '); - if(!(c&0xffffff00)) { - inputstr[9] = '\0'; - disppos = 30; - } - else if(!(c&0xffff0000)) { - inputstr[19] = '\0'; - disppos = 30; - } - else if(!(c&0xff000000)) { - inputstr[30] = '\0'; - } - } - FCEU_DispMessage("Held:\n%s", disppos, inputstr); - } - else - { - JSAutoHeldAffected = 0; - autoHoldRefire = 0; + // apply "alternator" (turbo buttons) + int alternator = GetRapidAlternatorState(); + if(TestButton(&GamePadConfig[gpadIdx][8])) { // A + FL_SET(gpadState[gpadIdx], (alternator)? 1:0); + } + if(DesynchAutoFire) (alternator)? 0:1; // flip alternator state for (B) if desync enabled + if(TestButton(&GamePadConfig[gpadIdx][9])) { // B + FL_SET(gpadState[gpadIdx], (alternator)? 2:0); + } } - if(autoHoldReset) - { - FCEU_DispMessage("Held: ",30); - JSAutoHeld = 0; - JSAutoHeldAffected = 0; - autoHoldRefire = 0; + // report autohold mask + // FIXME is this needed? there is neat graphical autoholds feedback we have besides this + if(addPressedButtonsToAutohold) { + std::string str; + int disppos = 38; + { + stringstream strstr; + for(int gpadIdx=0; gpadIdx0) strstr << ' '; + strstr << gpadIdx; + uint32 p = gpadAutoHoldMask[gpadIdx]; + strstr << (FL_TEST(p, GPAD_LEFT)?'<':' ') + << (FL_TEST(p, GPAD_UP)?'^':' ') + << (FL_TEST(p, GPAD_RIGHT)?'>':' ') + << (FL_TEST(p, GPAD_DOWN)?'v':' ') + << (FL_TEST(p, GPAD_A)?'A':' ') + << (FL_TEST(p, GPAD_B)?'B':' ') + << (FL_TEST(p, GPAD_START)?'S':' ') + << (FL_TEST(p, GPAD_SELECT)?'s':' '); + } + + str = strstr.str(); + } + + // Cut empty chunks off the string + if(gpadAutoHoldMask[3] == 0) { + if(gpadAutoHoldMask[2] == 0) { + if(gpadAutoHoldMask[1] == 0) { + str.resize(9); // nothing on pads 2, 3, 4 + } + else { + str.resize(19); // nothing on pads 3, 4 + } + disppos = 30; // also text fit in single line + } + else { + str.resize(30); // nothing on pad 4 + } + } + + FCEU_DispMessage("Held:\n%s", disppos, str.c_str()); + } + + if(clearAutoholdButtons) { + FCEU_DispMessage("Held: ", 30); + gpadAutoHoldMask[0] = 0; + gpadAutoHoldMask[1] = 0; + gpadAutoHoldMask[2] = 0; + gpadAutoHoldMask[3] = 0; } // apply auto-hold - if(JSAutoHeld) - JS ^= JSAutoHeld; + for(int gpadIdx=0; gpadIdxNumC;x++) - { - if(x) strcat(tmpstr, ", "); - - if(bc->ButtType[x] == BUTTC_KEYBOARD) - { - strcat(tmpstr,"KB: "); - if(!GetKeyNameText(((bc->ButtonNum[x] & 0x7F) << 16) | ((bc->ButtonNum[x] & 0x80) << 17), tmpstr+strlen(tmpstr), 16)) - { - // GetKeyNameText wasn't able to provide a name for the key, then just show scancode - sprintf(tmpstr+strlen(tmpstr),"%03d",bc->ButtonNum[x]); - } - } - else if(bc->ButtType[x] == BUTTC_JOYSTICK) - { - strcat(tmpstr,"JS "); - sprintf(tmpstr+strlen(tmpstr), "%d ", bc->DeviceNum[x]); - if(bc->ButtonNum[x] & 0x8000) - { - char *asel[3]={"x","y","z"}; - sprintf(tmpstr+strlen(tmpstr), "axis %s%s", asel[bc->ButtonNum[x] & 3],(bc->ButtonNum[x]&0x4000)?"-":"+"); - } - else if(bc->ButtonNum[x] & 0x2000) - { - sprintf(tmpstr+strlen(tmpstr), "hat %d:%d", (bc->ButtonNum[x] >> 4)&3, - bc->ButtonNum[x]&3); - } - else - { - sprintf(tmpstr+strlen(tmpstr), "button %d", bc->ButtonNum[x] & 127); - } - - } - } - - astr=(char*)malloc(strlen(tmpstr) + 1); //mbg merge 7/17/06 added cast - strcpy(astr,tmpstr); - return(astr); -} - - -static int DWBStarted; -static ButtConfig *DWBButtons; -static const uint8 *DWBText; - -static HWND die; - -static BOOL CALLBACK DWBCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - - switch(uMsg) { - case WM_DESTROY: - die = NULL; - return(0); - case WM_TIMER: - { - uint8 devicenum; - uint16 buttonnum; - GUID guid; - - if(DoJoyWaitTest(&guid, &devicenum, &buttonnum)) - { - ButtConfig *bc = DWBButtons; - char *nstr; - int wc; - if(DWBStarted) - { - ButtConfig *bc = DWBButtons; - bc->NumC = 0; - DWBStarted = 0; - } - wc = bc->NumC; - //FCEU_printf("%d: %d\n",devicenum,buttonnum); - bc->ButtType[wc]=BUTTC_JOYSTICK; - bc->DeviceNum[wc]=devicenum; - bc->ButtonNum[wc]=buttonnum; - bc->DeviceInstance[wc] = guid; - - /* Stop config if the user pushes the same button twice in a row. */ - if(wc && bc->ButtType[wc]==bc->ButtType[wc-1] && bc->DeviceNum[wc]==bc->DeviceNum[wc-1] && - bc->ButtonNum[wc]==bc->ButtonNum[wc-1]) - goto gornk; - - bc->NumC++; - - /* Stop config if we reached our maximum button limit. */ - if(bc->NumC >= MAXBUTTCONFIG) - goto gornk; - nstr = MakeButtString(bc); - SetDlgItemText(hwndDlg, LBL_DWBDIALOG_TEXT, nstr); - free(nstr); - } - } - break; - case WM_USER + 666: - //SetFocus(GetDlgItem(hwndDlg,LBL_DWBDIALOG_TEXT)); - if(DWBStarted) - { - char *nstr; - ButtConfig *bc = DWBButtons; - bc->NumC = 0; - DWBStarted = 0; - nstr = MakeButtString(bc); - SetDlgItemText(hwndDlg, LBL_DWBDIALOG_TEXT, nstr); - free(nstr); - } - - { - ButtConfig *bc = DWBButtons; - int wc = bc->NumC; - char *nstr; - - bc->ButtType[wc]=BUTTC_KEYBOARD; - bc->DeviceNum[wc]=0; - bc->ButtonNum[wc]=lParam&255; - - //Stop config if the user pushes the same button twice in a row. - if(wc && bc->ButtType[wc]==bc->ButtType[wc-1] && bc->DeviceNum[wc]==bc->DeviceNum[wc-1] && - bc->ButtonNum[wc]==bc->ButtonNum[wc-1]) - goto gornk; - - bc->NumC++; - //Stop config if we reached our maximum button limit. - if(bc->NumC >= MAXBUTTCONFIG) - goto gornk; - - nstr = MakeButtString(bc); - SetDlgItemText(hwndDlg, LBL_DWBDIALOG_TEXT, nstr); - free(nstr); - } - break; - case WM_INITDIALOG: - SetWindowText(hwndDlg, (char*)DWBText); //mbg merge 7/17/06 added cast - BeginJoyWait(hwndDlg); - SetTimer(hwndDlg,666,25,0); //Every 25ms. - { - char *nstr = MakeButtString(DWBButtons); - SetDlgItemText(hwndDlg, LBL_DWBDIALOG_TEXT, nstr); - free(nstr); - } - - - - break; - case WM_CLOSE: - case WM_QUIT: goto gornk; - - case WM_COMMAND: - switch(wParam&0xFFFF) - { - case BTN_CLEAR: - { - ButtConfig *bc = DWBButtons; - char *nstr; - bc->NumC = 0; - nstr = MakeButtString(bc); - SetDlgItemText(hwndDlg, LBL_DWBDIALOG_TEXT, nstr); - free(nstr); - } - break; - case BTN_CLOSE: -gornk: - KillTimer(hwndDlg,666); - EndJoyWait(hAppWnd); - SetForegroundWindow(GetParent(hwndDlg)); - DestroyWindow(hwndDlg); - break; - } - } - return 0; -} - -int DWaitButton(HWND hParent, const uint8 *text, ButtConfig *bc) -{ - DWBText=text; - DWBButtons = bc; - DWBStarted = 1; - - die = CreateDialog(fceu_hInstance, "DWBDIALOG", hParent, DWBCallB); - - EnableWindow(hParent, 0); - - ShowWindow(die, 1); - - while(die) - { - MSG msg; - while(PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) - { - if(GetMessage(&msg, 0, 0, 0) > 0) - { - if(msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN) - { - LPARAM tmpo; - - tmpo = ((msg.lParam >> 16) & 0x7F) | ((msg.lParam >> 17) & 0x80); - PostMessage(die,WM_USER+666,0,tmpo); - continue; - } - if(msg.message == WM_SYSCOMMAND) continue; - if(!IsDialogMessage(die, &msg)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - } - Sleep(10); - } - - EnableWindow(hParent, 1); - return 0; //mbg merge TODO 7/17/06 - had to add this return value--is it right? -} - -int DWaitSimpleButton(HWND hParent, const uint8 *text) -{ - DWBStarted = 1; - int ret = 0; - - die = CreateDialog(fceu_hInstance, "DWBDIALOGSIMPLE", hParent, NULL); - SetWindowText(die, (char*)text); //mbg merge 7/17/06 added cast - EnableWindow(hParent, 0); - - ShowWindow(die, 1); - - while(die) - { - MSG msg; - while(PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) - { - if(GetMessage(&msg, 0, 0, 0) > 0) - { - if(msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN) - { - LPARAM tmpo; - - tmpo=((msg.lParam>>16)&0x7F)|((msg.lParam>>17)&0x80); - ret = tmpo; - goto done; - } - if(msg.message == WM_SYSCOMMAND) continue; - if(!IsDialogMessage(die, &msg)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - } - Sleep(10); - } -done: - EndDialog(die,0); - EnableWindow(hParent, 1); - - if(ret == 1) // convert Esc to nothing (why is it 1 and not VK_ESCAPE?) - ret = 0; - return ret; -} - - -static ButtConfig *DoTBButtons=0; -static const char *DoTBTitle=0; -static int DoTBMax=0; -static int DoTBType=0,DoTBPort=0; - -static BOOL CALLBACK DoTBCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch(uMsg) { - case WM_INITDIALOG: - if(DoTBType == SI_GAMEPAD) - { - char buf[32]; - sprintf(buf,"Virtual Gamepad %d",DoTBPort+1); - SetDlgItemText(hwndDlg, GRP_GAMEPAD1,buf); - - sprintf(buf,"Virtual Gamepad %d",DoTBPort+3); - SetDlgItemText(hwndDlg, GRP_GAMEPAD2, buf); - } - SetWindowText(hwndDlg, DoTBTitle); - break; - case WM_CLOSE: - case WM_QUIT: goto gornk; - - case WM_COMMAND: - { - int b; - b=wParam&0xFFFF; - if(b>= 300 && b < (300 + DoTBMax)) - { - char btext[128]; - btext[0]=0; - GetDlgItemText(hwndDlg, b, btext, 128); - DWaitButton(hwndDlg, (uint8*)btext,&DoTBButtons[b - 300]); //mbg merge 7/17/06 added cast - } - else switch(wParam&0xFFFF) - { - case BTN_CLOSE: -gornk: - - EndDialog(hwndDlg,0); - break; - } - } - } - return 0; -} - -static void DoTBConfig(HWND hParent, const char *text, char *_template, ButtConfig *buttons, int max) -{ - DoTBTitle=text; - DoTBButtons = buttons; - DoTBMax = max; - DialogBox(fceu_hInstance,_template,hParent,DoTBCallB); -} - - -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 }; -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; - -static void UpdateComboPad(HWND hwndDlg, WORD id) -{ - unsigned int sel_input = id - COMBO_PAD1; - - // Update the user input type - InputType[sel_input] = - SendDlgItemMessage( - hwndDlg, - id, - CB_GETCURSEL, - 0, - (LPARAM)(LPSTR)0 - ); - - // Enable or disable the configuration button - EnableWindow( - GetDlgItem(hwndDlg, id + 2), - configurable_nes[InputType[sel_input]] - ); - - // Update the text field - SetDlgItemText( - hwndDlg, - TXT_PAD1 + sel_input, - (LPTSTR)ESI_Name((ESI)InputType[sel_input]) - ); -} - -static void UpdateComboFam(HWND hwndDlg) -{ -// Update the user input type of the famicom - InputType[FAMICOM_POSITION] = - SendDlgItemMessage( - hwndDlg, - COMBO_FAM, - CB_GETCURSEL, - 0, - (LPARAM)(LPSTR)0 - ); - - // Enable or disable the configuration button - EnableWindow( - GetDlgItem(hwndDlg, BTN_FAM), - configurable_fam[InputType[FAMICOM_POSITION]] - ); - - // Update the text field - SetDlgItemText( - hwndDlg, - TXT_FAM, - (LPTSTR)ESIFC_Name((ESIFC)InputType[FAMICOM_POSITION]) - ); -} - - -static void UpdateFourscoreState(HWND dlg) -{ - //(inverse logic:) - BOOL enable = (eoptions & EO_FOURSCORE)?FALSE:TRUE; - - EnableWindow(GetDlgItem(dlg,BTN_PORT1),enable); - EnableWindow(GetDlgItem(dlg,BTN_PORT2),enable); - EnableWindow(GetDlgItem(dlg,COMBO_PAD1),enable); - EnableWindow(GetDlgItem(dlg,COMBO_PAD2),enable); - EnableWindow(GetDlgItem(dlg,TXT_PAD1),enable); - EnableWindow(GetDlgItem(dlg,TXT_PAD2),enable); - - //change the inputs to gamepad - if(!enable) - { - SendMessage(GetDlgItem(dlg,COMBO_PAD1),CB_SETCURSEL,SI_GAMEPAD,0); - SendMessage(GetDlgItem(dlg,COMBO_PAD2),CB_SETCURSEL,SI_GAMEPAD,0); - UpdateComboPad(dlg,COMBO_PAD1); - UpdateComboPad(dlg,COMBO_PAD2); - SetDlgItemText(dlg,TXT_PAD1,ESI_Name(SI_GAMEPAD)); - SetDlgItemText(dlg,TXT_PAD2,ESI_Name(SI_GAMEPAD)); - } -} - -//Callback function of the input configuration dialog. -BOOL CALLBACK InputConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch(uMsg) - { - case WM_INITDIALOG: - // Update the disable UDLR checkbox based on the current value - CheckDlgButton(hwndDlg,BTN_ALLOW_LRUD,allowUDLR?BST_CHECKED:BST_UNCHECKED); - - //update the fourscore checkbox - CheckDlgButton(hwndDlg,CHECK_ENABLE_FOURSCORE,(eoptions & EO_FOURSCORE)?BST_CHECKED:BST_UNCHECKED); - - //update the microphone checkbox - CheckDlgButton(hwndDlg,CHECK_ENABLE_MICROPHONE,replaceP2StartWithMicrophone?BST_CHECKED:BST_UNCHECKED); - - // Initialize the controls for the input ports - for(unsigned int port = 0; port < NUMBER_OF_PORTS; port++) - { - // Initialize the combobox - for(unsigned int current_device = 0; current_device < NUMBER_OF_NES_DEVICES; current_device++) - { - SendDlgItemMessage(hwndDlg, - COMBO_PAD1 + port, - CB_ADDSTRING, 0, - (LPARAM)(LPSTR)ESI_Name((ESI)current_device) - ); - } - - // Fix to deal with corrupted config. - if (InputType[port]>SI_COUNT || InputType[port]<0) - InputType[port]=SI_UNSET; - - // Update the combobox selection according to the - // currently selected input mode. - SendDlgItemMessage(hwndDlg, - COMBO_PAD1 + port, - CB_SETCURSEL, - InputType[port], - (LPARAM)(LPSTR)0 - ); - - // Enable the configuration button if necessary. - EnableWindow( - GetDlgItem(hwndDlg, BTN_PORT1 + port), - configurable_nes[InputType[port]] - ); - - // Update the label that displays the input device. - SetDlgItemText( - hwndDlg, - TXT_PAD1 + port, - (LPTSTR)ESI_Name((ESI)InputType[port]) - ); - } - - // Initialize the Famicom combobox - for(unsigned current_device = 0; current_device < NUMBER_OF_FAMICOM_DEVICES; current_device++) - { - SendDlgItemMessage( - hwndDlg, - COMBO_FAM, - CB_ADDSTRING, - 0, - (LPARAM)(LPSTR)ESIFC_Name((ESIFC)current_device) - ); - } - - if (InputType[FAMICOM_POSITION]>SIFC_COUNT || InputType[FAMICOM_POSITION]<0) - InputType[FAMICOM_POSITION]=SIFC_UNSET; - - // Update the combobox selection according to the - // currently selected input mode. - SendDlgItemMessage( - hwndDlg, - COMBO_FAM, - CB_SETCURSEL, - InputType[FAMICOM_POSITION], - (LPARAM)(LPSTR)0 - ); - - // Enable the configuration button if necessary. - EnableWindow( - GetDlgItem(hwndDlg, BTN_FAM), - configurable_fam[InputType[FAMICOM_POSITION]] - ); - - // Update the label that displays the input device. - SetDlgItemText( - hwndDlg, - TXT_FAM, - (LPTSTR)ESIFC_Name((ESIFC)InputType[FAMICOM_POSITION]) - ); - - // Initialize the auto key controls - extern int autoHoldKey, autoHoldClearKey; - char btext[128]; - if (autoHoldKey) - { - if (!GetKeyNameText(autoHoldKey << 16, btext, 128)) - sprintf(btext, "KB: %d", autoHoldKey); - } else - { - sprintf(btext, "not assigned"); - } - SetDlgItemText(hwndDlg, LBL_AUTO_HOLD, btext); - - if (autoHoldClearKey) - { - if (!GetKeyNameText(autoHoldClearKey << 16, btext, 128)) - sprintf(btext, "KB: %d", autoHoldClearKey); - } else - { - sprintf(btext, "not assigned"); - } - SetDlgItemText(hwndDlg, LBL_CLEAR_AH, btext); - - CenterWindowOnScreen(hwndDlg); - UpdateFourscoreState(hwndDlg); - - if (!FCEUMOV_Mode(MOVIEMODE_INACTIVE)) - { - // disable changing fourscore and Input ports while a movie is recorded/played - EnableWindow(GetDlgItem(hwndDlg, CHECK_ENABLE_FOURSCORE), false); - EnableWindow(GetDlgItem(hwndDlg, CHECK_ENABLE_MICROPHONE), false); - EnableWindow(GetDlgItem(hwndDlg, COMBO_PAD1), false); - EnableWindow(GetDlgItem(hwndDlg, COMBO_PAD2), false); - EnableWindow(GetDlgItem(hwndDlg, COMBO_FAM), false); - } - - break; - - case WM_CLOSE: - case WM_QUIT: - EndDialog(hwndDlg, 0); - - case WM_COMMAND: - // Handle disable UD/LR option - if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == BTN_ALLOW_LRUD) - { - FCEU_printf("Allow UDLR toggled.\n"); - allowUDLR = !allowUDLR; - } - - //Handle the fourscore button - if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == CHECK_ENABLE_FOURSCORE) - { - eoptions ^= EO_FOURSCORE; - FCEU_printf("Fourscore toggled to %s\n",(eoptions & EO_FOURSCORE)?"ON":"OFF"); - UpdateFourscoreState(hwndDlg); - } - - //Handle the fourscore button - if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == CHECK_ENABLE_MICROPHONE) - { - replaceP2StartWithMicrophone = !replaceP2StartWithMicrophone; - FCEU_printf("Microphone toggled to %s\n",replaceP2StartWithMicrophone?"ON":"OFF"); - } - - - if(HIWORD(wParam) == CBN_SELENDOK) - { - switch(LOWORD(wParam)) - { - case COMBO_PAD1: - case COMBO_PAD2: - UpdateComboPad(hwndDlg, LOWORD(wParam)); - break; - - case COMBO_FAM: - UpdateComboFam(hwndDlg); - break; - } - - } - - if( !(wParam >> 16) ) - { - switch(wParam & 0xFFFF) - { - case BTN_FAM: - { - const char *text = ESIFC_Name((ESIFC)InputType[FAMICOM_POSITION]); - - DoTBType = DoTBPort = 0; - - switch(InputType[FAMICOM_POSITION]) - { - case SIFC_FTRAINERA: - case SIFC_FTRAINERB: - DoTBConfig(hwndDlg, text, "POWERPADDIALOG", FTrainerButtons, 12); - break; - case SIFC_FKB: - DoTBConfig(hwndDlg, text, "FKBDIALOG", fkbmap, sizeof(fkbkeys)); - break; - case SIFC_PEC586KB: - case SIFC_SUBORKB: - DoTBConfig(hwndDlg, text, "SUBORKBDIALOG", suborkbmap, sizeof(suborkbkeys)); - break; - case SIFC_MAHJONG: - DoTBConfig(hwndDlg, text, "MAHJONGDIALOG", MahjongButtons, 21); - break; - case SIFC_QUIZKING: - DoTBConfig(hwndDlg, text, "QUIZKINGDIALOG", QuizKingButtons, 6); - break; - } - } - - break; - - case BTN_PORT2: - case BTN_PORT1: - { - int which = (wParam & 0xFFFF) - BTN_PORT1; - const char *text = ESI_Name((ESI)InputType[which]); - - DoTBType = DoTBPort = 0; - - switch(InputType[which]) - { - case SI_GAMEPAD: - { - ButtConfig tmp[10 + 10]; - - memcpy(tmp, GamePadConfig[which], 10 * sizeof(ButtConfig)); - memcpy(&tmp[10], GamePadConfig[which + 2], 10 * sizeof(ButtConfig)); - - DoTBType = SI_GAMEPAD; - DoTBPort = which; - DoTBConfig(hwndDlg, text, "GAMEPADDIALOG", tmp, 10 + 10); - - memcpy(GamePadConfig[which], tmp, 10 * sizeof(ButtConfig)); - memcpy(GamePadConfig[which + 2], &tmp[10], 10 * sizeof(ButtConfig)); - } - break; - - case SI_POWERPADA: - case SI_POWERPADB: - DoTBConfig(hwndDlg, text, "POWERPADDIALOG", powerpadsc[which], 12); - break; - } - } - - break; - - case BTN_PRESET_SET1: - MessageBox(0, "Current input configuration has been set as Preset 1.", FCEU_NAME, MB_ICONINFORMATION | MB_OK | MB_SETFOREGROUND | MB_TOPMOST); - memcpy(GamePadPreset1, GamePadConfig, sizeof(GamePadConfig)); - break; - case BTN_PRESET_SET2: - MessageBox(0, "Current input configuration has been set as Preset 2.", FCEU_NAME, MB_ICONINFORMATION | MB_OK | MB_SETFOREGROUND | MB_TOPMOST); - memcpy(GamePadPreset2, GamePadConfig, sizeof(GamePadConfig)); - break; - case BTN_PRESET_SET3: - MessageBox(0, "Current input configuration has been set as Preset 3.", FCEU_NAME, MB_ICONINFORMATION | MB_OK | MB_SETFOREGROUND | MB_TOPMOST); - memcpy(GamePadPreset3, GamePadConfig, sizeof(GamePadConfig)); - break; - - case BTN_PRESET_EXPORT1: PresetExport(1); break; - case BTN_PRESET_EXPORT2: PresetExport(2); break; - case BTN_PRESET_EXPORT3: PresetExport(3); break; - - case BTN_PRESET_IMPORT1: PresetImport(1); break; - case BTN_PRESET_IMPORT2: PresetImport(2); break; - case BTN_PRESET_IMPORT3: PresetImport(3); break; - - case BTN_AUTO_HOLD: // auto-hold button - { - char btext[128] = { 0 }; - - GetDlgItemText(hwndDlg, BTN_AUTO_HOLD, btext, sizeof(btext) ); - - int button = DWaitSimpleButton(hwndDlg, (uint8*)btext); //mbg merge 7/17/06 - - if(button) - { - if(!GetKeyNameText(button << 16, btext, 128)) - { - sprintf(btext, "KB: %d", button); - } - } - else - { - sprintf(btext, "not assigned"); - } - - extern int autoHoldKey; - autoHoldKey = button; - SetDlgItemText(hwndDlg, LBL_AUTO_HOLD, btext); - } - break; - - case BTN_CLEAR_AH: // auto-hold clear button - { - char btext[128] = { 0 }; - - GetDlgItemText(hwndDlg, BTN_CLEAR_AH, btext, 128); - - int button = DWaitSimpleButton(hwndDlg, (uint8*)btext); //mbg merge 7/17/06 added cast - - if(button) - { - if( !GetKeyNameText(button << 16, btext, sizeof(btext))) - { - sprintf(btext, "KB: %d", button); - } - } - else - { - sprintf(btext, "not assigned"); - } - - extern int autoHoldClearKey; - autoHoldClearKey = button; - - SetDlgItemText(hwndDlg, LBL_CLEAR_AH, btext); - } - break; - - case BTN_CLOSE: - EndDialog(hwndDlg, 0); - break; - } - } - } - - return 0; -} - -//Shows the input configuration dialog. -void ConfigInput(HWND hParent) -{ - DialogBox(fceu_hInstance, "INPUTCONFIG", hParent, InputConCallB); - - //in case the input config changes while a game is running, reconfigure the input ports - if(GameInfo) - { - InitInputPorts((eoptions & EO_FOURSCORE)!=0); - } -} - -void DestroyInput(void) -{ - if(lpDI) - { - KillJoysticks(); - KeyboardClose(); - IDirectInput7_Release(lpDI); - } -} - -int FCEUD_CommandMapping[EMUCMD_MAX]; - -CFGSTRUCT HotkeyConfig[]={ - AC(FCEUD_CommandMapping), - ENDCFGSTRUCT -}; - -int FCEUD_TestCommandState(int c) -{ - int cmd=FCEUD_CommandMapping[c]; - int cmdmask=cmd&CMD_KEY_MASK; - - // allow certain commands be affected by key repeat - if(c == EMUCMD_FRAME_ADVANCE/* - || c == EMUCMD_SOUND_VOLUME_UP - || c == EMUCMD_SOUND_VOLUME_DOWN - || c == EMUCMD_SPEED_SLOWER - || c == EMUCMD_SPEED_FASTER*/) - { - keys=GetKeyboard_nr(); - /* if((cmdmask & CMD_KEY_LALT) == CMD_KEY_LALT - || (cmdmask & CMD_KEY_RALT) == CMD_KEY_RALT - || (cmdmask & CMD_KEY_LALT) == CMD_KEY_LALT - || (cmdmask & CMD_KEY_LCTRL) == CMD_KEY_LCTRL - || (cmdmask & CMD_KEY_RCTRL) == CMD_KEY_RCTRL - || (cmdmask & CMD_KEY_LSHIFT) == CMD_KEY_LSHIFT - || (cmdmask & CMD_KEY_RSHIFT) == CMD_KEY_RSHIFT)*/ - keys_nr=GetKeyboard_nr(); - // else - // keys_nr=GetKeyboard_nr(); - } - else if(c != EMUCMD_SPEED_TURBO && c != EMUCMD_TASEDITOR_REWIND) // TODO: this should be made more general by detecting if the command has an "off" function - { - keys=GetKeyboard_jd(); - keys_nr=GetKeyboard_nr(); - } - else - { - keys=GetKeyboard_nr(); - keys_nr=GetKeyboard_nr(); - } - - /* test CTRL, SHIFT, ALT */ - if (cmd & CMD_KEY_ALT) - { - int ctlstate = (cmd & CMD_KEY_LALT) ? keys_nr[SCAN_LEFTALT] : 0; - ctlstate |= (cmd & CMD_KEY_RALT) ? keys_nr[SCAN_RIGHTALT] : 0; - if (!ctlstate) - return 0; - } - else if((cmdmask != SCAN_LEFTALT && keys_nr[SCAN_LEFTALT]) || (cmdmask != SCAN_RIGHTALT && keys_nr[SCAN_RIGHTALT])) - return 0; - - if (cmd & CMD_KEY_CTRL) - { - int ctlstate = (cmd & CMD_KEY_LCTRL) ? keys_nr[SCAN_LEFTCONTROL] : 0; - ctlstate |= (cmd & CMD_KEY_RCTRL) ? keys_nr[SCAN_RIGHTCONTROL] : 0; - if (!ctlstate) - return 0; - } - else if((cmdmask != SCAN_LEFTCONTROL && keys_nr[SCAN_LEFTCONTROL]) || (cmdmask != SCAN_RIGHTCONTROL && keys_nr[SCAN_RIGHTCONTROL])) - return 0; - - if (cmd & CMD_KEY_SHIFT) - { - int ctlstate = (cmd & CMD_KEY_LSHIFT) ? keys_nr[SCAN_LEFTSHIFT] : 0; - ctlstate |= (cmd & CMD_KEY_RSHIFT) ? keys_nr[SCAN_RIGHTSHIFT] : 0; - if (!ctlstate) - return 0; - } - else if((cmdmask != SCAN_LEFTSHIFT && keys_nr[SCAN_LEFTSHIFT]) || (cmdmask != SCAN_RIGHTSHIFT && keys_nr[SCAN_RIGHTSHIFT])) - return 0; - - return keys[cmdmask] ? 1 : 0; -} - -void FCEUD_TurboOn (void) - { - tempwinsync = GetWindowedSyncModeIdx(); //Store wndSyncMode setting - SetWindowedSyncModeIdx(SYNCMODE_NONE); //turn off wndSyncMode for turbo (so that turbo can function even with VBlank sync methods - tempsoundquality = soundquality; //Store sound quality settings - FCEUI_SetSoundQuality(0); //Turn sound quality to low - turbo = true; - if (muteTurbo && soundo) TrashSound(); - } -void FCEUD_TurboOff (void) - { - SetWindowedSyncModeIdx(tempwinsync); //Restore wndSyncMode setting - soundquality = tempsoundquality; //Restore sound quality settings - FCEUI_SetSoundQuality(soundquality); - turbo = false; - if (muteTurbo && soundo) InitSound(); - } -void FCEUD_TurboToggle(void) -{ - if (turbo) { - SetWindowedSyncModeIdx(tempwinsync); //If turbo was on, restore wndSyncMode - soundquality = tempsoundquality; //and restore sound quality setting - FCEUI_SetSoundQuality(soundquality); - } - else - { - tempwinsync = GetWindowedSyncModeIdx(); //Store video sync settings - tempsoundquality = soundquality; //Store sound quality settings - SetWindowedSyncModeIdx(SYNCMODE_NONE); //If turbo was off, turn off wndSyncMode (so that turbo can function even with VBlank sync methods - FCEUI_SetSoundQuality(0); //Set sound quality to low - } - - turbo = !turbo; - if (muteTurbo && soundo) - { - if (turbo) TrashSound(); - if (!turbo) InitSound(); - } -} - -void FCEUI_UseInputPreset(int preset) -{ - switch(preset) - { - case 0: memcpy(GamePadConfig, GamePadPreset1, sizeof(GamePadPreset1)); break; - case 1: memcpy(GamePadConfig, GamePadPreset2, sizeof(GamePadPreset2)); break; - case 2: memcpy(GamePadConfig, GamePadPreset3, sizeof(GamePadPreset3)); break; - } FCEU_DispMessage("Using input preset %d.",0,preset+1); } -static void PresetExport(int preset) -{ +void CopyConfigToPreset(unsigned int presetIdx) { + assert(presetIdx < NUMPRESETS); + memcpy(GamePadPresets[presetIdx], GamePadConfig, sizeof(GamePadConfig)); +} + +void PresetExport(int presetNum) { + std::string initdir = FCEU_GetPath(FCEUMKF_INPUT); const char filter[]="Input Preset File (*.pre)\0*.pre\0All Files (*.*)\0*.*\0\0"; char nameo[2048]; - OPENFILENAME ofn; - memset(&ofn,0,sizeof(ofn)); - ofn.lStructSize=sizeof(ofn); - ofn.hInstance=fceu_hInstance; - ofn.lpstrTitle="Export Input Preset To..."; - ofn.lpstrFilter=filter; - nameo[0]=0; //No default filename - ofn.lpstrFile=nameo; - ofn.lpstrDefExt="pre"; - ofn.nMaxFile=256; - ofn.Flags=OFN_EXPLORER|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT; - std::string initdir = FCEU_GetPath(FCEUMKF_INPUT).c_str(); - ofn.lpstrInitialDir=initdir.c_str(); - if(GetSaveFileName(&ofn)) - { - //Save the directory - if(ofn.nFileOffset < 1024) - { - free(InputPresetDir); - InputPresetDir=(char*)malloc(strlen(ofn.lpstrFile)+1); - strcpy(InputPresetDir,ofn.lpstrFile); - InputPresetDir[ofn.nFileOffset]=0; - } + nameo[0] = '\0'; //No default filename - FILE *fp=FCEUD_UTF8fopen(nameo,"w"); - switch(preset) - { - case 1: fwrite(GamePadPreset1,1,sizeof(GamePadPreset1),fp); break; - case 2: fwrite(GamePadPreset2,1,sizeof(GamePadPreset2),fp); break; - case 3: fwrite(GamePadPreset3,1,sizeof(GamePadPreset3),fp); break; - } + OPENFILENAME ofn; + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hInstance = fceu_hInstance; + ofn.lpstrTitle = "Export Input Preset To..."; + ofn.lpstrFilter = filter; + ofn.lpstrFile = nameo; + ofn.lpstrDefExt = "pre"; + ofn.nMaxFile = 256; + ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + ofn.lpstrInitialDir = initdir.c_str(); + + if(GetSaveFileName(&ofn)) { + BtnConfig* datap = &GamePadPresets[presetNum][0][0]; + unsigned int size = sizeof(GamePadPresets[presetNum]); + + FILE* fp = FCEUD_UTF8fopen(nameo, "w"); + fwrite(datap, 1, size, fp); fclose(fp); } } -static void PresetImport(int preset) -{ +void PresetImport(int presetNum) { + std::string initdir = FCEU_GetPath(FCEUMKF_INPUT); const char filter[]="Input Preset File (*.pre)\0*.pre\0\0"; char nameo[2048]; + nameo[0] = '\0'; + OPENFILENAME ofn; - memset(&ofn,0,sizeof(ofn)); - ofn.lStructSize=sizeof(ofn); - ofn.hInstance=fceu_hInstance; - ofn.lpstrTitle="Import Input Preset......"; - ofn.lpstrFilter=filter; - nameo[0]=0; - ofn.lpstrFile=nameo; - ofn.nMaxFile=256; - ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; - std::string initdir = FCEU_GetPath(FCEUMKF_INPUT); - ofn.lpstrInitialDir=initdir.c_str(); + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hInstance = fceu_hInstance; + ofn.lpstrTitle = "Import Input Preset......"; + ofn.lpstrFilter = filter; + ofn.lpstrFile = nameo; + ofn.nMaxFile = 256; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + ofn.lpstrInitialDir = initdir.c_str(); - if(GetOpenFileName(&ofn)) - { - //Save the directory - if(ofn.nFileOffset < 1024) - { - free(InputPresetDir); - InputPresetDir=(char*)malloc(strlen(ofn.lpstrFile)+1); - strcpy(InputPresetDir,ofn.lpstrFile); - InputPresetDir[ofn.nFileOffset]=0; - } + if(GetOpenFileName(&ofn)) { + BtnConfig* data = &GamePadPresets[presetNum][0][0]; + unsigned int size = sizeof(GamePadPresets[presetNum]); - FILE *fp=FCEUD_UTF8fopen(nameo,"r"); - switch(preset) - { - case 1: fread(GamePadPreset1,1,sizeof(GamePadPreset1),fp); break; - case 2: fread(GamePadPreset2,1,sizeof(GamePadPreset2),fp); break; - case 3: fread(GamePadPreset3,1,sizeof(GamePadPreset3),fp); break; - } + FILE* fp = FCEUD_UTF8fopen(nameo, "r"); + fread(data, 1, size, fp); fclose(fp); } } -//commandline input config. not being used right now -//--------------------------- -//static void FCExp(char *text) -//{ -// static char *fccortab[12]={"none","arkanoid","shadow","4player","fkb","suborkb", -// "hypershot","mahjong","quizking","ftrainera","ftrainerb","oekakids"}; -// -// static int fccortabi[12]={SIFC_NONE,SIFC_ARKANOID,SIFC_SHADOW, -// SIFC_4PLAYER,SIFC_FKB,SIFC_SUBORKB,SIFC_HYPERSHOT,SIFC_MAHJONG,SIFC_QUIZKING, -// SIFC_FTRAINERA,SIFC_FTRAINERB,SIFC_OEKAKIDS}; -// int y; -// for(y=0;y<12;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[]={ -// {"-fcexp",0,(void *)FCExp,0x2000}, -// {"-input1",0,(void *)Input1,0x2000}, -// {"-input2",0,(void *)Input2,0x2000}, -// {0,0,0,0} -//}; +int (&_FIXME_GetInputPortsArr(void))[3] { + return inputPorts.InputPorts_configAdapter; +} + +int& _FIXME_GetAddAutoholdsKeyVar() { + return addBtnToAutoholdsKey; +} + +int& _FIXME_GetClearAutoholdsKeyVar() { + return clearAllAutoholdsKey; +} + +int& _FIXME_GetAllowUDLRVar() { + return allowUDLR; +} + +int& _FIXME_GetDesynchAutoFireVar() { + return DesynchAutoFire; +} + +CFGSTRUCT* _FIXME_GetCommandsConfigVar() { + return &CommandsConfig[0]; +} + +CFGSTRUCT* _FIXME_GetInputConfigVar() { + return &InputConfig[0]; +} diff --git a/trunk/src/drivers/win/input.h b/trunk/src/drivers/win/input.h index b60b1ddf..c96056d3 100644 --- a/trunk/src/drivers/win/input.h +++ b/trunk/src/drivers/win/input.h @@ -1,73 +1,99 @@ +/* + NOTE: for purposes of this header and related source files, "gamepad" is + an internal emulated NES/Famicom device, and actual hardware devices are + referred to as "joysticks" +*/ + #ifndef WIN_INPUT_H -#define WIN_INPU_H +#define WIN_INPUT_H -#include "dinput.h" - -#define CMD_KEY_MASK 0xff -#define CMD_KEY_LSHIFT (1<<16) -#define CMD_KEY_RSHIFT (1<<17) -#define CMD_KEY_SHIFT (CMD_KEY_LSHIFT|CMD_KEY_RSHIFT) -#define CMD_KEY_LCTRL (1<<18) -#define CMD_KEY_RCTRL (1<<19) -#define CMD_KEY_CTRL (CMD_KEY_LCTRL|CMD_KEY_RCTRL) -#define CMD_KEY_LALT (1<<20) -#define CMD_KEY_RALT (1<<21) -#define CMD_KEY_ALT (CMD_KEY_LALT|CMD_KEY_RALT) - -void ConfigInput(HWND hParent); -int InitDInput(void); -void CreateInputStuff(void); -void InitInputStuff(void); -void DestroyInput(void); -void InputScreenChanged(int fs); // FIXME defined nowhere used nowhere -void SetAutoFireDesynch(int DesynchOn); -int GetAutoFireDesynch(); -uint32 GetGamepadPressedImmediate(); -void UpdateRawInputAndHotkeys(); - -extern LPDIRECTINPUT7 lpDI; - -extern int InputType[3]; -//extern int UsrInputType[3]; -extern int cidisabled; -#ifndef _aosdfjk02fmasf -#define _aosdfjk02fmasf - -#include "../common/args.h" -#include "../common/config.h" +#include "drivers/common/input.h" +#include "drivers/common/args.h" +#include "drivers/common/config.h" #include "../../input.h" -#define MAXBUTTCONFIG 4 -typedef struct { - uint8 ButtType[MAXBUTTCONFIG]; - uint8 DeviceNum[MAXBUTTCONFIG]; - uint16 ButtonNum[MAXBUTTCONFIG]; - uint32 NumC; - GUID DeviceInstance[MAXBUTTCONFIG]; - //uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */ -} ButtConfig; -extern CFGSTRUCT InputConfig[]; -extern ARGPSTRUCT InputArgs[]; -void ParseGIInput(FCEUGI *GameInfo); +// Show input configuration dialog +void ConfigInput(void); -#define BUTTC_KEYBOARD 0x00 -#define BUTTC_JOYSTICK 0x01 -#define BUTTC_MOUSE 0x02 +// Init/Deinit input devices +bool InitInputDriver(void); +void KillInputDriver(void); -#define FCFGD_GAMEPAD 1 -#define FCFGD_POWERPAD 2 -#define FCFGD_HYPERSHOT 3 -#define FCFGD_QUIZKING 4 +// Enable/disable virtual keyboard handling +void SetInputKeyboard(bool on); +bool GetInputKeyboard(void); -void SetEmulationSpeed(int type); -int FCEUD_TestCommandState(int c); -void FCEUD_UpdateInput(); +// Get/set turbo A-B alternation +void SetAutoFireDesynch(bool DesynchOn); +bool GetAutoFireDesynch(void); -extern CFGSTRUCT HotkeyConfig[]; +// U+D, L+R at the same time +bool GetAllowUDLR(void); +void SetAllowUDLR(bool allow); -extern int FCEUD_CommandMapping[EMUCMD_MAX]; +// Get/set keys to add or remove autoholds +int GetAutoholdsAddKey(void); +void SetAutoholdsAddKey(int k); -#endif +int GetAutoholdsClearKey(void); +void SetAutoholdsClearKey(int k); -#endif +// Get autohold masks for four gamepads +// used for input visualization +uint8 const (& GetAutoHoldMask(void))[4]; + +// Get current key configurations for virtual input devices +BtnConfig* GetGamePadConfig(void); +BtnConfig* GetPowerPadConfig(void); +BtnConfig* GetFamiTrainerConfig(void); +BtnConfig* GetFamiKeyBoardConfig(void); +BtnConfig* GetSuborKeyBoardConfig(void); +BtnConfig* GetMahjongConfig(void); +BtnConfig* GetPartyTapConfig(void); + +// Get 'physical' or 'mechanical' state of the gamepad +// Returned state represents state of buttons on the gamepad, rather than +// state of lines on input port (with no autohold/turbo/etc applied) +// Used for recording and input visualization +uint32 GetGamepadPressedPhysical(void); + +// Update input +#define UPDATEINPUT_KEYBOARD (0x1) +#define UPDATEINPUT_JOYSTICKS (0x2) +#define UPDATEINPUT_COMMANDS (UPDATEINPUT_KEYBOARD|0x4) // NOTE also updates keyboard +#define UPDATEINPUT_EVERYTHING (UPDATEINPUT_KEYBOARD|UPDATEINPUT_JOYSTICKS|UPDATEINPUT_COMMANDS|0x8) +void FCEUD_UpdateInput(int flags); + +// Get input ports (types of devices currently plugged in) +ESI GetPluggedIn(int port); +void SetPluggedIn(int port, ESI device); +ESIFC GetPluggedInEx(void); +void SetPluggedInEx(ESIFC device); + + +// Force set input configuration +// FIXME really only need one generalized version +void FCEUD_SetInput(bool fourscore, bool microphone, ESI port0, ESI port1, ESIFC fcexp); +void FCEUD_SetInput(ESI port0, ESI port1, ESIFC fcexp); + +// FIXME bloature +// Use of unified and abstract configuration facility is strongly +// recommended for all config-related imports/exports. +// Moving presets mechanisms off of driver layer is recommended. +void CopyConfigToPreset(unsigned int presetIdx); +void PresetExport(int presetNum); +void PresetImport(int presetNum); +void FCEUI_UseInputPreset(int preset); + + +// see win/config.h +int (&_FIXME_GetInputPortsArr(void))[3]; +int& _FIXME_GetAddAutoholdsKeyVar(void); +int& _FIXME_GetClearAutoholdsKeyVar(void); +int& _FIXME_GetAllowUDLRVar(void); +int& _FIXME_GetDesynchAutoFireVar(void); +CFGSTRUCT* _FIXME_GetCommandsConfigVar(void); +CFGSTRUCT* _FIXME_GetInputConfigVar(void); + +#endif // WIN_INPUT_H diff --git a/trunk/src/drivers/win/inputConfigUI.cpp b/trunk/src/drivers/win/inputConfigUI.cpp new file mode 100644 index 00000000..d6545dcd --- /dev/null +++ b/trunk/src/drivers/win/inputConfigUI.cpp @@ -0,0 +1,747 @@ +/* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + Input configuration UI - Windows implementation +*/ + +#define _WIN32_IE 0x0550 +#include +#include + +#include +#include + +#include "inputConfigUI.h" +#include "drivers/win/common.h" +#include "drivers/win/window.h" +#include "drivers/win/input.h" +#include "drivers/win/joystick.h" +#include "drivers/win/gui.h" +#include "utils/bitflags.h" +#include "../../movie.h" +#include "../../version.h" +#include "../../input/gamepad.h" +#include "../../input/fkb.h" +#include "../../input/suborkb.h" + + +// main +#define KEY_MASK_SCANCODE 0xFF0000 +#define KEY_MASK_EXTBIT 0x1000000 +#define BTNNUM_TO_WINCODE(num) (((num << 16) & KEY_MASK_SCANCODE) | ((num << 17) & KEY_MASK_EXTBIT)) +#define WINCODE_TO_BTNNUM(cod) (((cod & KEY_MASK_SCANCODE) >> 16) | ((cod & KEY_MASK_EXTBIT) >> 17)) +const unsigned int NUMBER_OF_PORTS = 2; // number of (normal) input ports +// which input devices can be configured +static const BOOL configurable_nes[SI_COUNT + 1] = { FALSE, TRUE, FALSE, TRUE, TRUE, FALSE }; +static const BOOL configurable_fam[SIFC_COUNT + 1] = { FALSE,FALSE,FALSE,FALSE, TRUE,TRUE,TRUE,FALSE, TRUE,TRUE,TRUE,TRUE, FALSE,FALSE,FALSE }; +HWND hwndMainDlg; + +// device config +static BtnConfig *DeviceConfigButtons = 0; +static const char *DeviceConfigTitle = 0; +static int DeviceConfigButtonsCount = 0; +static int VirtualDeviceType = 0; +static int VirtualDevicePort = 0; + +// button config +static HWND hwndNormalDlg; +static BtnConfig dummy_; +static BtnConfig* targetBtnCfg = NULL; +#define WM_USER_SIMPLEKEYDOWN (WM_USER + 666) +#define ID_TIMER (666) +HWND hwndNormalDlgParent; + +// simplified button config +HWND hwndSimplifiedDlg; +HWND hwndSimplifiedDlgParent; + +static void UpdateComboPad(HWND dlg, WORD id) +{ + unsigned int sel_input = id - COMBO_PAD1; + + // Update the user input type + SetPluggedIn(sel_input, (ESI)SendDlgItemMessage( + dlg, + id, + CB_GETCURSEL, + 0, + (LPARAM)(LPSTR)0 + )); + + // Enable or disable the configuration button + EnableWindow( + GetDlgItem(dlg, id + 2), + configurable_nes[GetPluggedIn(sel_input)] + ); + + // Update the text field + SetDlgItemText( + dlg, + TXT_PAD1 + sel_input, + (LPTSTR)ESI_Name(GetPluggedIn(sel_input)) + ); +} + +static void UpdateFourscoreState(HWND dlg) +{ + //(inverse logic:) + BOOL enable = (eoptions & EO_FOURSCORE)?FALSE:TRUE; + + EnableWindow(GetDlgItem(dlg,BTN_PORT1),enable); + EnableWindow(GetDlgItem(dlg,BTN_PORT2),enable); + EnableWindow(GetDlgItem(dlg,COMBO_PAD1),enable); + EnableWindow(GetDlgItem(dlg,COMBO_PAD2),enable); + EnableWindow(GetDlgItem(dlg,TXT_PAD1),enable); + EnableWindow(GetDlgItem(dlg,TXT_PAD2),enable); + + if(!enable) { + //change the inputs to gamepad + SendMessage(GetDlgItem(dlg,COMBO_PAD1),CB_SETCURSEL,SI_GAMEPAD,0); + SendMessage(GetDlgItem(dlg,COMBO_PAD2),CB_SETCURSEL,SI_GAMEPAD,0); + UpdateComboPad(dlg,COMBO_PAD1); + UpdateComboPad(dlg,COMBO_PAD2); + SetDlgItemText(dlg,TXT_PAD1,ESI_Name(SI_GAMEPAD)); + SetDlgItemText(dlg,TXT_PAD2,ESI_Name(SI_GAMEPAD)); + } +} + +static void UpdateComboFam(HWND dlg) +{ + // Update the user input type of the famicom + SetPluggedInEx((ESIFC)SendDlgItemMessage( + dlg, + COMBO_FAM, + CB_GETCURSEL, + 0, + (LPARAM)(LPSTR)0 + )); + + // Enable or disable the configuration button + EnableWindow( + GetDlgItem(dlg, BTN_FAM), + configurable_fam[GetPluggedInEx()] + ); + + // Update the text field + SetDlgItemText( + dlg, + TXT_FAM, + (LPTSTR)ESIFC_Name(GetPluggedInEx()) + ); +} + + +static void MakeButtString(const BtnConfig& btnCfg, std::string& outstr) +{ + std::stringstream strstr; + for(uint32 btnIdx=0; btnIdx 0) strstr << ", "; + + if(btnCfg.ButtType[btnIdx] == BtnConfig::BT_KEYBOARD) { + strstr << "KB: "; + char keyname[16]; + if(GetKeyNameText(BTNNUM_TO_WINCODE(btnCfg.GetScanCode(btnIdx)), keyname, 16)) { + strstr << keyname; + } + else { + // GetKeyNameText wasn't able to provide a name for the key, then just show scancode + strstr << std::right << std::setw(3) << btnCfg.GetScanCode(btnIdx); + } + } + else if(btnCfg.ButtType[btnIdx] == BtnConfig::BT_JOYSTICK) { + strstr << "JS " << ((unsigned int)btnCfg.DeviceNum[btnIdx]); + if(btnCfg.IsAxisButton(btnIdx)) { + char *asel[3]={"x","y","z"}; + strstr << " axis " << asel[btnCfg.GetAxisIdx(btnIdx)] << (btnCfg.IsAxisNegative(btnIdx)? "-":"+"); + } + else if(btnCfg.IsPovButton(btnIdx)) { + strstr << " hat " << ((int)btnCfg.GetPovController(btnIdx)) << ':' << ((int)btnCfg.GetPovDir(btnIdx)); + } + else { + strstr << " button " << ((int)btnCfg.GetJoyButton(btnIdx)); + } + } + } + + outstr = strstr.str(); +} + +static void SetDlgButtonsString(HWND dlg, int textID, const BtnConfig& btnCfg) +{ + std::string str; + MakeButtString(btnCfg, str); + SetDlgItemText(dlg, textID, str.c_str()); +} + +static BOOL CALLBACK ButtonConfigDialogProc(HWND dlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static bool isFirstButton = true; + bool closeDlg = false; + + switch(uMsg) { + case WM_DESTROY: + hwndNormalDlg = NULL; + break; + case WM_TIMER: + { + JOYINSTANCEID guid; + uint8 devicenum; + uint16 buttonnum; + + if(driver::input::joystick::GetButtonPressedTest(&guid, &devicenum, &buttonnum)) { + // Got button pressed + if(isFirstButton) { + targetBtnCfg->NumC = 0; + isFirstButton = false; + } + int btnIdx = targetBtnCfg->NumC; + targetBtnCfg->ButtType[btnIdx] = BtnConfig::BT_JOYSTICK; + targetBtnCfg->DeviceNum[btnIdx] = devicenum; + targetBtnCfg->AssignJoyButton(btnIdx, buttonnum); + targetBtnCfg->DeviceInstance[btnIdx] = guid; + + // Stop config if the user pushes the same button twice in a row. + if(btnIdx && + targetBtnCfg->ButtType[btnIdx] == targetBtnCfg->ButtType[btnIdx-1] && + targetBtnCfg->DeviceNum[btnIdx] == targetBtnCfg->DeviceNum[btnIdx-1] && + targetBtnCfg->ButtonNum[btnIdx] == targetBtnCfg->ButtonNum[btnIdx-1]) + { + closeDlg = true; + } + else { + targetBtnCfg->NumC++; + + // Stop config if we reached our maximum button limit. + if(targetBtnCfg->NumC >= MAXBUTTCONFIG) closeDlg = true; + + SetDlgButtonsString(dlg, LBL_DWBDIALOG_TEXT, *targetBtnCfg); + } + } + } + break; + case WM_USER_SIMPLEKEYDOWN: + // received button press via windows message + if(isFirstButton) { + targetBtnCfg->NumC = 0; + isFirstButton = false; + + SetDlgButtonsString(dlg, LBL_DWBDIALOG_TEXT, *targetBtnCfg); + } + + { + int btnIdx = targetBtnCfg->NumC; + + targetBtnCfg->ButtType[btnIdx] = BtnConfig::BT_KEYBOARD; + targetBtnCfg->DeviceNum[btnIdx] = 0; + targetBtnCfg->AssignScanCode(btnIdx, lParam & 0xFF); + + //Stop config if the user pushes the same button twice in a row. + if(btnIdx && + targetBtnCfg->ButtType[btnIdx]==targetBtnCfg->ButtType[btnIdx-1] && + targetBtnCfg->DeviceNum[btnIdx]==targetBtnCfg->DeviceNum[btnIdx-1] && + targetBtnCfg->ButtonNum[btnIdx]==targetBtnCfg->ButtonNum[btnIdx-1]) + { + closeDlg = true; + } + else { + targetBtnCfg->NumC++; + //Stop config if we reached our maximum button limit. + if(targetBtnCfg->NumC >= MAXBUTTCONFIG) closeDlg = true; + + SetDlgButtonsString(dlg, LBL_DWBDIALOG_TEXT, *targetBtnCfg); + } + } + break; + case WM_INITDIALOG: + isFirstButton = true; + + driver::input::joystick::BeginWaitButton(dlg); + SetTimer(dlg, ID_TIMER, 25, 0); //Every 25ms. + + SetDlgButtonsString(dlg, LBL_DWBDIALOG_TEXT, *targetBtnCfg); + break; + case WM_CLOSE: + case WM_QUIT: + closeDlg = true; + break; + case WM_COMMAND: + switch(wParam & 0xFFFF) { + case BTN_CLEAR: + { + // clear configuration + targetBtnCfg->NumC = 0; + + SetDlgButtonsString(dlg, LBL_DWBDIALOG_TEXT, *targetBtnCfg); + } + break; + case BTN_CLOSE: + closeDlg = true; + break; + } + } + + if(closeDlg) { + KillTimer(dlg, ID_TIMER); + driver::input::joystick::EndWaitButton(hAppWnd); + SetForegroundWindow(GetParent(dlg)); + DestroyWindow(dlg); + } + + return 0; +} + +static void DoButtonConfigDlg(const uint8 *title, BtnConfig& bc) { + targetBtnCfg = &bc; + + hwndNormalDlg = CreateDialog(fceu_hInstance, "DWBDIALOG", hwndNormalDlgParent, ButtonConfigDialogProc); + EnableWindow(hwndNormalDlgParent, FALSE); + SetWindowText(hwndNormalDlg, (char*)title); + ShowWindow(hwndNormalDlg, SW_SHOWNORMAL); + + while(hwndNormalDlg) { + MSG msg; + while(PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) { + if(GetMessage(&msg, 0, 0, 0) > 0) { + if(msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN) { + PostMessage(hwndNormalDlg, WM_USER_SIMPLEKEYDOWN, 0, WINCODE_TO_BTNNUM(msg.lParam)); + continue; + } + + if(msg.message == WM_SYSCOMMAND) continue; + + if(!IsDialogMessage(hwndNormalDlg, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + Sleep(10); + } + + EnableWindow(hwndNormalDlgParent, TRUE); +} + + +static BOOL CALLBACK VirtualDeviceConfigProc(HWND dlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + bool closeDlg = false; + + switch(uMsg) { + case WM_INITDIALOG: + SetWindowText(dlg, DeviceConfigTitle); + if(VirtualDeviceType == SI_GAMEPAD) { + // assign labels for two gamepads + char buf[32]; + sprintf(buf, "Virtual Gamepad %d", VirtualDevicePort+1); + SetDlgItemText(dlg, GRP_GAMEPAD1, buf); + + sprintf(buf, "Virtual Gamepad %d", VirtualDevicePort+3); + SetDlgItemText(dlg, GRP_GAMEPAD2, buf); + } + break; + case WM_CLOSE: + case WM_QUIT: + closeDlg = true; + break; + case WM_COMMAND: + { + int ctrlId = LOWORD(wParam); + int configIdx = ctrlId - 300; + if(configIdx >= 0 && configIdx < DeviceConfigButtonsCount) { + char btnText[128]; + btnText[0] = '\0'; + GetDlgItemText(dlg, ctrlId, btnText, 128); + hwndNormalDlgParent = dlg; + DoButtonConfigDlg((uint8*)btnText, DeviceConfigButtons[configIdx]); + } + else switch(LOWORD(wParam)) { + case BTN_CLOSE: + closeDlg = true; + break; + } + } + } + + if(closeDlg) EndDialog(dlg, 0); + + return 0; +} + +static void DoVirtualDeviceConfigDlg(const char *title, char *dlgTemplate, BtnConfig *buttons, int buttonsCount) { + DeviceConfigTitle = title; + DeviceConfigButtons = buttons; + DeviceConfigButtonsCount = buttonsCount; + DialogBox(fceu_hInstance, dlgTemplate, hwndMainDlg, VirtualDeviceConfigProc); +} + + +static int DoSimplifiedButtonConfigDlg(const uint8* title) { + int btnCode = 0; + + hwndSimplifiedDlg = CreateDialog(fceu_hInstance, "DWBDIALOGSIMPLE", hwndSimplifiedDlgParent, NULL); + EnableWindow(hwndSimplifiedDlgParent, 0); + SetWindowText(hwndSimplifiedDlg, (char*)title); + ShowWindow(hwndSimplifiedDlg, SW_SHOWNORMAL); + + while(hwndSimplifiedDlg) { + MSG msg; + while(PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) { + if(GetMessage(&msg, 0, 0, 0) > 0) { + if(msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN) { + btnCode = WINCODE_TO_BTNNUM(msg.lParam); + if(btnCode == 1) btnCode = 0; // convert Esc to nothing + goto done; + } + + if(msg.message == WM_SYSCOMMAND) continue; + + if(!IsDialogMessage(hwndSimplifiedDlg, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + Sleep(10); + } + +done: + EndDialog(hwndSimplifiedDlg, NULL); + EnableWindow(hwndSimplifiedDlgParent, TRUE); + + return btnCode; +} + + +// Main input configuration dialog proc +static BOOL CALLBACK ConfigInputDialogProc(HWND dlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + hwndMainDlg = dlg; + + switch(uMsg) { + case WM_INITDIALOG: + // Update the disable UDLR checkbox based on the current value + CheckDlgButton(dlg, BTN_ALLOW_LRUD, (GetAllowUDLR())? BST_CHECKED:BST_UNCHECKED); + + //update the fourscore checkbox + CheckDlgButton(dlg, CHECK_ENABLE_FOURSCORE, FL_TEST(eoptions, EO_FOURSCORE)? BST_CHECKED:BST_UNCHECKED); + + //update the microphone checkbox + CheckDlgButton(dlg, CHECK_ENABLE_MICROPHONE, FCEUI_GetInputMicrophone()? BST_CHECKED:BST_UNCHECKED); + + // Initialize the controls for the input ports + for(unsigned int port = 0; port < NUMBER_OF_PORTS; port++) { + // Initialize the combobox + for(unsigned int current_device = 0; current_device < SI_COUNT + 1; ++current_device) { + SendDlgItemMessage(dlg, + COMBO_PAD1 + port, + CB_ADDSTRING, + 0, + (LPARAM)ESI_Name((ESI)current_device) + ); + } + + // Fix to deal with corrupted config. + if (GetPluggedIn(port)>SI_COUNT || GetPluggedIn(port)<0) + SetPluggedIn(port, SI_UNSET); + + // Update the combobox selection according to the + // currently selected input mode. + SendDlgItemMessage(dlg, + COMBO_PAD1 + port, + CB_SETCURSEL, + GetPluggedIn(port), + (LPARAM)0 + ); + + // Enable the configuration button if necessary. + EnableWindow( + GetDlgItem(dlg, BTN_PORT1 + port), + configurable_nes[GetPluggedIn(port)] + ); + + // Update the label that displays the input device. + SetDlgItemText( + dlg, + TXT_PAD1 + port, + (LPTSTR)ESI_Name(GetPluggedIn(port)) + ); + } + + // Initialize the Famicom combobox + for(unsigned current_device = 0; current_device < SIFC_COUNT + 1; ++current_device) { + SendDlgItemMessage( + dlg, + COMBO_FAM, + CB_ADDSTRING, + 0, + (LPARAM)(LPSTR)ESIFC_Name((ESIFC)current_device) + ); + } + + if (GetPluggedInEx()>SIFC_COUNT || GetPluggedInEx()<0) { + SetPluggedInEx(SIFC_UNSET); + } + + // Update the combobox selection according to the + // currently selected input mode. + SendDlgItemMessage( + dlg, + COMBO_FAM, + CB_SETCURSEL, + GetPluggedInEx(), + (LPARAM)0 + ); + + // Enable the configuration button if necessary. + EnableWindow( + GetDlgItem(dlg, BTN_FAM), + configurable_fam[GetPluggedInEx()] + ); + + // Update the label that displays the input device. + SetDlgItemText( + dlg, + TXT_FAM, + (LPTSTR)ESIFC_Name(GetPluggedInEx()) + ); + + { + // Initialize the auto key controls + char btext[128]; + if(GetAutoholdsAddKey() != 0) { + if(!GetKeyNameText(BTNNUM_TO_WINCODE(GetAutoholdsAddKey()), btext, 128)) { + sprintf(btext, "KB: %d", GetAutoholdsAddKey()); + } + } + else { + sprintf(btext, "not assigned"); + } + SetDlgItemText(dlg, LBL_AUTO_HOLD, btext); + + if(GetAutoholdsClearKey() != 0) { + if(!GetKeyNameText(BTNNUM_TO_WINCODE(GetAutoholdsClearKey()), btext, 128)) { + sprintf(btext, "KB: %d", GetAutoholdsClearKey()); + } + } + else { + sprintf(btext, "not assigned"); + } + SetDlgItemText(dlg, LBL_CLEAR_AH, btext); + } + + CenterWindowOnScreen(dlg); + UpdateFourscoreState(dlg); + + if (!FCEUMOV_Mode(MOVIEMODE_INACTIVE)) { + // disable changing fourscore and Input ports while a movie is recorded/played + EnableWindow(GetDlgItem(dlg, CHECK_ENABLE_FOURSCORE), FALSE); + EnableWindow(GetDlgItem(dlg, CHECK_ENABLE_MICROPHONE), FALSE); + EnableWindow(GetDlgItem(dlg, COMBO_PAD1), FALSE); + EnableWindow(GetDlgItem(dlg, COMBO_PAD2), FALSE); + EnableWindow(GetDlgItem(dlg, COMBO_FAM), FALSE); + } + + break; + + case WM_CLOSE: + case WM_QUIT: + EndDialog(dlg, 0); + break; + + case WM_COMMAND: + if(HIWORD(wParam) == CBN_SELENDOK) { + switch(LOWORD(wParam)) { + case COMBO_PAD1: + case COMBO_PAD2: + UpdateComboPad(dlg, LOWORD(wParam)); + break; + + case COMBO_FAM: + UpdateComboFam(dlg); + break; + } + } + else if( HIWORD(wParam) == BN_CLICKED ) { + switch(LOWORD(wParam)) { + case BTN_ALLOW_LRUD: + SetAllowUDLR(!GetAllowUDLR()); + FCEU_printf("Allow UDLR toggled.\n"); + break; + case CHECK_ENABLE_FOURSCORE: + FL_FROMBOOL(eoptions, EO_FOURSCORE, !FL_TEST(eoptions, EO_FOURSCORE)); + FCEU_printf("Fourscore toggled to %s\n",(eoptions & EO_FOURSCORE)?"ON":"OFF"); + UpdateFourscoreState(dlg); + break; + case CHECK_ENABLE_MICROPHONE: + FCEUI_SetInputMicrophone(!FCEUI_GetInputMicrophone()); + FCEU_printf("Microphone toggled to %s\n", FCEUI_GetInputMicrophone()? "ON":"OFF"); + break; + case BTN_FAM: + { + const char *text = ESIFC_Name(GetPluggedInEx()); + + VirtualDeviceType = VirtualDevicePort = 0; + + switch(GetPluggedInEx()) + { + case SIFC_FTRAINERA: + case SIFC_FTRAINERB: + DoVirtualDeviceConfigDlg(text, "POWERPADDIALOG", GetFamiTrainerConfig(), 12); + break; + case SIFC_FKB: + DoVirtualDeviceConfigDlg(text, "FKBDIALOG", GetFamiKeyBoardConfig(), NUMKEYS_FAMIKB); + break; + case SIFC_PEC586KB: + case SIFC_SUBORKB: + DoVirtualDeviceConfigDlg(text, "SUBORKBDIALOG", GetSuborKeyBoardConfig(), NUMKEYS_SUBORKB); + break; + case SIFC_MAHJONG: + DoVirtualDeviceConfigDlg(text, "MAHJONGDIALOG", GetMahjongConfig(), 21); + break; + case SIFC_PARTYTAP: + DoVirtualDeviceConfigDlg(text, "PARTYTAPDIALOG", GetPartyTapConfig(), 6); + break; + } + } + + break; + + case BTN_PORT2: + case BTN_PORT1: + { + int which = LOWORD(wParam) - BTN_PORT1; + const char *text = ESI_Name(GetPluggedIn(which)); + + VirtualDeviceType = VirtualDevicePort = 0; + + switch(GetPluggedIn(which)) { + case SI_GAMEPAD: + { + BtnConfig tmp[GPAD_NUMKEYS*2]; // reserve room for two gpad configs + BtnConfig* target = GetGamePadConfig() + (which * GPAD_NUMKEYS); + + uint32 count = GPAD_NUMKEYS * sizeof(BtnConfig); + memcpy(tmp, target, count); // 1st to cinfigure (gpad 0 or 1) + memcpy(tmp + GPAD_NUMKEYS, target + GPAD_NUMKEYS * 2, count); // 2nd to configure (gpad 2 or 3) + + VirtualDeviceType = SI_GAMEPAD; + VirtualDevicePort = which; + DoVirtualDeviceConfigDlg(text, "GAMEPADDIALOG", tmp, GPAD_NUMKEYS*2); + + memcpy(target, tmp, count); // copy back first set to 0/1 + memcpy(target + GPAD_NUMKEYS * 2, tmp + GPAD_NUMKEYS, count); // copy back second set to gpad 2/3 + } + break; + + case SI_POWERPADA: + case SI_POWERPADB: + DoVirtualDeviceConfigDlg(text, "POWERPADDIALOG", &(GetPowerPadConfig()[which]), 12); + break; + } + } + + break; + + case BTN_PRESET_SET1: + MessageBox(0, "Current input configuration has been set as Preset 1.", FCEU_NAME, MB_ICONINFORMATION | MB_OK | MB_SETFOREGROUND | MB_TOPMOST); + CopyConfigToPreset(0); + break; + case BTN_PRESET_SET2: + MessageBox(0, "Current input configuration has been set as Preset 2.", FCEU_NAME, MB_ICONINFORMATION | MB_OK | MB_SETFOREGROUND | MB_TOPMOST); + CopyConfigToPreset(1); + break; + case BTN_PRESET_SET3: + MessageBox(0, "Current input configuration has been set as Preset 3.", FCEU_NAME, MB_ICONINFORMATION | MB_OK | MB_SETFOREGROUND | MB_TOPMOST); + CopyConfigToPreset(2); + break; + + case BTN_PRESET_EXPORT1: PresetExport(1); break; + case BTN_PRESET_EXPORT2: PresetExport(2); break; + case BTN_PRESET_EXPORT3: PresetExport(3); break; + + case BTN_PRESET_IMPORT1: PresetImport(1); break; + case BTN_PRESET_IMPORT2: PresetImport(2); break; + case BTN_PRESET_IMPORT3: PresetImport(3); break; + + case BTN_AUTO_HOLD: // auto-hold button + { + char btext[128] = { 0 }; + + GetDlgItemText(dlg, BTN_AUTO_HOLD, btext, sizeof(btext) ); + + hwndSimplifiedDlgParent = dlg; + int button = DoSimplifiedButtonConfigDlg((uint8*)btext); + + if(button) { + if(!GetKeyNameText(BTNNUM_TO_WINCODE(button), btext, 128)) { + sprintf(btext, "KB: %d", button); + } + } + else { + sprintf(btext, "not assigned"); + } + SetDlgItemText(dlg, LBL_AUTO_HOLD, btext); + + SetAutoholdsAddKey(button); + } + break; + + case BTN_CLEAR_AH: // auto-hold clear button + { + char btext[128] = { 0 }; + + GetDlgItemText(dlg, BTN_CLEAR_AH, btext, 128); + + hwndSimplifiedDlgParent = dlg; + int button = DoSimplifiedButtonConfigDlg((uint8*)btext); + + if(button) { + if( !GetKeyNameText(BTNNUM_TO_WINCODE(button), btext, sizeof(btext))) { + sprintf(btext, "KB: %d", button); + } + } + else { + sprintf(btext, "not assigned"); + } + SetDlgItemText(dlg, LBL_CLEAR_AH, btext); + + SetAutoholdsClearKey(button); + } + break; + + case BTN_CLOSE: + EndDialog(dlg, 0); + break; + } + } + } + + return 0; +} + + + + + + +void driver::input::ui::RootDialog() { + DialogBox(fceu_hInstance, "INPUTCONFIG", GetMainHWND(), ConfigInputDialogProc); +} diff --git a/trunk/src/drivers/win/inputConfigUI.h b/trunk/src/drivers/win/inputConfigUI.h new file mode 100644 index 00000000..cd170f09 --- /dev/null +++ b/trunk/src/drivers/win/inputConfigUI.h @@ -0,0 +1,18 @@ +/* Common input configuration ui interface */ + +#ifndef INPUTCONFIGUI_H +#define INPUTCONFIGUI_H + +#include "drivers/common/input.h" + + +namespace driver { +namespace input { +namespace ui { + // Bring up input config root dialog + void RootDialog(void); +}; +}; +}; + +#endif // INPUTCONFIGUI_H diff --git a/trunk/src/drivers/win/inputDevKeyMap.h b/trunk/src/drivers/win/inputDevKeyMap.h new file mode 100644 index 00000000..0ae1015c --- /dev/null +++ b/trunk/src/drivers/win/inputDevKeyMap.h @@ -0,0 +1,123 @@ +/* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef INPUTDEVKEYMAP_H +#define INPUTDEVKEYMAP_H + +#define GPAD_NOCFG() {{{BtnConfig::BT_UNSET},{0},{0},0}, {{BtnConfig::BT_UNSET},{0},{0},0}, {{BtnConfig::BT_UNSET},{0},{0},0}, {{BtnConfig::BT_UNSET},{0},{0},0}} +#define MK(key) {{BtnConfig::BT_KEYBOARD},{0},{SCANCODE(key)},1} // make config from key id + +#define MC(scancode) {{BtnConfig::BT_KEYBOARD},{0},{scancode},1} // make config from scan code + // FIXME encourages use of hardcoded values, remove; + // if the key has no ID in keyscan.h we should not use it + +static BtnConfig GamePadConfig[GPAD_COUNT][GPAD_NUMKEYS] = { + //Gamepad 1 + { + MK(F), // A + MK(D), // B + MK(S), // select + MK(ENTER), // start + MK(BL_CURSORUP), MK(BL_CURSORDOWN),MK(BL_CURSORLEFT),MK(BL_CURSORRIGHT) + }, + + //Gamepad 2 + GPAD_NOCFG(), + + //Gamepad 3 + GPAD_NOCFG(), + + //Gamepad 4 + GPAD_NOCFG() +}; + +static BtnConfig PowerPadConfig[2][NUMKEYS_POWERPAD]={ + { + 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 BtnConfig FamiKeyBoardConfig[NUMKEYS_FAMIKB]= +{ + 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(TILDE),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(BL_DELETE), + MK(BL_END), + MK(BL_PAGEDOWN), + MK(BL_CURSORUP),MK(BL_CURSORLEFT),MK(BL_CURSORRIGHT),MK(BL_CURSORDOWN) +}; + +// FIXME uses codes not listed in our keyscan.h +static BtnConfig SuborKeyBoardConfig[NUMKEYS_SUBORKB]= +{ + MK(ESCAPE),MK(F1),MK(F2),MK(F3),MK(F4),MK(F5),MK(F6),MK(F7),MK(F8),MK(F9),MK(F10),MK(F11),MK(F12),MK(NUMLOCK), + MK(TILDE),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(BACKSPACE),MC(0xd2/*INS*/),MC(0xc7/*HOME*/),MC(0xc9/*NUM9*/),MK(PAUSE), + MC(0xb5/*NUM/*/),MK(ASTERISK),MK(KP_MINUS), + MK(TAB),MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y),MK(U),MK(I),MK(O),MK(P),MK(BRACKET_LEFT),MK(BRACKET_RIGHT),MK(ENTER),MC(0xd3/*NUM.*/),MC(0xca/*???*/),MC(0xd1/*NUM3*/),MK(HOME),MK(CURSORUP),MK(PAGEUP),MK(KP_PLUS), + MK(CAPSLOCK),MK(A),MK(S),MK(D),MK(F),MK(G),MK(H),MK(J),MK(K),MK(L),MK(SEMICOLON),MK(APOSTROPHE),MK(CURSORLEFT),MK(CENTER),MK(CURSORRIGHT), + MK(LEFTSHIFT),MK(Z),MK(X),MK(C),MK(V),MK(B),MK(N),MK(M),MK(COMMA),MK(PERIOD),MK(SLASH),MK(BACKSLASH),MC(0xc8/*NUM8*/),MK(END),MK(CURSORDOWN),MK(PAGEDOWN), + MK(LEFTCONTROL),MK(LEFTALT),MK(SPACE),MC(0xcb/*NUM4*/),MC(0xd0/*NUM2*/),MC(0xcd/*NUM6*/),MK(INSERT),MK(KP_DELETE),MC(0x00),MC(0x00),MC(0x00),MC(0x00),MC(0x00),MC(0x00) +}; + +static BtnConfig MahjongConfig[NUMKEYS_MAHJONG]= +{ + 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 BtnConfig PartyTapConfig[NUMKEYS_PARTYTAP]= +{ + MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y) +}; + +static BtnConfig TopRiderConfig[NUMKEYS_TOPRIDER]= +{ + MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y),MK(U),MK(I) +}; + +static BtnConfig FamiTrainerConfig[NUMKEYS_FAMITRAINER]= +{ + 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 BtnConfig HyperShotConfig[NUMKEYS_HYPERSHOT]= +{ + MK(Q),MK(W),MK(E),MK(R) +}; + +#endif // INPUTDEVKEYMAP_H diff --git a/trunk/src/drivers/win/joystick.cpp b/trunk/src/drivers/win/joystick.cpp index d1cb0c16..dffba164 100644 --- a/trunk/src/drivers/win/joystick.cpp +++ b/trunk/src/drivers/win/joystick.cpp @@ -20,435 +20,268 @@ #include "common.h" #include "dinput.h" +#include "window.h" #include "input.h" +#include "directinput/directinput.h" #include "joystick.h" +#include "utils/bitflags.h" -#define MAX_JOYSTICKS 32 -static LPDIRECTINPUTDEVICE7 Joysticks[MAX_JOYSTICKS]={0}; -static GUID JoyGUID[MAX_JOYSTICKS]; +#define FPOV_CENTER 16 +#define AXIS_DEADZONE (0x10000) -static int numjoysticks = 0; -static int HavePolled[MAX_JOYSTICKS]; -static int background = 0; -static DIJOYSTATE2 StatusSave[MAX_JOYSTICKS]; -static DIJOYSTATE2 StatusSaveImmediate[MAX_JOYSTICKS]; +typedef struct { + bool x; + bool y; +} AXES_; +static vector axisHelperFlag; + // some temporary flags to handle axes correctly during input config -static int FindByGUID(GUID how) +static int backgroundAccessBits = 0; + + +int driver::input::joystick::Init() { - int x; - - for(x=0; x> 1) + (pov & 1); - pov &= 3; - return(pov); - } - - lowpov = pov % 9000; - if(lowpov < (4500 - 4500 / 2)) - { - pov /= 9000; - } - else if(lowpov > (4500 + 4500/2)) - { - pov /= 9000; - pov = (pov + 1) % 4; - } - else - { - if(!roundpos) pov /= 9000; - else { pov /= 9000; pov = (pov + 1) % 4; } - } - return(pov); + directinput::joystick::ReleaseDevices(); + return 1; } - -typedef struct +void driver::input::joystick::Update() { - LONG MinX; - LONG MaxX; - LONG MinY; - LONG MaxY; - LONG MinZ; - LONG MaxZ; -} POWER_RANGER; - -static POWER_RANGER ranges[MAX_JOYSTICKS]; - -// r=diprg.lMax-diprg.lMin; -// JoyXMax[w]=diprg.lMax-(r>>2); -// JoyXMin[w]=diprg.lMin+(r>>2); - -static int JoyAutoRestore(HRESULT dival,LPDIRECTINPUTDEVICE7 lpJJoy) -{ - switch(dival) - { - case DIERR_INPUTLOST: - case DIERR_NOTACQUIRED: - return(IDirectInputDevice7_Acquire(lpJJoy)==DI_OK); - } - return(0); -} - -/* Called during normal emulator operation, not during button configuration. */ -/* Call before DTestButtonJoy */ -void UpdateJoysticks(void) -{ - memset(HavePolled, 0, sizeof(HavePolled)); -} - -int DTestButtonJoy(ButtConfig *bc) -{ - uint32 x; //mbg merge 7/17/06 changed to uint - - for(x=0;xNumC;x++) - { - HRESULT dival; - int n = bc->DeviceNum[x]; - - if(n == 0xFF) - continue; - - if(bc->ButtType[x] != BUTTC_JOYSTICK) continue; - if(n >= numjoysticks) continue; - - if(!HavePolled[n]) - { - while((dival = IDirectInputDevice7_Poll(Joysticks[n])) != DI_OK) - { - if(dival == DI_NOEFFECT) break; - - if(!JoyAutoRestore(dival,Joysticks[n])) - { - return(0); - } - } - - IDirectInputDevice7_GetDeviceState(Joysticks[n],sizeof(DIJOYSTATE2),&StatusSave[n]); - HavePolled[n] = 1; - } - - if(bc->ButtonNum[x]&0x8000) /* Axis "button" */ - { - int sa = bc->ButtonNum[x]&3; - long source; - - if(sa == 0) source=((int64)StatusSave[n].lX - ranges[n].MinX) * 262144 / - (ranges[n].MaxX - ranges[n].MinX) - 131072; - else if(sa == 1) source=((int64)StatusSave[n].lY - ranges[n].MinY) * 262144 / - (ranges[n].MaxY - ranges[n].MinY) - 131072; - else if(sa == 2) source=((int64)StatusSave[n].lZ - ranges[n].MinZ) * 262144 / - (ranges[n].MaxZ - ranges[n].MinZ) - 131072; - - /* Now, source is of the range -131072 to 131071. Good enough. */ - if(bc->ButtonNum[x] & 0x4000) - { - if(source <= (0 - 262144/4)) - return(1); - } - else - { - if(source >= (262144/4)) - return(1); - } - } - else if(bc->ButtonNum[x]&0x2000) /* Hat "button" */ - { - int wpov = StatusSave[n].rgdwPOV[(bc->ButtonNum[x] >> 4) &3]; - int tpov = bc->ButtonNum[x] & 3; - - if(POVFix(wpov, 0) == tpov || POVFix(wpov, 1) == tpov) - return(1); - } - else /* Normal button */ - { - if(StatusSave[n].rgbButtons[bc->ButtonNum[x] & 127]&0x80) - return(1); - } - - } - - return(0); -} - -static int canax[MAX_JOYSTICKS][3]; - -/* Now the fun configuration test begins. */ -void BeginJoyWait(HWND hwnd) -{ - int n; - - //StatusSave = malloc(sizeof(DIJOYSTATE2) * numjoysticks); - memset(canax, 0, sizeof(canax)); - - for(n=0; n= 65536 && canax[n][0]) - { - *guid = JoyGUID[n]; - *devicenum = n; - *buttonnum = 0x8000 | (0) | ((source < 0) ? 0x4000 : 0); - memcpy(&StatusSave[n], &JoyStatus, sizeof(DIJOYSTATE2)); - canax[n][0] = 0; - return(1); - } else if(abs(source) <= 32768) canax[n][0] = 1; - } - - if(day) - { - source=((int64)JoyStatus.lY - ranges[n].MinY) * 262144 / day - 131072; - psource=((int64)StatusSave[n].lY - ranges[n].MinY) * 262144 / day - 131072; - - if(abs(source) >= 65536 && canax[n][1]) - { - *guid = JoyGUID[n]; - *devicenum = n; - *buttonnum = 0x8000 | (1) | ((source < 0) ? 0x4000 : 0); - memcpy(&StatusSave[n], &JoyStatus, sizeof(DIJOYSTATE2)); - canax[n][1] = 0; - return(1); - } else if(abs(source) <= 32768) canax[n][1] = 1; - } - - if(daz) - { - - - } - - for(x=0; x<4; x++) - { - if(POVFix(JoyStatus.rgdwPOV[x],-1) != FPOV_CENTER && POVFix(StatusSave[n].rgdwPOV[x],-1) == FPOV_CENTER) - { - *guid = JoyGUID[n]; - *devicenum = n; - *buttonnum = 0x2000 | (x<<4) | POVFix(JoyStatus.rgdwPOV[x], -1); - memcpy(&StatusSave[n], &JoyStatus, sizeof(DIJOYSTATE2)); - return(1); - } - } - memcpy(&StatusSave[n], &JoyStatus, sizeof(DIJOYSTATE2)); - } - - return(0); -} - -void EndJoyWait(HWND hwnd) -{ - int n; - - for(n=0; nNumC; x++) - if(bc->ButtType[x] == BUTTC_JOYSTICK) - bc->DeviceNum[x] = FindByGUID(bc->DeviceInstance[x]); -} - -static int GetARange(LPDIRECTINPUTDEVICE7 dev, LONG which, LONG *min, LONG *max) -{ - HRESULT dival; - DIPROPRANGE diprg; - //int r; //mbg merge 7/17/06 removed - - memset(&diprg,0,sizeof(DIPROPRANGE)); - diprg.diph.dwSize=sizeof(DIPROPRANGE); - diprg.diph.dwHeaderSize=sizeof(DIPROPHEADER); - diprg.diph.dwHow=DIPH_BYOFFSET; - diprg.diph.dwObj=which; - dival=IDirectInputDevice7_GetProperty(dev,DIPROP_RANGE,&diprg.diph); - if(dival!=DI_OK) - { - *min = *max = 0; - return(1); - } - *min = diprg.lMin; - *max = diprg.lMax; - return(1); -} - -static BOOL CALLBACK JoystickFound(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) -{ - //HRESULT dival; //mbg merge 7/17/06 removed - int n = numjoysticks; - - //mbg merge 7/17/06 changed: - if(DI_OK != IDirectInput7_CreateDeviceEx(lpDI,lpddi->guidInstance,IID_IDirectInputDevice7,(LPVOID *)&Joysticks[n],0)) - //if(DI_OK != IDirectInput7_CreateDeviceEx(lpDI,&lpddi->guidInstance,&IID_IDirectInputDevice7,(LPVOID *)&Joysticks[n],0)) - - { - FCEU_printf("Device creation of a joystick failed during init.\n"); - return(DIENUM_CONTINUE); - } - - if(DI_OK != IDirectInputDevice7_SetCooperativeLevel(Joysticks[n],*(HWND *)pvRef, (background?DISCL_BACKGROUND:DISCL_FOREGROUND)|DISCL_NONEXCLUSIVE)) - { - FCEU_printf("Cooperative level set of a joystick failed during init.\n"); - IDirectInputDevice7_Release(Joysticks[n]); - return(DIENUM_CONTINUE); - } - - if(DI_OK != IDirectInputDevice7_SetDataFormat(Joysticks[n], &c_dfDIJoystick2)) - { - FCEU_printf("Data format set of a joystick failed during init.\n"); - IDirectInputDevice7_Release(Joysticks[n]); - return(DIENUM_CONTINUE); - } - - GetARange(Joysticks[n], DIJOFS_X, &ranges[n].MinX, &ranges[n].MaxX); - GetARange(Joysticks[n], DIJOFS_Y, &ranges[n].MinY, &ranges[n].MaxY); - GetARange(Joysticks[n], DIJOFS_Z, &ranges[n].MinZ, &ranges[n].MaxZ); - - JoyGUID[numjoysticks] = lpddi->guidInstance; - - if(DI_OK != IDirectInputDevice7_Acquire(Joysticks[n])) - { - //FCEU_printf("Acquire of a joystick failed during init.\n"); - } - - numjoysticks++; - - if(numjoysticks > MAX_JOYSTICKS) return(0); - - return(DIENUM_CONTINUE); -} - -int InitJoysticks(HWND hwnd) -{ - IDirectInput7_EnumDevices(lpDI, DIDEVTYPE_JOYSTICK, JoystickFound, (LPVOID *)&hwnd, DIEDFL_ATTACHEDONLY); - return(1); -} - -static bool curr = false; - - -static void UpdateBackgroundAccess(bool on) -{ - if(curr == on) return; - - curr = on; - - for(int n=0; nisUpdated = false; } } -void JoystickSetBackgroundAccessBit(int bit) -{ - background |= (1<> 1) + (pov & 1); + pov &= 3; + return pov; } -void JoystickSetBackgroundAccess(bool on) -{ - if(on) - JoystickSetBackgroundAccessBit(JOYBACKACCESS_OLDSTYLE); - else - JoystickClearBackgroundAccessBit(JOYBACKACCESS_OLDSTYLE); +// Test if specified system pov value hits desired internal pov range +// If diagonalPass is true, diagonal povs adjanced to targetpov will also pass +// (when pov hat is used as a d-pad, diagonals will trigger both adjanced directions) +static bool IsPovInRange(long syspov, int targetpov, bool diagonalsPass) { + static const int QUARTER = 9000; + static const int EIGHT = QUARTER/2; + static const int SIXTEENTH = EIGHT/2; + + if(povToRange(syspov) == FPOV_CENTER) return false; + + if(povToRange(syspov) == targetpov) return true; // exact hit + + if(diagonalsPass && ( + povToRange(syspov + SIXTEENTH) == targetpov || + povToRange(syspov - SIXTEENTH) == targetpov)) return true; + + return false; +} + +bool driver::input::joystick::TestButton(const BtnConfig *btnConfig) +{ + bool isPressed = false; + + for(uint32 btnIdx=0; btnIdxNumC; btnIdx++) { + directinput::joystick::DEVICE* device = directinput::joystick::GetDevice(btnConfig->DeviceInstance[btnIdx]); + if(device == NULL) continue; + + if(btnConfig->ButtType[btnIdx] != BtnConfig::BT_JOYSTICK) continue; + + if(!device->isUpdated) { + if(!directinput::GetState(device->handle, sizeof(DIJOYSTATE2), &device->state)) { + continue; + } + device->isUpdated = true; + } + + if(btnConfig->IsAxisButton(btnIdx)) { + // Axis + int axisIdx = btnConfig->GetAxisIdx(btnIdx); + LONG rangeBase = device->ranges.base[axisIdx]; + LONG rangeRange = device->ranges.range[axisIdx]; + LONG srcval = (axisIdx == 0)? device->state.lX:device->state.lY; + long val = ((int64)srcval - rangeBase) * 0x40000 / rangeRange - 0x20000; + /* Now, val is of the range -131072 to 131071. Good enough. */ + + if((btnConfig->IsAxisNegative(btnIdx) && val <= -AXIS_DEADZONE) || + (!btnConfig->IsAxisNegative(btnIdx) && val >= AXIS_DEADZONE)) + { + isPressed = true; + break; + } + } + else if(btnConfig->IsPovButton(btnIdx)) { + // POV Hat + int srcpov = device->state.rgdwPOV[btnConfig->GetPovController(btnIdx)]; + int targetDir = btnConfig->GetPovDir(btnIdx); + + if(IsPovInRange(srcpov, targetDir, true)) { + isPressed = true; + break; + } + } + else { + // Button + if(device->state.rgbButtons[btnConfig->GetJoyButton(btnIdx)] & 0x80) { + isPressed = true; + break; + } + } + } + + return isPressed; +} + +/* Now the fun configuration test begins. */ +void driver::input::joystick::BeginWaitButton(PLATFORM_DIALOG_ARGUMENT hwnd) +{ + unsigned int count = directinput::joystick::GetDeviceCount(); + axisHelperFlag.resize(count); + for(unsigned int n=0; nhandle, hwnd, false); + } +} + +int driver::input::joystick::GetButtonPressedTest(JOYINSTANCEID *guid, uint8 *devicenum, uint16 *buttonnum) +{ + unsigned int count = directinput::joystick::GetDeviceCount(); + for(unsigned int devIdx=0; devIdxhandle, sizeof(DIJOYSTATE2), &immediateState)) { + return 0; + } + + // check normal buttons + for(int btnIdx = 0; btnIdx < 128; btnIdx++) { + if((immediateState.rgbButtons[btnIdx] & 0x80) && !(device->state.rgbButtons[btnIdx] & 0x80)) { + // button pressed in immediate state but not in last saved state + *devicenum = devIdx; + *buttonnum = btnIdx; + *guid = device->guid; + memcpy(device->state.rgbButtons, immediateState.rgbButtons, 128); + + return 1; + } + } + memcpy(device->state.rgbButtons, immediateState.rgbButtons, 128); + + // check X, Y axii + long rangeX = device->ranges.range[0]; + if(rangeX != 0) { + long value = ((int64)immediateState.lX - device->ranges.base[0]) * 0x40000 / rangeX - 0x20000; + + if(axisHelperFlag[devIdx].x && abs(value) >= AXIS_DEADZONE) { + // activity on X axis + *guid = device->guid; + *devicenum = devIdx; + *buttonnum = BtnConfig::ISAXIS_MASK | + (0) | + ((value < 0) ? (BtnConfig::ISAXISNEG_MASK):0); + + memcpy(&device->state, &immediateState, sizeof(DIJOYSTATE2)); + axisHelperFlag[devIdx].x = false; + + return 1; + } + else if(abs(value) <= 0x8000) { + axisHelperFlag[devIdx].x = true; + } + } + + long rangeY = device->ranges.range[1]; + if(rangeY != 0) { + long value = ((int64)immediateState.lY - device->ranges.base[1]) * 0x40000 / rangeY - 0x20000; + + if(abs(value) >= AXIS_DEADZONE && axisHelperFlag[devIdx].y) { + // activity on Y axis + *guid = device->guid; + *devicenum = devIdx; + *buttonnum = BtnConfig::ISAXIS_MASK | + (1) | + ((value < 0) ? (BtnConfig::ISAXISNEG_MASK):0); + + memcpy(&device->state, &immediateState, sizeof(DIJOYSTATE2)); + axisHelperFlag[devIdx].y = false; + + return 1; + } + else if(abs(value) <= 0x8000) { + axisHelperFlag[devIdx].y = true; + } + } + + // check POV button + for(int x=0; x<4; x++) { + if(povToRange(immediateState.rgdwPOV[x]) != FPOV_CENTER && povToRange(device->state.rgdwPOV[x]) == FPOV_CENTER) { + *guid = device->guid; + *devicenum = devIdx; + *buttonnum = BtnConfig::ISPOVBTN_MASK | (x<<4) | povToRange(immediateState.rgdwPOV[x]); + memcpy(&device->state, &immediateState, sizeof(DIJOYSTATE2)); + return 1; + } + } + memcpy(&device->state, &immediateState, sizeof(DIJOYSTATE2)); + } + + return 0; +} + +void driver::input::joystick::EndWaitButton(PLATFORM_DIALOG_ARGUMENT hwnd) +{ + unsigned int count = directinput::joystick::GetDeviceCount(); + for(unsigned int n=0; nhandle, hwnd, false); + } +} + + +static void UpdateBackgroundAccess(bool enable) +{ + static bool isEnabled = false; + if(isEnabled != enable) { + isEnabled = enable; + + unsigned int count = directinput::joystick::GetDeviceCount(); + for(unsigned int n=0; nhandle, GetMainHWND(), (backgroundAccessBits!=0)); + directinput::Acquire(device->handle); + } + } +} + +void driver::input::joystick::SetBackgroundAccessBit(driver::input::joystick::BKGINPUT bit) +{ + FL_SET(backgroundAccessBits, 1<= 64; -#define KEY_REPEAT_INITIAL_DELAY ((!notAlternateThrottle) ? (16) : (64)) // must be >= 0 and <= 255 +#ifdef KEYBOARDTRANSFORMER_SPECIFIC +#define KEY_REPEAT_INITIAL_DELAY ((!isSoundEnabled || fps_scale < 64) ? (16) : (64)) // must be >= 0 and <= 255 #define KEY_REPEAT_REPEATING_DELAY (6) // must be >= 1 and <= 255 -#define KEY_JUST_DOWN_DURATION (1) // must be >= 1 and <= 255 // AnS: changed to 1 to disallow unwanted hits of e.g. F1 after pressing Shift+F1 and quickly releasing Shift - for(int i = 0 ; i < 256 ; i++) - if(tk[i]) - if(keys_nr[i] < 255) - keys_nr[i]++; // activate key, and count up for repeat - else - keys_nr[i] = 255 - KEY_REPEAT_REPEATING_DELAY; // oscillate for repeat - else - keys_nr[i] = 0; // deactivate key +static unsigned int keyStatesAutorepeated[driver::input::keyboard::KEYCOUNT] = {0,}; // key states with autorepeat applied +#endif // KEYBOARDTRANSFORMER_SPECIFIC - memcpy(keys,keys_nr,sizeof(keys)); - // key-down detection - for(int i = 0 ; i < 256 ; i++) - if(!keys_nr[i]) - { - keys_jd[i] = 0; - keys_jd_lock[i] = 0; - } - else if(keys_jd_lock[i]) - {} - else if(keys_jd[i] - /*&& (i != 0x2A && i != 0x36 && i != 0x1D && i != 0x38)*/) - { - if(++keys_jd[i] > KEY_JUST_DOWN_DURATION) - { - keys_jd[i] = 0; - keys_jd_lock[i] = 1; - } - } - else - keys_jd[i] = 1; - - // key repeat - for(int i = 0 ; i < 256 ; i++) - if((int)keys[i] >= KEY_REPEAT_INITIAL_DELAY && !(keys[i]%KEY_REPEAT_REPEATING_DELAY)) - keys[i] = 0; - - extern uint8 autoHoldOn, autoHoldReset; - autoHoldOn = autoHoldKey && keys[autoHoldKey] != 0; - autoHoldReset = autoHoldClearKey && keys[autoHoldClearKey] != 0; -} - -unsigned int *GetKeyboard(void) -{ - return(keys); -} -unsigned int *GetKeyboard_nr(void) -{ - return(keys_nr); -} -unsigned int *GetKeyboard_jd(void) -{ - return(keys_jd); -} - -int KeyboardInitialize(void) -{ - if(lpdid) +int driver::input::keyboard::Init() { + if(deviceHandle) return(1); - //mbg merge 7/17/06 changed: - ddrval=IDirectInput7_CreateDeviceEx(lpDI, GUID_SysKeyboard,IID_IDirectInputDevice7, (LPVOID *)&lpdid,0); - //ddrval=IDirectInput7_CreateDeviceEx(lpDI, &GUID_SysKeyboard,&IID_IDirectInputDevice7, (LPVOID *)&lpdid,0); - if(ddrval != DI_OK) + deviceHandle = directinput::CreateDevice(GUID_SysKeyboard); + if(deviceHandle == NULL) { FCEUD_PrintError("DirectInput: Error creating keyboard device."); return 0; } - ddrval=IDirectInputDevice7_SetCooperativeLevel(lpdid, hAppWnd,(background?DISCL_BACKGROUND:DISCL_FOREGROUND)|DISCL_NONEXCLUSIVE); - if(ddrval != DI_OK) + if(!directinput::SetCoopLevel(deviceHandle, GetMainHWND(), (backgroundInputBits!=0))) { FCEUD_PrintError("DirectInput: Error setting keyboard cooperative level."); return 0; } + + directinput::Acquire(deviceHandle); - ddrval=IDirectInputDevice7_SetDataFormat(lpdid,&c_dfDIKeyboard); - if(ddrval != DI_OK) - { - FCEUD_PrintError("DirectInput: Error setting keyboard data format."); - return 0; - } + // any key with scancode not in this list will be ignored + validKeyMask[DIK_ESCAPE] = 1; + validKeyMask[DIK_1] = 1; + validKeyMask[DIK_2] = 1; + validKeyMask[DIK_3] = 1; + validKeyMask[DIK_4] = 1; + validKeyMask[DIK_5] = 1; + validKeyMask[DIK_6] = 1; + validKeyMask[DIK_7] = 1; + validKeyMask[DIK_8] = 1; + validKeyMask[DIK_9] = 1; + validKeyMask[DIK_0] = 1; + validKeyMask[DIK_MINUS] = 1; + validKeyMask[DIK_EQUALS] = 1; + validKeyMask[DIK_BACK] = 1; + validKeyMask[DIK_TAB] = 1; + validKeyMask[DIK_Q] = 1; + validKeyMask[DIK_W] = 1; + validKeyMask[DIK_E] = 1; + validKeyMask[DIK_R] = 1; + validKeyMask[DIK_T] = 1; + validKeyMask[DIK_Y] = 1; + validKeyMask[DIK_U] = 1; + validKeyMask[DIK_I] = 1; + validKeyMask[DIK_O] = 1; + validKeyMask[DIK_P] = 1; + validKeyMask[DIK_LBRACKET] = 1; + validKeyMask[DIK_RBRACKET] = 1; + validKeyMask[DIK_RETURN] = 1; + validKeyMask[DIK_LCONTROL] = 1; + validKeyMask[DIK_A] = 1; + validKeyMask[DIK_S] = 1; + validKeyMask[DIK_D] = 1; + validKeyMask[DIK_F] = 1; + validKeyMask[DIK_G] = 1; + validKeyMask[DIK_H] = 1; + validKeyMask[DIK_J] = 1; + validKeyMask[DIK_K] = 1; + validKeyMask[DIK_L] = 1; + validKeyMask[DIK_SEMICOLON] = 1; + validKeyMask[DIK_APOSTROPHE] = 1; + validKeyMask[DIK_GRAVE] = 1; + validKeyMask[DIK_LSHIFT] = 1; + validKeyMask[DIK_BACKSLASH] = 1; + validKeyMask[DIK_Z] = 1; + validKeyMask[DIK_X] = 1; + validKeyMask[DIK_C] = 1; + validKeyMask[DIK_V] = 1; + validKeyMask[DIK_B] = 1; + validKeyMask[DIK_N] = 1; + validKeyMask[DIK_M] = 1; + validKeyMask[DIK_COMMA] = 1; + validKeyMask[DIK_PERIOD] = 1; + validKeyMask[DIK_SLASH] = 1; + validKeyMask[DIK_RSHIFT] = 1; + validKeyMask[DIK_MULTIPLY] = 1; + validKeyMask[DIK_LMENU] = 1; + validKeyMask[DIK_SPACE] = 1; + validKeyMask[DIK_CAPITAL] = 1; + validKeyMask[DIK_F1] = 1; + validKeyMask[DIK_F2] = 1; + validKeyMask[DIK_F3] = 1; + validKeyMask[DIK_F4] = 1; + validKeyMask[DIK_F5] = 1; + validKeyMask[DIK_F6] = 1; + validKeyMask[DIK_F7] = 1; + validKeyMask[DIK_F8] = 1; + validKeyMask[DIK_F9] = 1; + validKeyMask[DIK_F10] = 1; + validKeyMask[DIK_NUMLOCK] = 1; + validKeyMask[DIK_SCROLL] = 1; + validKeyMask[DIK_NUMPAD7] = 1; + validKeyMask[DIK_NUMPAD8] = 1; + validKeyMask[DIK_NUMPAD9] = 1; + validKeyMask[DIK_SUBTRACT] = 1; + validKeyMask[DIK_NUMPAD4] = 1; + validKeyMask[DIK_NUMPAD5] = 1; + validKeyMask[DIK_NUMPAD6] = 1; + validKeyMask[DIK_ADD] = 1; + validKeyMask[DIK_NUMPAD1] = 1; + validKeyMask[DIK_NUMPAD2] = 1; + validKeyMask[DIK_NUMPAD3] = 1; + validKeyMask[DIK_NUMPAD0] = 1; + validKeyMask[DIK_DECIMAL] = 1; + validKeyMask[DIK_OEM_102] = 1; + validKeyMask[DIK_F11] = 1; + validKeyMask[DIK_F12] = 1; + validKeyMask[DIK_F13] = 1; + validKeyMask[DIK_F14] = 1; + validKeyMask[DIK_F15] = 1; + validKeyMask[DIK_KANA] = 1; + validKeyMask[DIK_ABNT_C1] = 1; + validKeyMask[DIK_CONVERT] = 1; + validKeyMask[DIK_NOCONVERT] = 1; + validKeyMask[DIK_YEN] = 1; + validKeyMask[DIK_ABNT_C2] = 1; + validKeyMask[DIK_NUMPADEQUALS] = 1; + validKeyMask[DIK_PREVTRACK] = 1; + validKeyMask[DIK_AT] = 1; + validKeyMask[DIK_COLON] = 1; + validKeyMask[DIK_UNDERLINE] = 1; + validKeyMask[DIK_KANJI] = 1; + validKeyMask[DIK_STOP] = 1; + validKeyMask[DIK_AX] = 1; + validKeyMask[DIK_UNLABELED] = 1; + validKeyMask[DIK_NEXTTRACK] = 1; + validKeyMask[DIK_NUMPADENTER] = 1; + validKeyMask[DIK_RCONTROL] = 1; + validKeyMask[DIK_MUTE] = 1; + validKeyMask[DIK_CALCULATOR] = 1; + validKeyMask[DIK_PLAYPAUSE] = 1; + validKeyMask[DIK_MEDIASTOP] = 1; + validKeyMask[DIK_VOLUMEDOWN] = 1; + validKeyMask[DIK_VOLUMEUP] = 1; + validKeyMask[DIK_WEBHOME] = 1; + validKeyMask[DIK_NUMPADCOMMA] = 1; + validKeyMask[DIK_DIVIDE] = 1; + validKeyMask[DIK_SYSRQ] = 1; + validKeyMask[DIK_RMENU] = 1; + validKeyMask[DIK_PAUSE] = 1; + validKeyMask[DIK_HOME] = 1; + validKeyMask[DIK_UP] = 1; + validKeyMask[DIK_PRIOR] = 1; + validKeyMask[DIK_LEFT] = 1; + validKeyMask[DIK_RIGHT] = 1; + validKeyMask[DIK_END] = 1; + validKeyMask[DIK_DOWN] = 1; + validKeyMask[DIK_NEXT] = 1; + validKeyMask[DIK_INSERT] = 1; + validKeyMask[DIK_DELETE] = 1; + validKeyMask[DIK_LWIN] = 1; + validKeyMask[DIK_RWIN] = 1; + validKeyMask[DIK_APPS] = 1; + validKeyMask[DIK_POWER] = 1; + validKeyMask[DIK_SLEEP] = 1; + validKeyMask[DIK_WAKE] = 1; + validKeyMask[DIK_WEBSEARCH] = 1; + validKeyMask[DIK_WEBFAVORITES] = 1; + validKeyMask[DIK_WEBREFRESH] = 1; + validKeyMask[DIK_WEBSTOP] = 1; + validKeyMask[DIK_WEBFORWARD] = 1; + validKeyMask[DIK_WEBBACK] = 1; + validKeyMask[DIK_MYCOMPUTER] = 1; + validKeyMask[DIK_MAIL] = 1; + validKeyMask[DIK_MEDIASELECT] = 1; - ////--set to buffered mode - //DIPROPDWORD dipdw; - //dipdw.diph.dwSize = sizeof(DIPROPDWORD); - //dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - //dipdw.diph.dwObj = 0; - //dipdw.diph.dwHow = DIPH_DEVICE; - //dipdw.dwData = 64; - - //ddrval = IDirectInputDevice7_SetProperty(lpdid,DIPROP_BUFFERSIZE, &dipdw.diph); - ////-------- - - ddrval=IDirectInputDevice7_Acquire(lpdid); - /* Not really a fatal error. */ - //if(ddrval != DI_OK) - //{ - // FCEUD_PrintError("DirectInput: Error acquiring keyboard."); - // return 0; - //} return 1; } -static bool curr = false; - - -static void UpdateBackgroundAccess(bool on) +void driver::input::keyboard::Kill() { - if(curr == on) return; + if(deviceHandle) directinput::DestroyDevice(deviceHandle); + deviceHandle = 0; +} - curr = on; - if(!lpdid) - return; +void driver::input::keyboard::Update() +{ + unsigned char deviceState[256]; + bool gotState = directinput::GetState(deviceHandle, sizeof(deviceState), deviceState); - ddrval=IDirectInputDevice7_Unacquire(lpdid); + for(int k = 0 ; k < KEYCOUNT ; ++k) { + if(k < sizeof(deviceState) && validKeyMask[k] && FL_TEST(deviceState[k], 0x80) != 0) { + keyStates[k] = 1; + } + else keyStates[k] = 0; // deactivate key - if(on) - ddrval=IDirectInputDevice7_SetCooperativeLevel(lpdid, hAppWnd,DISCL_BACKGROUND|DISCL_NONEXCLUSIVE); - else - ddrval=IDirectInputDevice7_SetCooperativeLevel(lpdid, hAppWnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE); - if(ddrval != DI_OK) - { - FCEUD_PrintError("DirectInput: Error setting keyboard cooperative level."); - return; + // key-down detection + if(keyStates[k] == 0) { + // key isn't pressed + keyStatesDownEvent[k] = 0; + keys_jd_lock[k] = 0; + } + else if(keys_jd_lock[k] != 0) { + // key was pressed before and already got through its 'down' event + } + else { + // key is entering 'down' state or still in it from before + if(++keyStatesDownEvent[k] > 1) { + keyStatesDownEvent[k] = 0; + keys_jd_lock[k] = 1; + } + } } - ddrval=IDirectInputDevice7_Acquire(lpdid); - return; +#ifdef KEYBOARDTRANSFORMER_SPECIFIC + // autorepeat keys + for(int k = 0 ; k < KEYCOUNT ; ++k) { + if(keyStatesDownEvent[k] != 0) { + // key just went down, set up for repeat + keyStatesAutorepeated[k] = KEY_REPEAT_INITIAL_DELAY; + } + else if(keys_jd_lock[k] != 0) { + // key remains pressed + if(keyStatesAutorepeated[k] > 0) { + --keyStatesAutorepeated[k]; // advance counter + } + else { + keyStatesAutorepeated[k] = KEY_REPEAT_REPEATING_DELAY; // restart counter + } + } + else keyStatesAutorepeated[k] = 0; + } +#endif // KEYBOARDTRANSFORMER_SPECIFIC } -void KeyboardSetBackgroundAccessBit(int bit) -{ - background |= (1<NumC; ++x) { + if(bc->ButtType[x] == BtnConfig::BT_KEYBOARD) { + if(keyStates[bc->GetScanCode(x)]) { + return true; + } + } + } + + return false; } -void KeyboardSetBackgroundAccess(bool on) -{ - if(on) - KeyboardSetBackgroundAccessBit(KEYBACKACCESS_OLDSTYLE); - else - KeyboardClearBackgroundAccessBit(KEYBACKACCESS_OLDSTYLE); +driver::input::keyboard::KeysState_const driver::input::keyboard::GetState() { + return keyStates; +} + +driver::input::keyboard::KeysState_const driver::input::keyboard::GetStateJustPressed() { + return keyStatesDownEvent; +} + +#ifdef KEYBOARDTRANSFORMER_SPECIFIC +unsigned int *GetKeyboardAutorepeated() { + return keyStatesAutorepeated; +} +#endif // KEYBOARDTRANSFORMER_SPECIFIC + + +static void UpdateBackgroundAccess(bool enable) { + if(!deviceHandle) + return; + + static bool bkgModeEnabled = false; + if(bkgModeEnabled != enable) { + bkgModeEnabled = enable; + + if(!directinput::SetCoopLevel(deviceHandle, GetMainHWND(), bkgModeEnabled)) + { + FCEUD_PrintError("DirectInput: Error setting keyboard cooperative level."); + return; + } + + directinput::Acquire(deviceHandle); + } +} + +void driver::input::keyboard::SetBackgroundAccessBit(int bit) +{ + FL_SET(backgroundInputBits, 1< #include "window.h" -void KeyboardUpdateState(void); //mbg merge 7/17/06 yech had to add this struct INPUTDLGTHREADARGS { @@ -18,11 +17,11 @@ struct INPUTDLGTHREADARGS static struct { - int cmd; + EMUCMD cmd; int key; } DefaultCommandMapping[]= { - { EMUCMD_RESET, SCAN_R | CMD_KEY_CTRL, }, + { EMUCMD_RESET, SCAN_R | KeyCombo::CTRL_BIT, }, { EMUCMD_PAUSE, SCAN_PAUSE, }, { EMUCMD_FRAME_ADVANCE, SCAN_BACKSLASH, }, { EMUCMD_SCREENSHOT, SCAN_F12, }, @@ -46,16 +45,16 @@ static struct { EMUCMD_MOVIE_INPUT_DISPLAY_TOGGLE, SCAN_COMMA, }, { EMUCMD_MISC_DISPLAY_LAGCOUNTER_TOGGLE, SCAN_SLASH, }, { EMUCMD_MOVIE_READONLY_TOGGLE, SCAN_Q, }, - { EMUCMD_SAVE_STATE_SLOT_0, SCAN_F10 | CMD_KEY_SHIFT, }, - { EMUCMD_SAVE_STATE_SLOT_1, SCAN_F1 | CMD_KEY_SHIFT, }, - { EMUCMD_SAVE_STATE_SLOT_2, SCAN_F2 | CMD_KEY_SHIFT, }, - { EMUCMD_SAVE_STATE_SLOT_3, SCAN_F3 | CMD_KEY_SHIFT, }, - { EMUCMD_SAVE_STATE_SLOT_4, SCAN_F4 | CMD_KEY_SHIFT, }, - { EMUCMD_SAVE_STATE_SLOT_5, SCAN_F5 | CMD_KEY_SHIFT, }, - { EMUCMD_SAVE_STATE_SLOT_6, SCAN_F6 | CMD_KEY_SHIFT, }, - { EMUCMD_SAVE_STATE_SLOT_7, SCAN_F7 | CMD_KEY_SHIFT, }, - { EMUCMD_SAVE_STATE_SLOT_8, SCAN_F8 | CMD_KEY_SHIFT, }, - { EMUCMD_SAVE_STATE_SLOT_9, SCAN_F9 | CMD_KEY_SHIFT, }, + { EMUCMD_SAVE_STATE_SLOT_0, SCAN_F10 | KeyCombo::SHIFT_BIT, }, + { EMUCMD_SAVE_STATE_SLOT_1, SCAN_F1 | KeyCombo::SHIFT_BIT, }, + { EMUCMD_SAVE_STATE_SLOT_2, SCAN_F2 | KeyCombo::SHIFT_BIT, }, + { EMUCMD_SAVE_STATE_SLOT_3, SCAN_F3 | KeyCombo::SHIFT_BIT, }, + { EMUCMD_SAVE_STATE_SLOT_4, SCAN_F4 | KeyCombo::SHIFT_BIT, }, + { EMUCMD_SAVE_STATE_SLOT_5, SCAN_F5 | KeyCombo::SHIFT_BIT, }, + { EMUCMD_SAVE_STATE_SLOT_6, SCAN_F6 | KeyCombo::SHIFT_BIT, }, + { EMUCMD_SAVE_STATE_SLOT_7, SCAN_F7 | KeyCombo::SHIFT_BIT, }, + { EMUCMD_SAVE_STATE_SLOT_8, SCAN_F8 | KeyCombo::SHIFT_BIT, }, + { EMUCMD_SAVE_STATE_SLOT_9, SCAN_F9 | KeyCombo::SHIFT_BIT, }, { EMUCMD_LOAD_STATE_SLOT_0, SCAN_F10, }, { EMUCMD_LOAD_STATE_SLOT_1, SCAN_F1, }, { EMUCMD_LOAD_STATE_SLOT_2, SCAN_F2, }, @@ -66,25 +65,24 @@ static struct { EMUCMD_LOAD_STATE_SLOT_7, SCAN_F7, }, { EMUCMD_LOAD_STATE_SLOT_8, SCAN_F8, }, { EMUCMD_LOAD_STATE_SLOT_9, SCAN_F9, }, - { EMUCMD_MOVIE_PLAY_FROM_BEGINNING, SCAN_R | CMD_KEY_SHIFT, }, - { EMUCMD_SCRIPT_RELOAD, SCAN_L | CMD_KEY_SHIFT, }, - { EMUCMD_OPENROM, SCAN_O | CMD_KEY_CTRL, }, - { EMUCMD_CLOSEROM, SCAN_W | CMD_KEY_CTRL, }, - { EMUCMD_RELOAD, SCAN_F1 | CMD_KEY_CTRL , }, - { EMUCMD_MISC_UNDOREDOSAVESTATE, SCAN_Z | CMD_KEY_CTRL, }, - { EMUCMD_MISC_TOGGLEFULLSCREEN, SCAN_ENTER | CMD_KEY_ALT, }, + { EMUCMD_MOVIE_PLAY_FROM_BEGINNING, SCAN_R | KeyCombo::SHIFT_BIT, }, + { EMUCMD_SCRIPT_RELOAD, SCAN_L | KeyCombo::SHIFT_BIT, }, + { EMUCMD_OPENROM, SCAN_O | KeyCombo::CTRL_BIT, }, + { EMUCMD_CLOSEROM, SCAN_W | KeyCombo::CTRL_BIT, }, + { EMUCMD_RELOAD, SCAN_F1 | KeyCombo::CTRL_BIT , }, + { EMUCMD_MISC_UNDOREDOSAVESTATE, SCAN_Z | KeyCombo::CTRL_BIT, }, + { EMUCMD_MISC_TOGGLEFULLSCREEN, SCAN_ENTER | KeyCombo::ALT_BIT, }, { EMUCMD_RERECORD_DISPLAY_TOGGLE, SCAN_M, }, { EMUCMD_TASEDITOR_REWIND, SCAN_BACKSPACE, }, { EMUCMD_TASEDITOR_RESTORE_PLAYBACK, SCAN_SPACE, }, { EMUCMD_TASEDITOR_CANCEL_SEEKING, SCAN_ESCAPE, }, - { EMUCMD_TASEDITOR_SWITCH_AUTORESTORING, SCAN_SPACE | CMD_KEY_CTRL, }, + { EMUCMD_TASEDITOR_SWITCH_AUTORESTORING, SCAN_SPACE | KeyCombo::CTRL_BIT, }, { EMUCMD_TASEDITOR_SWITCH_MULTITRACKING, SCAN_W, }, }; #define NUM_DEFAULT_MAPPINGS (sizeof(DefaultCommandMapping)/sizeof(DefaultCommandMapping[0])) static uint8 keyonce[MKK_COUNT]; -static unsigned int *keys_nr = 0; static const char* ScanNames[256]= { @@ -108,6 +106,7 @@ static const char* ScanNames[256]= int _keyonly(int a) { + driver::input::keyboard::KeysState_const keys_nr = driver::input::keyboard::GetState(); if(keys_nr[a]) { if(!keyonce[a]) @@ -129,7 +128,7 @@ int GetKeyPressed() int key = 0; int i; - keys_nr = GetKeyboard_nr(); + driver::input::keyboard::KeysState_const keys_nr = driver::input::keyboard::GetState(); for(i = 0; i < 256 && !key; ++i) { @@ -146,7 +145,7 @@ int NothingPressed() { int i; - keys_nr = GetKeyboard_nr(); + driver::input::keyboard::KeysState_const keys_nr = driver::input::keyboard::GetState(); for(i = 0; i < 256; ++i) { @@ -159,48 +158,52 @@ int NothingPressed() return 1; } -int GetKeyMeta(int key) +int GetKeyMeta(KeyCombo combo) { - int meta = key & (~CMD_KEY_MASK); + KeyCombo tmp(0); + tmp.setMeta(combo.getMeta()); - switch(key & CMD_KEY_MASK) + switch(combo.getKey()) { case SCAN_LEFTCONTROL: - case SCAN_RIGHTCONTROL: - return CMD_KEY_CTRL | meta; + case SCAN_RIGHTCONTROL: + tmp.setModifiers(KeyCombo::CTRL_BIT); + break; case SCAN_LEFTALT: case SCAN_RIGHTALT: - return CMD_KEY_ALT | meta; + tmp.setModifiers(KeyCombo::ALT_BIT); + break; case SCAN_LEFTSHIFT: case SCAN_RIGHTSHIFT: - return CMD_KEY_SHIFT | meta; + tmp.setModifiers(KeyCombo::SHIFT_BIT); + break; default: break; } - return meta; + return tmp.getMeta(); } -void ClearExtraMeta(int* key) +void ClearExtraMeta(KeyCombo& combo) { - switch((*key)&0xff) + switch(combo.getKey()) { case SCAN_LEFTCONTROL: case SCAN_RIGHTCONTROL: - *key &= ~(CMD_KEY_CTRL); + combo.clearModifiers(KeyCombo::CTRL_BIT); break; case SCAN_LEFTALT: case SCAN_RIGHTALT: - *key &= ~(CMD_KEY_ALT); + combo.clearModifiers(KeyCombo::ALT_BIT); break; case SCAN_LEFTSHIFT: case SCAN_RIGHTSHIFT: - *key &= ~(CMD_KEY_SHIFT); + combo.clearModifiers(KeyCombo::SHIFT_BIT); break; default: @@ -258,57 +261,48 @@ const char* GetKeyName(int code) * * TODO: Replace return value with parameter. **/ -char* GetKeyComboName(int c) +char* GetKeyComboName(const KeyCombo& combo) { static char text[80]; text[0] = '\0'; - if(!c) - { - return text; - } + if(!combo.isEmpty()) { + uint32 mods = combo.getModifiers() & KeyCombo::CTRL_BIT; + if (mods == KeyCombo::CTRL_BIT) { + strcat(text, "Ctrl + "); + } + else if (mods == KeyCombo::LCTRL_BIT) { + strcat(text, "Left Ctrl + "); + } + else if (mods == KeyCombo::RCTRL_BIT) { + strcat(text, "Right Ctrl + "); + } - if ((c & CMD_KEY_CTRL) == CMD_KEY_CTRL) - { - strcat(text, "Ctrl + "); - } - else if ((c & CMD_KEY_CTRL) == CMD_KEY_LCTRL) - { - strcat(text, "Left Ctrl + "); - } - else if ((c & CMD_KEY_CTRL) == CMD_KEY_RCTRL) - { - strcat(text, "Right Ctrl + "); - } + mods = combo.getModifiers() & KeyCombo::ALT_BIT; + if (mods == KeyCombo::ALT_BIT) { + strcat(text, "Alt + "); + } + else if (mods == KeyCombo::LALT_BIT) { + strcat(text, "Left Alt + "); + } + else if (mods == KeyCombo::RALT_BIT) { + strcat(text, "Right Alt + "); + } - if ((c & CMD_KEY_ALT) == CMD_KEY_ALT) - { - strcat(text, "Alt + "); - } - else if ((c & CMD_KEY_ALT) == CMD_KEY_LALT) - { - strcat(text, "Left Alt + "); - } - else if ((c & CMD_KEY_ALT) == CMD_KEY_RALT) - { - strcat(text, "Right Alt + "); - } + mods = combo.getModifiers() & KeyCombo::SHIFT_BIT; + if (mods == KeyCombo::SHIFT_BIT) { + strcat(text, "Shift + "); + } + else if (mods == KeyCombo::LSHIFT_BIT) { + strcat(text, "Left Shift + "); + } + else if (mods == KeyCombo::RSHIFT_BIT) { + strcat(text, "Right Shift + "); + } - if ((c & CMD_KEY_SHIFT) == CMD_KEY_SHIFT) - { - strcat(text, "Shift + "); + strcat(text, GetKeyName(combo.getKey())); } - else if ((c & CMD_KEY_SHIFT) == CMD_KEY_LSHIFT) - { - strcat(text, "Left Shift + "); - } - else if ((c & CMD_KEY_SHIFT) == CMD_KEY_RSHIFT) - { - strcat(text, "Right Shift + "); - } - - strcat(text, GetKeyName(c & CMD_KEY_MASK)); return text; } @@ -319,7 +313,7 @@ BOOL CALLBACK ChangeInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR static HANDLE hThread = NULL; static DWORD dwThreadId = 0; static struct INPUTDLGTHREADARGS threadargs; - static int key = 0; + static KeyCombo combo(0); switch (uMsg) { @@ -330,10 +324,10 @@ BOOL CALLBACK ChangeInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR threadargs.hwndDlg = hwndDlg; hThread = CreateThread(NULL, 0, NewInputDialogThread, (LPVOID)&threadargs, 0, &dwThreadId); - key = 0; + combo.assign(0); memset(keyonce, 0, sizeof(keyonce)); - KeyboardSetBackgroundAccess(true); + driver::input::keyboard::SetBackgroundAccessBit(driver::input::keyboard::BKGINPUT_GENERAL); SetFocus(GetDlgItem(hwndDlg, LBL_KEY_COMBO)); CenterWindowOnScreen(hwndDlg); @@ -349,7 +343,7 @@ BOOL CALLBACK ChangeInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR PostMessage(hwndDlg, WM_USER + 99, 0, 0); break; case BTN_CLEAR: - key = -1; + combo.assign(-1); // Send quit message. PostMessage(hwndDlg, WM_USER + 99, 0, 0); break; @@ -361,18 +355,19 @@ BOOL CALLBACK ChangeInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR case WM_USER: { // Our thread sent us a timer signal. - int newkey; - int meta = GetKeyMeta(key); + int newScanCode; + int meta = GetKeyMeta(combo); - KeyboardUpdateState(); + FCEUD_UpdateInput(UPDATEINPUT_KEYBOARD); - if((newkey = GetKeyPressed()) != 0) + if((newScanCode = GetKeyPressed()) != 0) { - key = newkey | meta; - ClearExtraMeta(&key); - SetDlgItemText(hwndDlg, LBL_KEY_COMBO, GetKeyComboName(key)); + combo.setKey(newScanCode); + combo.setMeta(meta); + ClearExtraMeta(combo); + SetDlgItemText(hwndDlg, LBL_KEY_COMBO, GetKeyComboName(combo.get())); } - else if(NothingPressed() && key) + else if(NothingPressed() && !combo.isEmpty()) { PostMessage(hwndDlg, WM_USER + 99, 0, 0); // Send quit message. } @@ -381,10 +376,10 @@ BOOL CALLBACK ChangeInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR case WM_CLOSE: // exit without changing the key mapping - key = 0; + combo.assign(0); case WM_USER + 99: // Done with keyboard. - KeyboardSetBackgroundAccess(false); + driver::input::keyboard::ClearBackgroundAccessBit(driver::input::keyboard::BKGINPUT_GENERAL); // Kill the thread. SetEvent(threadargs.hThreadExit); @@ -393,7 +388,7 @@ BOOL CALLBACK ChangeInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPAR CloseHandle(threadargs.hThreadExit); // End the dialog. - EndDialog(hwndDlg, key); + EndDialog(hwndDlg, combo.get()); return TRUE; default: @@ -425,11 +420,11 @@ bool ShouldDisplayMapping(int mapn, int filter, const int* conflictTable) } else if(filter == EMUCMDTYPE_MAX + 1) /* Assigned */ { - return FCEUD_CommandMapping[FCEUI_CommandTable[mapn].cmd] != 0; + return (!GetCommandKeyCombo(FCEUI_CommandTable[mapn].cmd).isEmpty()); } else if(filter == EMUCMDTYPE_MAX + 2) /* Unassigned */ { - return FCEUD_CommandMapping[FCEUI_CommandTable[mapn].cmd] == 0; + return GetCommandKeyCombo(FCEUI_CommandTable[mapn].cmd).isEmpty(); } else if(filter == EMUCMDTYPE_MAX + 3) /* Conflicts */ { @@ -454,8 +449,8 @@ void PopulateConflictTable(int* conflictTable) { for(unsigned int j = i + 1; j < EMUCMD_MAX; ++j) { - if(FCEUD_CommandMapping[i] && - FCEUD_CommandMapping[i] == FCEUD_CommandMapping[j] && + if(!GetCommandKeyCombo((EMUCMD)i).isEmpty() && + GetCommandKeyCombo((EMUCMD)i).get() == GetCommandKeyCombo((EMUCMD)j).get() && // AnS: added the condition that both commands must have the same EMUCMDFLAG_TASEDITOR, or else they are not considered conflicting (FCEUI_CommandTable[i].flags & EMUCMDFLAG_TASEDITOR) == (FCEUI_CommandTable[j].flags & EMUCMDFLAG_TASEDITOR)) { @@ -533,7 +528,7 @@ void PopulateMappingDisplay(HWND hwndDlg) lvi.mask = LVIF_TEXT; lvi.iItem = idx; lvi.iSubItem = 2; - lvi.pszText = GetKeyComboName(FCEUD_CommandMapping[FCEUI_CommandTable[i].cmd]); + lvi.pszText = GetKeyComboName(GetCommandKeyCombo(FCEUI_CommandTable[i].cmd)); SendMessage(hwndListView, LVM_SETITEM, (WPARAM)0, (LPARAM)&lvi); @@ -640,20 +635,20 @@ void AskForHotkey(HWND hwndListView) SendMessage(hwndListView, LVM_GETITEM, 0, (LPARAM)&lvi); - int nCmd = lvi.lParam; + EMUCMD nCmd = (EMUCMD)lvi.lParam; int nRet = DialogBox(fceu_hInstance, "NEWINPUT", hwndListView, ChangeInputDialogProc); if (nRet) { - // nRet will be -1 when the user selects "clear". - FCEUD_CommandMapping[nCmd] = ( nRet < 0) ? 0 : nRet; + if(nRet < 0) nRet = 0; // nRet will be -1 when the user selects "clear". + SetCommandKeyCombo(nCmd, KeyCombo(nRet)); memset(&lvi, 0, sizeof(lvi)); lvi.mask = LVIF_TEXT; lvi.iItem = nSel; lvi.iSubItem = 2; - lvi.pszText = GetKeyComboName(FCEUD_CommandMapping[nCmd]); + lvi.pszText = GetKeyComboName(GetCommandKeyCombo(nCmd)); SendMessage(hwndListView, LVM_SETITEM, (WPARAM)0, (LPARAM)&lvi); } } @@ -664,11 +659,13 @@ void AskForHotkey(HWND hwndListView) **/ void ApplyDefaultCommandMapping() { - memset(FCEUD_CommandMapping, 0, sizeof(FCEUD_CommandMapping)); + for(unsigned int i = 0; i < EMUCMD_MAX; ++i) { + SetCommandKeyCombo((EMUCMD)i, KeyCombo(0)); + } for(unsigned i = 0; i < NUM_DEFAULT_MAPPINGS; ++i) { - FCEUD_CommandMapping[DefaultCommandMapping[i].cmd] = DefaultCommandMapping[i].key; + SetCommandKeyCombo(DefaultCommandMapping[i].cmd, KeyCombo(DefaultCommandMapping[i].key)); } } @@ -772,14 +769,16 @@ BOOL CALLBACK MapInputDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM void MapInput(void) { // Make a backup of the current mappings, in case the user changes their mind. - int* backupmapping = (int*)malloc(sizeof(FCEUD_CommandMapping)); - memcpy(backupmapping, FCEUD_CommandMapping, sizeof(FCEUD_CommandMapping)); + int backupmapping[EMUCMD_MAX]; + for(unsigned int i = 0; i < EMUCMD_MAX; ++i) { + backupmapping[i] = GetCommandKeyCombo((EMUCMD)i).get(); + } if(!DialogBox(fceu_hInstance, "MAPINPUT", hAppWnd, MapInputDialogProc)) { - memcpy(FCEUD_CommandMapping, backupmapping, sizeof(FCEUD_CommandMapping)); + for(unsigned int i = 0; i < EMUCMD_MAX; ++i) { + SetCommandKeyCombo((EMUCMD)i, KeyCombo(backupmapping[i])); + } } - - free(backupmapping); } diff --git a/trunk/src/drivers/win/mapinput.h b/trunk/src/drivers/win/mapinput.h index dc6545f0..0c2c3a52 100644 --- a/trunk/src/drivers/win/mapinput.h +++ b/trunk/src/drivers/win/mapinput.h @@ -1,4 +1,8 @@ #ifndef WIN_MAPINPUT_h #define WIN_MAPINPUT_h -char* GetKeyComboName(int c); + +#include "../../input.h" + + +char* GetKeyComboName(const KeyCombo& c); #endif diff --git a/trunk/src/drivers/win/netplay.cpp b/trunk/src/drivers/win/netplay.cpp index 9afbdb8d..b0e0065e 100644 --- a/trunk/src/drivers/win/netplay.cpp +++ b/trunk/src/drivers/win/netplay.cpp @@ -82,7 +82,7 @@ void FCEUD_NetworkClose(void) wsainit=0; } /* Make sure blocking is returned to normal once network play is stopped. */ - NoWaiting&=~2; + skipVSync = 0; FCEUDnetplay = 0; FCEUI_NetplayStop(); } @@ -344,7 +344,7 @@ static int recv_tcpwrap(uint8 *buf, int len) int FCEUD_RecvData(void *data, uint32 len) { - NoWaiting&=~2; + skipVSync = 0; for(;;) { @@ -370,7 +370,7 @@ int FCEUD_RecvData(void *data, uint32 len) unsigned long beefie; if(!ioctlsocket(Socket,FIONREAD,&beefie)) if(beefie) - NoWaiting|=2; + skipVSync = 1; return(1); } else diff --git a/trunk/src/drivers/win/res.rc b/trunk/src/drivers/win/res.rc index 56f3d34f..4c97d772 100644 --- a/trunk/src/drivers/win/res.rc +++ b/trunk/src/drivers/win/res.rc @@ -975,9 +975,9 @@ BEGIN PUSHBUTTON "12",311,91,59,16,12 END -QUIZKINGDIALOG DIALOG 30, 123, 160, 74 +PARTYTAPDIALOG DIALOG 30, 123, 160, 74 STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "quiz king" +CAPTION "party tap" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "Close",BTN_CLOSE,54,56,56,14 diff --git a/trunk/src/drivers/win/sound.cpp b/trunk/src/drivers/win/sound.cpp index cc4abcb8..18206446 100644 --- a/trunk/src/drivers/win/sound.cpp +++ b/trunk/src/drivers/win/sound.cpp @@ -393,7 +393,7 @@ static void UpdateSD(HWND hwndDlg) { int t; - CheckDlgButton(hwndDlg,CHECK_SOUND_ENABLED,soundo?BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg,CHECK_SOUND_ENABLED,isSoundEnabled?BST_CHECKED:BST_UNCHECKED); CheckDlgButton(hwndDlg,CHECK_SOUND_8BIT,(soundoptions&SO_FORCE8BIT)?BST_CHECKED:BST_UNCHECKED); // The option formerly flagged by SO_SECONDARY can no longer be disabled. // CheckDlgButton(hwndDlg,123,(soundoptions&SO_SECONDARY)?BST_CHECKED:BST_UNCHECKED); @@ -410,7 +410,7 @@ static void UpdateSD(HWND hwndDlg) else if(soundrate==96000) t=4; SendDlgItemMessage(hwndDlg,COMBO_SOUND_RATE,CB_SETCURSEL,t,(LPARAM)(LPSTR)0); - if (!soundo) + if (!isSoundEnabled) { EnableWindow(GetDlgItem(hwndDlg,CHECK_SOUND_MUTETURBO),FALSE); EnableWindow(GetDlgItem(hwndDlg,CHECK_SOUND_MUTEFA),FALSE); @@ -628,10 +628,10 @@ case WM_COMMAND: if (!turbo) FCEUI_SetSoundQuality(0); ///If turbo is running, don't do this call, turbo will handle it instead UpdateSD(hwndDlg); } - if(soundo) + if(isSoundEnabled) { TrashSoundNow(); - soundo=InitSound(); + isSoundEnabled=InitSound(); UpdateSD(hwndDlg); } } @@ -651,29 +651,29 @@ case WM_COMMAND: switch(LOWORD(wParam)) { case CHECK_SOUND_8BIT:soundoptions^=SO_FORCE8BIT; - if(soundo) + if(isSoundEnabled) { TrashSoundNow(); - soundo=InitSound(); + isSoundEnabled=InitSound(); UpdateSD(hwndDlg); } break; // The option formerly flagged by SO_SECONDARY can no longer be disabled. #if 0 case 123:soundoptions^=SO_SECONDARY; - if(soundo) + if(isSoundEnabled) { TrashSoundNow(); - soundo=InitSound(); + isSoundEnabled=InitSound(); UpdateSD(hwndDlg); } break; #endif case CHECK_SOUND_GLOBAL_FOCUS:soundoptions^=SO_GFOCUS; - if(soundo) + if(isSoundEnabled) { TrashSoundNow(); - soundo=InitSound(); + isSoundEnabled=InitSound(); UpdateSD(hwndDlg); } break; @@ -682,10 +682,10 @@ case WM_COMMAND: // The option formerly flagged by SO_OLDUP can no longer be enabled. #if 0 case 131:soundoptions^=SO_OLDUP; - if(soundo) + if(isSoundEnabled) { TrashSoundNow(); - soundo=InitSound(); + isSoundEnabled=InitSound(); UpdateSD(hwndDlg); } break; @@ -693,9 +693,9 @@ case WM_COMMAND: case CHECK_SOUND_MUTETURBO: muteTurbo ^= 1; break; - case CHECK_SOUND_ENABLED:soundo=!soundo; - if(!soundo) TrashSound(); - else soundo=InitSound(); + case CHECK_SOUND_ENABLED:isSoundEnabled=!isSoundEnabled; + if(!isSoundEnabled) TrashSound(); + else isSoundEnabled=InitSound(); UpdateSD(hwndDlg); break; case IDC_SOUND_RESTOREDEFAULTVOL: @@ -746,7 +746,7 @@ void UpdateSoundChannelQualityMode(HWND hwndDlg) if (soundquality) //If high or highest { //Enable sliders & corresponding group boxes - if (soundo) + if (isSoundEnabled) { EnableWindow(GetDlgItem(hwndDlg,CTL_VOLUME_TRACKBAR_SQUARE2),TRUE); EnableWindow(GetDlgItem(hwndDlg,CTL_VOLUME_TRACKBAR_NOISE),TRUE); diff --git a/trunk/src/drivers/win/sound.h b/trunk/src/drivers/win/sound.h index fe14e929..7cf474d3 100644 --- a/trunk/src/drivers/win/sound.h +++ b/trunk/src/drivers/win/sound.h @@ -8,4 +8,4 @@ void win_SoundSetScale(int scale); void win_SoundWriteData(int32 *buffer, int count); void win_Throttle(); extern bool muteTurbo; -extern int soundo; +extern int isSoundEnabled; diff --git a/trunk/src/drivers/win/taseditor.cpp b/trunk/src/drivers/win/taseditor.cpp index c1a645b3..f465c2ad 100644 --- a/trunk/src/drivers/win/taseditor.cpp +++ b/trunk/src/drivers/win/taseditor.cpp @@ -1002,13 +1002,13 @@ void enableGeneralKeyboardInput() { taseditorEnableAcceleratorKeys = true; // set "Background TAS Editor input" - KeyboardSetBackgroundAccessBit(KEYBACKACCESS_TASEDITOR); - JoystickSetBackgroundAccessBit(JOYBACKACCESS_TASEDITOR); + driver::input::keyboard::SetBackgroundAccessBit(driver::input::keyboard::BKGINPUT_TASEDITOR); + driver::input::joystick::SetBackgroundAccessBit(driver::input::joystick::BKGINPUT_TASEDITOR); } void disableGeneralKeyboardInput() { taseditorEnableAcceleratorKeys = false; // clear "Background TAS Editor input" - KeyboardClearBackgroundAccessBit(KEYBACKACCESS_TASEDITOR); - JoystickClearBackgroundAccessBit(JOYBACKACCESS_TASEDITOR); + driver::input::keyboard::ClearBackgroundAccessBit(driver::input::keyboard::BKGINPUT_TASEDITOR); + driver::input::joystick::ClearBackgroundAccessBit(driver::input::joystick::BKGINPUT_TASEDITOR); } diff --git a/trunk/src/drivers/win/taseditor/recorder.cpp b/trunk/src/drivers/win/taseditor/recorder.cpp index 2ded5fd1..0091a949 100644 --- a/trunk/src/drivers/win/taseditor/recorder.cpp +++ b/trunk/src/drivers/win/taseditor/recorder.cpp @@ -17,10 +17,10 @@ Recorder - Tool for Input recording ------------------------------------------------------------------------------------ */ #include "taseditor_project.h" +#include "drivers/win/input.h" extern int joysticksPerFrame[INPUT_TYPES_TOTAL]; -extern uint32 GetGamepadPressedImmediate(); extern int getInputType(MovieData& md); extern char lagFlag; @@ -165,7 +165,7 @@ void RECORDER::update() oldJoyData[2] = currentJoypadData[2]; oldJoyData[3] = currentJoypadData[3]; // fill current_joy data for Piano Roll header lights - uint32 joypads = GetGamepadPressedImmediate(); + uint32 joypads = GetGamepadPressedPhysical(); currentJoypadData[0] = (joypads & 0xFF); currentJoypadData[1] = ((joypads >> 8) & 0xFF); currentJoypadData[2] = ((joypads >> 16) & 0xFF); diff --git a/trunk/src/drivers/win/taseditor/taseditor_window.cpp b/trunk/src/drivers/win/taseditor/taseditor_window.cpp index c4afb7fd..cb50964a 100644 --- a/trunk/src/drivers/win/taseditor/taseditor_window.cpp +++ b/trunk/src/drivers/win/taseditor/taseditor_window.cpp @@ -26,6 +26,7 @@ Window - User Interface #include "../taseditor.h" #include #include "../../input.h" // for EMUCMD +#include "../mapinput.h" //compile for windows 2000 target #if (_WIN32_WINNT < 0x501) @@ -51,8 +52,6 @@ extern POPUP_DISPLAY popupDisplay; extern bool turbo; extern bool mustCallManualLuaFunction; -extern char* GetKeyComboName(int c); - extern BOOL CALLBACK findNoteWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); extern BOOL CALLBACK aboutWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); extern BOOL CALLBACK savingOptionsWndProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam); @@ -132,47 +131,47 @@ char taseditorHelpFilename[] = "\\taseditor.chm"; // "y < 0" means that the coordinate is counted from the lower border of the window (bottom-aligned) // The items in this array MUST be sorted by the same order as the Window_items_enum! WindowItemData windowItems[TASEDITOR_WINDOW_TOTAL_ITEMS] = { - WINDOWITEMS_PIANO_ROLL, IDC_LIST1, 0, 0, -1, -1, "", "", false, 0, 0, - WINDOWITEMS_PLAYBACK_MARKER, IDC_PLAYBACK_MARKER, 0, 0, 0, 0, "Click here to scroll Piano Roll to Playback cursor (hotkey: tap Shift twice)", "", false, 0, 0, - WINDOWITEMS_PLAYBACK_MARKER_EDIT, IDC_PLAYBACK_MARKER_EDIT, 0, 0, -1, 0, "Click to edit text", "", false, 0, 0, - WINDOWITEMS_SELECTION_MARKER, IDC_SELECTION_MARKER, 0, -1, 0, -1, "Click here to scroll Piano Roll to Selection (hotkey: tap Ctrl twice)", "", false, 0, 0, - WINDOWITEMS_SELECTION_MARKER_EDIT, IDC_SELECTION_MARKER_EDIT, 0, -1, -1, -1, "Click to edit text", "", false, 0, 0, - WINDOWITEMS_PLAYBACK_BOX, IDC_PLAYBACK_BOX, -1, 0, 0, 0, "", "", false, 0, 0, + WINDOWITEMS_PIANO_ROLL, IDC_LIST1, 0, 0, -1, -1, "", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_PLAYBACK_MARKER, IDC_PLAYBACK_MARKER, 0, 0, 0, 0, "Click here to scroll Piano Roll to Playback cursor (hotkey: tap Shift twice)", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_PLAYBACK_MARKER_EDIT, IDC_PLAYBACK_MARKER_EDIT, 0, 0, -1, 0, "Click to edit text", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_SELECTION_MARKER, IDC_SELECTION_MARKER, 0, -1, 0, -1, "Click here to scroll Piano Roll to Selection (hotkey: tap Ctrl twice)", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_SELECTION_MARKER_EDIT, IDC_SELECTION_MARKER_EDIT, 0, -1, -1, -1, "Click to edit text", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_PLAYBACK_BOX, IDC_PLAYBACK_BOX, -1, 0, 0, 0, "", "", false, EMUCMD_NONE, 0, WINDOWITEMS_PROGRESS_BUTTON, IDC_PROGRESS_BUTTON, -1, 0, 0, 0, "Click here when you want to abort seeking", "", false, EMUCMD_TASEDITOR_CANCEL_SEEKING, 0, - WINDOWITEMS_REWIND_FULL, TASEDITOR_REWIND_FULL, -1, 0, 0, 0, "Send Playback to previous Marker (mouse: Shift+Wheel up) (hotkey: Shift+PageUp)", "", false, 0, 0, + WINDOWITEMS_REWIND_FULL, TASEDITOR_REWIND_FULL, -1, 0, 0, 0, "Send Playback to previous Marker (mouse: Shift+Wheel up) (hotkey: Shift+PageUp)", "", false, EMUCMD_NONE, 0, WINDOWITEMS_REWIND, TASEDITOR_REWIND, -1, 0, 0, 0, "Rewind 1 frame (mouse: Right button+Wheel up) (hotkey: Shift+Up)", "", false, EMUCMD_TASEDITOR_REWIND, 0, WINDOWITEMS_PAUSE, TASEDITOR_PLAYSTOP, -1, 0, 0, 0, "Pause/Unpause Emulation (mouse: Middle button)", "", false, EMUCMD_PAUSE, 0, WINDOWITEMS_FORWARD, TASEDITOR_FORWARD, -1, 0, 0, 0, "Advance 1 frame (mouse: Right button+Wheel down) (hotkey: Shift+Down)", "", false, EMUCMD_FRAME_ADVANCE, 0, - WINDOWITEMS_FORWARD_FULL, TASEDITOR_FORWARD_FULL, -1, 0, 0, 0, "Send Playback to next Marker (mouse: Shift+Wheel down) (hotkey: Shift+PageDown)", "", false, 0, 0, - WINDOWITEMS_PROGRESS_BAR, IDC_PROGRESS1, -1, 0, 0, 0, "", "", false, 0, 0, - WINDOWITEMS_FOLLOW_CURSOR, CHECK_FOLLOW_CURSOR, -1, 0, 0, 0, "The Piano Roll will follow Playback cursor movements", "", false, 0, 0, - WINDOWITEMS_TURBO_SEEK, CHECK_TURBO_SEEK, -1, 0, 0, 0, "Uncheck when you need to watch seeking in slow motion", "", false, 0, 0, + WINDOWITEMS_FORWARD_FULL, TASEDITOR_FORWARD_FULL, -1, 0, 0, 0, "Send Playback to next Marker (mouse: Shift+Wheel down) (hotkey: Shift+PageDown)", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_PROGRESS_BAR, IDC_PROGRESS1, -1, 0, 0, 0, "", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_FOLLOW_CURSOR, CHECK_FOLLOW_CURSOR, -1, 0, 0, 0, "The Piano Roll will follow Playback cursor movements", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_TURBO_SEEK, CHECK_TURBO_SEEK, -1, 0, 0, 0, "Uncheck when you need to watch seeking in slow motion", "", false, EMUCMD_NONE, 0, WINDOWITEMS_AUTORESTORE_PLAYBACK, CHECK_AUTORESTORE_PLAYBACK, -1, 0, 0, 0, "Whenever you change Input above Playback cursor, the cursor returns to where it was before the change", "", false, EMUCMD_TASEDITOR_SWITCH_AUTORESTORING, 0, - WINDOWITEMS_RECORDER_BOX, IDC_RECORDER_BOX, -1, 0, 0, 0, "", "", false, 0, 0, + WINDOWITEMS_RECORDER_BOX, IDC_RECORDER_BOX, -1, 0, 0, 0, "", "", false, EMUCMD_NONE, 0, WINDOWITEMS_RECORDING, IDC_RECORDING, -1, 0, 0, 0, "Switch Input Recording on/off", "", false, EMUCMD_MOVIE_READONLY_TOGGLE, 0, - WINDOWITEMS_RECORD_ALL, IDC_RADIO_ALL, -1, 0, 0, 0, "Switch off Multitracking", "", false, 0, 0, + WINDOWITEMS_RECORD_ALL, IDC_RADIO_ALL, -1, 0, 0, 0, "Switch off Multitracking", "", false, EMUCMD_NONE, 0, WINDOWITEMS_RECORD_1P, IDC_RADIO_1P, -1, 0, 0, 0, "Select Joypad 1 as current", "", false, EMUCMD_TASEDITOR_SWITCH_MULTITRACKING, 0, WINDOWITEMS_RECORD_2P, IDC_RADIO_2P, -1, 0, 0, 0, "Select Joypad 2 as current", "", false, EMUCMD_TASEDITOR_SWITCH_MULTITRACKING, 0, WINDOWITEMS_RECORD_3P, IDC_RADIO_3P, -1, 0, 0, 0, "Select Joypad 3 as current", "", false, EMUCMD_TASEDITOR_SWITCH_MULTITRACKING, 0, WINDOWITEMS_RECORD_4P, IDC_RADIO_4P, -1, 0, 0, 0, "Select Joypad 4 as current", "", false, EMUCMD_TASEDITOR_SWITCH_MULTITRACKING, 0, - WINDOWITEMS_SUPERIMPOSE, IDC_SUPERIMPOSE, -1, 0, 0, 0, "Allows to superimpose old Input with new buttons, instead of overwriting", "", false, 0, 0, - WINDOWITEMS_USE_PATTERN, IDC_USEPATTERN, -1, 0, 0, 0, "Applies current Autofire Pattern to Input recording", "", false, 0, 0, - WINDOWITEMS_SPLICER_BOX, IDC_SPLICER_BOX, -1, 0, 0, 0, "", "", false, 0, 0, - WINDOWITEMS_SELECTION_TEXT, IDC_TEXT_SELECTION, -1, 0, 0, 0, "Current size of Selection", "", false, 0, 0, - WINDOWITEMS_CLIPBOARD_TEXT, IDC_TEXT_CLIPBOARD, -1, 0, 0, 0, "Current size of Input in the Clipboard", "", false, 0, 0, - WINDOWITEMS_LUA_BOX, IDC_LUA_BOX, -1, 0, 0, 0, "", "", false, 0, 0, + WINDOWITEMS_SUPERIMPOSE, IDC_SUPERIMPOSE, -1, 0, 0, 0, "Allows to superimpose old Input with new buttons, instead of overwriting", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_USE_PATTERN, IDC_USEPATTERN, -1, 0, 0, 0, "Applies current Autofire Pattern to Input recording", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_SPLICER_BOX, IDC_SPLICER_BOX, -1, 0, 0, 0, "", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_SELECTION_TEXT, IDC_TEXT_SELECTION, -1, 0, 0, 0, "Current size of Selection", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_CLIPBOARD_TEXT, IDC_TEXT_CLIPBOARD, -1, 0, 0, 0, "Current size of Input in the Clipboard", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_LUA_BOX, IDC_LUA_BOX, -1, 0, 0, 0, "", "", false, EMUCMD_NONE, 0, WINDOWITEMS_RUN_MANUAL, TASEDITOR_RUN_MANUAL, -1, 0, 0, 0, "Press the button to execute Lua Manual Function", "", false, EMUCMD_TASEDITOR_RUN_MANUAL_LUA, 0, - WINDOWITEMS_RUN_AUTO, IDC_RUN_AUTO, -1, 0, 0, 0, "Enable Lua Auto Function (but first it must be registered by Lua script)", "", false, 0, 0, - WINDOWITEMS_BRANCHES_BUTTON, IDC_BRANCHES_BUTTON, -1, 0, 0, 0, "Click here to switch between Bookmarks List and Branches Tree", "", false, 0, 0, - WINDOWITEMS_BOOKMARKS_BOX, IDC_BOOKMARKS_BOX, -1, 0, 0, 0, "", "", false, 0, 0, - WINDOWITEMS_BOOKMARKS_LIST, IDC_BOOKMARKSLIST, -1, 0, 0, 0, "Right click = set Bookmark, Left click = jump to Bookmark or load Branch", "", false, 0, 0, - WINDOWITEMS_BRANCHES_BITMAP, IDC_BRANCHES_BITMAP, -1, 0, 0, 0, "Right click = set Bookmark, single Left click = jump to Bookmark, double Left click = load Branch", "", false, 0, 0, - WINDOWITEMS_HISTORY_BOX, IDC_HISTORY_BOX, -1, 0, 0, -1, "", "", false, 0, 0, - WINDOWITEMS_HISTORY_LIST, IDC_HISTORYLIST, -1, 0, 0, -1, "Click to revert the project back to that time", "", false, 0, 0, - WINDOWITEMS_PREVIOUS_MARKER, TASEDITOR_PREV_MARKER, -1, -1, 0, -1, "Send Selection to previous Marker (mouse: Ctrl+Wheel up) (hotkey: Ctrl+PageUp)", "", false, 0, 0, - WINDOWITEMS_SIMILAR, TASEDITOR_FIND_BEST_SIMILAR_MARKER, -1, -1, 0, -1, "Auto-search for Marker Note", "", false, 0, 0, - WINDOWITEMS_MORE, TASEDITOR_FIND_NEXT_SIMILAR_MARKER, -1, -1, 0, -1, "Continue Auto-search", "", false, 0, 0, - WINDOWITEMS_NEXT_MARKER, TASEDITOR_NEXT_MARKER, -1, -1, 0, -1, "Send Selection to next Marker (mouse: Ctrl+Wheel up) (hotkey: Ctrl+PageDown)", "", false, 0, 0, + WINDOWITEMS_RUN_AUTO, IDC_RUN_AUTO, -1, 0, 0, 0, "Enable Lua Auto Function (but first it must be registered by Lua script)", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_BRANCHES_BUTTON, IDC_BRANCHES_BUTTON, -1, 0, 0, 0, "Click here to switch between Bookmarks List and Branches Tree", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_BOOKMARKS_BOX, IDC_BOOKMARKS_BOX, -1, 0, 0, 0, "", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_BOOKMARKS_LIST, IDC_BOOKMARKSLIST, -1, 0, 0, 0, "Right click = set Bookmark, Left click = jump to Bookmark or load Branch", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_BRANCHES_BITMAP, IDC_BRANCHES_BITMAP, -1, 0, 0, 0, "Right click = set Bookmark, single Left click = jump to Bookmark, double Left click = load Branch", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_HISTORY_BOX, IDC_HISTORY_BOX, -1, 0, 0, -1, "", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_HISTORY_LIST, IDC_HISTORYLIST, -1, 0, 0, -1, "Click to revert the project back to that time", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_PREVIOUS_MARKER, TASEDITOR_PREV_MARKER, -1, -1, 0, -1, "Send Selection to previous Marker (mouse: Ctrl+Wheel up) (hotkey: Ctrl+PageUp)", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_SIMILAR, TASEDITOR_FIND_BEST_SIMILAR_MARKER, -1, -1, 0, -1, "Auto-search for Marker Note", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_MORE, TASEDITOR_FIND_NEXT_SIMILAR_MARKER, -1, -1, 0, -1, "Continue Auto-search", "", false, EMUCMD_NONE, 0, + WINDOWITEMS_NEXT_MARKER, TASEDITOR_NEXT_MARKER, -1, -1, 0, -1, "Send Selection to next Marker (mouse: Ctrl+Wheel up) (hotkey: Ctrl+PageDown)", "", false, EMUCMD_NONE, 0, }; TASEDITOR_WINDOW::TASEDITOR_WINDOW() @@ -240,12 +239,12 @@ void TASEDITOR_WINDOW::init() toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; } // add hotkey mapping if needed - if (windowItems[i].hotkeyEmuCmd && FCEUD_CommandMapping[windowItems[i].hotkeyEmuCmd]) + if (windowItems[i].hotkeyEmuCmd && !GetCommandKeyCombo((EMUCMD)windowItems[i].hotkeyEmuCmd).isEmpty()) { windowItems[i].tooltipText[0] = 0; strcpy(windowItems[i].tooltipText, windowItems[i].tooltipTextBase); strcat(windowItems[i].tooltipText, " (hotkey: "); - strncat(windowItems[i].tooltipText, GetKeyComboName(FCEUD_CommandMapping[windowItems[i].hotkeyEmuCmd]), TOOLTIP_TEXT_MAX_LEN - strlen(windowItems[i].tooltipText) - 1); + strncat(windowItems[i].tooltipText, GetKeyComboName(GetCommandKeyCombo(windowItems[i].hotkeyEmuCmd)), TOOLTIP_TEXT_MAX_LEN - strlen(windowItems[i].tooltipText) - 1); strncat(windowItems[i].tooltipText, ")", TOOLTIP_TEXT_MAX_LEN - strlen(windowItems[i].tooltipText) - 1); toolInfo.lpszText = windowItems[i].tooltipText; } else diff --git a/trunk/src/drivers/win/taseditor/taseditor_window.h b/trunk/src/drivers/win/taseditor/taseditor_window.h index 687d55fa..04a0fcf4 100644 --- a/trunk/src/drivers/win/taseditor/taseditor_window.h +++ b/trunk/src/drivers/win/taseditor/taseditor_window.h @@ -1,4 +1,5 @@ // Specification file for TASEDITOR_WINDOW class +#include "../../input.h" enum TASEDITOR_WINDOW_ITEMS { @@ -65,7 +66,7 @@ struct WindowItemData char tooltipTextBase[TOOLTIP_TEXT_MAX_LEN]; char tooltipText[TOOLTIP_TEXT_MAX_LEN]; bool isStaticRect; - int hotkeyEmuCmd; + EMUCMD hotkeyEmuCmd; HWND tooltipHWND; }; diff --git a/trunk/src/drivers/win/throttle.h b/trunk/src/drivers/win/throttle.h index e719a7de..6cb2009e 100644 --- a/trunk/src/drivers/win/throttle.h +++ b/trunk/src/drivers/win/throttle.h @@ -1,3 +1,5 @@ +extern int32 fps_scale; + void InitSpeedThrottle(void); int SpeedThrottle(void); void RefreshThrottleFPS(); diff --git a/trunk/src/drivers/win/tracer.cpp b/trunk/src/drivers/win/tracer.cpp index 4f806e73..34246d5b 100644 --- a/trunk/src/drivers/win/tracer.cpp +++ b/trunk/src/drivers/win/tracer.cpp @@ -597,7 +597,7 @@ BOOL CALLBACK TracerCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Assemble the message to pause the game. Uses the current hotkey mapping dynamically strcpy(trace_str, "Pause the game (press "); - strcat(trace_str, GetKeyComboName(FCEUD_CommandMapping[EMUCMD_PAUSE])); + strcat(trace_str, GetKeyComboName(GetCommandKeyCombo(EMUCMD_PAUSE))); strcat(trace_str, " key or snap the Debugger) to update this window.\r\n"); SetDlgItemText(hTracer, IDC_TRACER_LOG, trace_str); } @@ -707,7 +707,7 @@ void BeginLoggingSequence(void) tracelogbufAddressesLog.resize(tracelogbufsize); // Assemble the message to pause the game. Uses the current hotkey mapping dynamically strcat(trace_str, "Pause the game (press "); - strcat(trace_str, GetKeyComboName(FCEUD_CommandMapping[EMUCMD_PAUSE])); + strcat(trace_str, GetKeyComboName(GetCommandKeyCombo(EMUCMD_PAUSE))); strcat(trace_str, " key or snap the Debugger) to update this window.\r\n"); SetDlgItemText(hTracer, IDC_TRACER_LOG, trace_str); tracelogbufpos = tracelogbufusedsize = 0; diff --git a/trunk/src/drivers/win/video.cpp b/trunk/src/drivers/win/video.cpp index 8ab4626f..f4827098 100644 --- a/trunk/src/drivers/win/video.cpp +++ b/trunk/src/drivers/win/video.cpp @@ -26,6 +26,7 @@ #include "gui.h" #include "../../fceu.h" #include "../../video.h" +#include "sound.h" #include "input.h" #include "mapinput.h" #include @@ -96,6 +97,12 @@ static bool fullscreenActual = false; // Internal 'actual' fullscreen status static int filterScaleMultiplier[6] = {1,2,2,2,3,3}; // scale multipliers for defined filters +static VSYNCMODE tempwinsync = SYNCMODE_NONE; //Temp variable used by turbo to turn of sync settings +static int tempsoundquality = 0; //Temp variable used by turbo to turn of sound quality settings +// globally exposed garbage +bool turbo = false; +int skipVSync = 0; + static void RestoreLostScreenSurface() { @@ -555,7 +562,7 @@ static bool SetVideoMode() static void VerticalSync() { - if(!NoWaiting) // apparently NoWaiting is set during netplay, which means there will be no vsync + if(!skipVSync) // apparently skipVSync is set during netplay, which means there will be no vsync { int syncMode = (fullscreenActual)? idxFullscreenSyncMode:idxWindowedSyncMode; switch(syncMode) { @@ -1048,8 +1055,8 @@ static BOOL CALLBACK VideoConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA CheckDlgButton(hwndDlg,IDC_VIDEOCONFIG_NO8LIM,BST_CHECKED); char buf[1024] = "Full Screen"; - int c = FCEUD_CommandMapping[EMUCMD_MISC_TOGGLEFULLSCREEN]; - if (c) + KeyCombo c = GetCommandKeyCombo(EMUCMD_MISC_TOGGLEFULLSCREEN); + if (!c.isEmpty()) { strcat(buf, " ("); strcat(buf, GetKeyComboName(c)); @@ -1255,6 +1262,28 @@ void FCEUD_GetPalette(unsigned char i, unsigned char *r, unsigned char *g, unsig *b=color_palette[i].peBlue; } +void FCEUD_TurboOn() { + tempwinsync = GetWindowedSyncModeIdx(); //Store wndSyncMode setting + SetWindowedSyncModeIdx(SYNCMODE_NONE); //turn off wndSyncMode for turbo (so that turbo can function even with VBlank sync methods + tempsoundquality = soundquality; //Store sound quality settings + FCEUI_SetSoundQuality(0); //Turn sound quality to low + turbo = true; + if (muteTurbo && isSoundEnabled) TrashSound(); +} + +void FCEUD_TurboOff() { + SetWindowedSyncModeIdx(tempwinsync); //Restore wndSyncMode setting + soundquality = tempsoundquality; //Restore sound quality settings + FCEUI_SetSoundQuality(soundquality); + turbo = false; + if (muteTurbo && isSoundEnabled) InitSound(); +} + +void FCEUD_TurboToggle() { + if(turbo) FCEUD_TurboOff(); + else FCEUD_TurboOn(); +} + bool& _FIXME_getFullscreenVar() { return fullscreenActual; // provide config with actual fullscreen state, not desired diff --git a/trunk/src/drivers/win/video.h b/trunk/src/drivers/win/video.h index 367bd35e..bb7c629d 100644 --- a/trunk/src/drivers/win/video.h +++ b/trunk/src/drivers/win/video.h @@ -82,6 +82,10 @@ void FCEUD_VideoChanged(void); // this one should be declared here void FCEUD_SetPalette(unsigned char index, unsigned char r, unsigned char g, unsigned char b); void FCEUD_GetPalette(unsigned char i, unsigned char *r, unsigned char *g, unsigned char *b); +void FCEUD_TurboOn(void); +void FCEUD_TurboOff(void); +void FCEUD_TurboToggle(void); + // see win/config.h bool& _FIXME_getFullscreenVar(void); diff --git a/trunk/src/drivers/win/window.cpp b/trunk/src/drivers/win/window.cpp index 536add32..2959961b 100644 --- a/trunk/src/drivers/win/window.cpp +++ b/trunk/src/drivers/win/window.cpp @@ -1075,7 +1075,7 @@ bool ALoad(const char *nameo, char* innerFilename, bool silent) } SetMainWindowText(); - ParseGIInput(GameInfo); + FCEUD_SetInput(GameInfo->input[0], GameInfo->input[1], GameInfo->inputfc); updateGameDependentMenus(GameInfo != 0); updateGameDependentMenusDebugger(GameInfo != 0); @@ -1874,16 +1874,22 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) if((eoptions & EO_BGRUN) == 0) { EnableBackgroundInput = 0; - KeyboardSetBackgroundAccess(EnableBackgroundInput!=0); - JoystickSetBackgroundAccess(EnableBackgroundInput!=0); + driver::input::keyboard::ClearBackgroundAccessBit(driver::input::keyboard::BKGINPUT_GENERAL); + driver::input::joystick::ClearBackgroundAccessBit(driver::input::joystick::BKGINPUT_GENERAL); } UpdateCheckedMenuItems(); break; case MENU_BACKGROUND_INPUT: EnableBackgroundInput ^= 1; eoptions |= EO_BGRUN * EnableBackgroundInput; - KeyboardSetBackgroundAccess(EnableBackgroundInput!=0); - JoystickSetBackgroundAccess(EnableBackgroundInput!=0); + if(EnableBackgroundInput != 0) { + driver::input::keyboard::SetBackgroundAccessBit(driver::input::keyboard::BKGINPUT_GENERAL); + driver::input::joystick::SetBackgroundAccessBit(driver::input::joystick::BKGINPUT_GENERAL); + } + else { + driver::input::keyboard::ClearBackgroundAccessBit(driver::input::keyboard::BKGINPUT_GENERAL); + driver::input::joystick::ClearBackgroundAccessBit(driver::input::joystick::BKGINPUT_GENERAL); + } UpdateCheckedMenuItems(); break; case MENU_ENABLE_AUTOSAVE: @@ -1982,7 +1988,7 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) ConfigGUI(); break; case MENU_INPUT: - ConfigInput(hWnd); + ConfigInput(); break; case MENU_NETWORK: ShowNetplayConsole(); @@ -2141,7 +2147,7 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) UpdateCheckedMenuItems(); break; case MENU_ALTERNATE_AB: - SetAutoFireDesynch(GetAutoFireDesynch()^1); + SetAutoFireDesynch(!GetAutoFireDesynch()); UpdateCheckedMenuItems(); break; case ID_TOOLS_TEXTHOOKER: @@ -2293,14 +2299,26 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) if(wParam==SC_KEYMENU) { - if(GameInfo && ((InputType[2]==SIFC_FKB) || (InputType[2]==SIFC_SUBORKB) || (InputType[2]==SIFC_PEC586KB)) && cidisabled) + if(GameInfo && + (GetPluggedInEx() == SIFC_FKB || + GetPluggedInEx() == SIFC_SUBORKB || + GetPluggedInEx() == SIFC_PEC586KB) && + GetInputKeyboard()) + { break; + } if(lParam == VK_RETURN || GetIsFullscreen() || tog) break; } goto proco; case WM_SYSKEYDOWN: - if(GameInfo && ((InputType[2]==SIFC_FKB) || (InputType[2]==SIFC_SUBORKB) || (InputType[2]==SIFC_PEC586KB)) && cidisabled) + if(GameInfo && + (GetPluggedInEx() == SIFC_FKB || + GetPluggedInEx() == SIFC_SUBORKB || + GetPluggedInEx() == SIFC_PEC586KB) && + GetInputKeyboard()) + { break; // Hopefully this won't break DInput... + } if(GetIsFullscreen() || tog) { @@ -2331,14 +2349,16 @@ adelikat: Outsourced this to a remappable hotkey if(GameInfo) { //Only disable command keys if a game is loaded(and the other conditions are right, of course). - if((InputType[2]==SIFC_FKB) || (InputType[2]==SIFC_SUBORKB) || (InputType[2]==SIFC_PEC586KB)) + if(GetPluggedInEx() == SIFC_FKB || + GetPluggedInEx() == SIFC_SUBORKB || + GetPluggedInEx() == SIFC_PEC586KB) { if(wParam==VK_SCROLL) { - cidisabled^=1; - FCEUI_DispMessage("%s Keyboard %sabled.",0,InputType[2]==SIFC_FKB?"Family":(InputType[2]==SIFC_SUBORKB?"Subor":"PEC586"),cidisabled?"en":"dis"); + SetInputKeyboard(!GetInputKeyboard()); + FCEUI_DispMessage("%s %s.",0, ESIFC_Name(GetPluggedInEx()), GetInputKeyboard()? "enabled":"disabled"); } - if(cidisabled) + if(GetInputKeyboard()) break; // Hopefully this won't break DInput... } } @@ -2739,246 +2759,246 @@ void UpdateMenuHotkeys() //-------------------------------FILE--------------------------------------- //Open ROM - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_OPENROM]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_OPENROM)); combined = "&Open ROM...\t" + combo; ChangeMenuItemText(MENU_OPEN_FILE, combined); //Close ROM - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_CLOSEROM]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_CLOSEROM)); combined = "&Close\t" + combo; ChangeMenuItemText(MENU_CLOSE_FILE, combined); //Load State - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_LOAD_STATE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_LOAD_STATE)); combined = "&Load State\t" + combo; ChangeMenuItemText(MENU_LOADSTATE, combined); //Save State - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SAVE_STATE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_SAVE_STATE)); combined = "&Save State\t" + combo; ChangeMenuItemText(MENU_SAVESTATE, combined); //Loadstate from - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_LOAD_STATE_FROM]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_LOAD_STATE_FROM)); combined = "Load State &From...\t" + combo; ChangeMenuItemText(MENU_LOAD_STATE, combined); //Savestate as - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SAVE_STATE_AS]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_SAVE_STATE_AS)); combined = "Save State &As...\t" + combo; ChangeMenuItemText(MENU_SAVE_STATE, combined); //Next Save Slot - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SAVE_SLOT_NEXT]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_SAVE_SLOT_NEXT)); combined = "&Next save slot\t" + combo; ChangeMenuItemText(MENU_NEXTSAVESTATE, combined); //Previous Save Slot - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SAVE_SLOT_PREV]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_SAVE_SLOT_PREV)); combined = "&Previous save slot\t" + combo; ChangeMenuItemText(MENU_PREVIOUSSAVESTATE, combined); //View Save Slots - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MISC_SHOWSTATES]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MISC_SHOWSTATES)); combined = "&View save slots\t" + combo; ChangeMenuItemText(MENU_VIEWSAVESLOTS, combined); //Record Movie - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_RECORD_TO]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MOVIE_RECORD_TO)); combined = "&Record Movie...\t" + combo; ChangeMenuItemText(MENU_RECORD_MOVIE, combined); //Play movie - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_REPLAY_FROM]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MOVIE_REPLAY_FROM)); combined = "&Play Movie...\t" + combo; ChangeMenuItemText(MENU_REPLAY_MOVIE, combined); //Stop movie - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_STOP]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MOVIE_STOP)); combined = "&Stop Movie\t" + combo; ChangeMenuItemText(MENU_STOP_MOVIE, combined); //Play Movie from Beginning - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_PLAY_FROM_BEGINNING]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MOVIE_PLAY_FROM_BEGINNING)); combined = "Play from &Beginning\t" + combo; ChangeMenuItemText(ID_FILE_PLAYMOVIEFROMBEGINNING, combined); //Read only - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_READONLY_TOGGLE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MOVIE_READONLY_TOGGLE)); combined = "&Read only\t" + combo; ChangeMenuItemText(ID_FILE_MOVIE_TOGGLEREAD, combined); //Screenshot - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SCREENSHOT]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_SCREENSHOT)); combined = "&Screenshot\t" + combo; ChangeMenuItemText(ID_FILE_SCREENSHOT, combined); //Record AVI - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_AVI_RECORD_AS]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_AVI_RECORD_AS)); combined = "&Record AVI...\t" + combo; ChangeMenuItemText(MENU_RECORD_AVI, combined); //Stop AVI - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_AVI_STOP]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_AVI_STOP)); combined = "&Stop AVI\t" + combo; ChangeMenuItemText(MENU_STOP_AVI, combined); //-------------------------------NES---------------------------------------- //Reset - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_RESET]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_RESET)); combined = "&Reset\t" + combo; ChangeMenuItemText(MENU_RESET, combined); //Power - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_POWER]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_POWER)); combined = "&Power\t" + combo; ChangeMenuItemText(MENU_POWER, combined); //Eject/Insert Disk - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_FDS_EJECT_INSERT]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_FDS_EJECT_INSERT)); combined = "&Eject/Insert Disk\t" + combo; ChangeMenuItemText(MENU_EJECT_DISK, combined); //Switch Disk Side - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_FDS_SIDE_SELECT]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_FDS_SIDE_SELECT)); combined = "&Switch Disk Side\t" + combo; ChangeMenuItemText(MENU_SWITCH_DISK, combined); //Insert Coin - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_VSUNI_COIN]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_VSUNI_COIN)); combined = "&Insert Coin\t" + combo; ChangeMenuItemText(MENU_INSERT_COIN, combined); //Speed Up - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SPEED_FASTER]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_SPEED_FASTER)); combined = "Speed &Up\t" + combo; ChangeMenuItemText(ID_NES_SPEEDUP, combined); //Slow Down - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SPEED_SLOWER]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_SPEED_SLOWER)); combined = "Slow &Down\t" + combo; ChangeMenuItemText(ID_NES_SLOWDOWN, combined); //Pause - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_PAUSE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_PAUSE)); combined = "&Pause\t" + combo; ChangeMenuItemText(ID_NES_PAUSE, combined); //Slowest Speed - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SPEED_SLOWEST]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_SPEED_SLOWEST)); combined = "&Slowest Speed\t" + combo; ChangeMenuItemText(ID_NES_SLOWESTSPEED, combined); //Normal Speed - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SPEED_NORMAL]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_SPEED_NORMAL)); combined = "&Normal Speed\t" + combo; ChangeMenuItemText(ID_NES_NORMALSPEED, combined); //Turbo - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_SPEED_TURBO_TOGGLE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_SPEED_TURBO_TOGGLE)); combined = "&Turbo\t" + combo; ChangeMenuItemText(ID_NES_TURBO, combined); //-------------------------------Config------------------------------------- //Hide Menu - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_HIDE_MENU_TOGGLE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_HIDE_MENU_TOGGLE)); combined = "&Hide Menu\t" + combo; ChangeMenuItemText(MENU_HIDE_MENU, combined); //Frame Adv. skip lag - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_FRAMEADV_SKIPLAG]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_FRAMEADV_SKIPLAG)); combined = "&Frame Adv. - Skip Lag\t" + combo; ChangeMenuItemText(MENU_DISPLAY_FA_LAGSKIP, combined); //Lag Counter - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MISC_DISPLAY_LAGCOUNTER_TOGGLE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MISC_DISPLAY_LAGCOUNTER_TOGGLE)); combined = "&Lag Counter\t" + combo; ChangeMenuItemText(MENU_DISPLAY_LAGCOUNTER, combined); //Frame Counter - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_FRAME_DISPLAY_TOGGLE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MOVIE_FRAME_DISPLAY_TOGGLE)); combined = "&Frame Counter\t" + combo; ChangeMenuItemText(ID_DISPLAY_FRAMECOUNTER, combined); //Rerecord Counter - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_RERECORD_DISPLAY_TOGGLE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_RERECORD_DISPLAY_TOGGLE)); combined = "&Rerecord Counter\t" + combo; ChangeMenuItemText(ID_DISPLAY_RERECORDCOUNTER, combined); //Movie status icon - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MOVIE_ICON_DISPLAY_TOGGLE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MOVIE_ICON_DISPLAY_TOGGLE)); combined = "&Movie status icon\t" + combo; ChangeMenuItemText(ID_DISPLAY_MOVIESTATUSICON, combined); //FPS counter - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_FPS_DISPLAY_TOGGLE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_FPS_DISPLAY_TOGGLE)); combined = "FPS\t" + combo; ChangeMenuItemText(ID_DISPLAY_FPS, combined); //Graphics: BG - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MISC_DISPLAY_BG_TOGGLE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MISC_DISPLAY_BG_TOGGLE)); combined = "Graphics: &BG\t" + combo; ChangeMenuItemText(MENU_DISPLAY_BG, combined); //Graphics: OBJ - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MISC_DISPLAY_OBJ_TOGGLE]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MISC_DISPLAY_OBJ_TOGGLE)); combined = "Graphics: &OBJ\t" + combo; ChangeMenuItemText(MENU_DISPLAY_OBJ, combined); //-------------------------------Tools-------------------------------------- //Open Cheats - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_TOOL_OPENCHEATS]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_TOOL_OPENCHEATS)); combined = "&Cheats...\t" + combo; ChangeMenuItemText(MENU_CHEATS, combined); //Open RAM Search - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_TOOL_OPENRAMSEARCH]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_TOOL_OPENRAMSEARCH)); combined = "&RAM Search...\t" + combo; ChangeMenuItemText(ID_RAM_SEARCH, combined); //Open RAM Watch - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_TOOL_OPENRAMWATCH]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_TOOL_OPENRAMWATCH)); combined = "&RAM Watch...\t" + combo; ChangeMenuItemText(ID_RAM_WATCH, combined); //Open Memory Watch - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_TOOL_OPENMEMORYWATCH]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_TOOL_OPENMEMORYWATCH)); combined = "&Memory Watch...\t" + combo; ChangeMenuItemText(MENU_MEMORY_WATCH, combined); //Open TAS Editor - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_MISC_OPENTASEDITOR]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_MISC_OPENTASEDITOR)); combined = "&TAS Editor...\t" + combo; ChangeMenuItemText(MENU_TASEDITOR, combined); //-------------------------------Debug-------------------------------------- //Open Debugger - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_TOOL_OPENDEBUGGER]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_TOOL_OPENDEBUGGER)); combined = "&Debugger...\t" + combo; ChangeMenuItemText(MENU_DEBUGGER, combined); //Open PPU Viewer - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_TOOL_OPENPPU]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_TOOL_OPENPPU)); combined = "&PPU Viewer...\t" + combo; ChangeMenuItemText(MENU_PPUVIEWER, combined); //Open Nametable Viewer - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_TOOL_OPENNTVIEW]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_TOOL_OPENNTVIEW)); combined = "&Name table Viewer...\t" + combo; ChangeMenuItemText(MENU_NAMETABLEVIEWER, combined); //Open Hex editor - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_TOOL_OPENHEX]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_TOOL_OPENHEX)); combined = "&Hex Editor...\t" + combo; ChangeMenuItemText(MENU_HEXEDITOR, combined); //Open Trace Logger - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_TOOL_OPENTRACELOGGER]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_TOOL_OPENTRACELOGGER)); combined = "&Trace Logger...\t" + combo; ChangeMenuItemText(MENU_TRACELOGGER, combined); //Open Code/Data Logger - combo = GetKeyComboName(FCEUD_CommandMapping[EMUCMD_TOOL_OPENCDLOGGER]); + combo = GetKeyComboName(GetCommandKeyCombo(EMUCMD_TOOL_OPENCDLOGGER)); combined = "&Code/Data Logger...\t" + combo; ChangeMenuItemText(MENU_CDLOGGER, combined); } diff --git a/trunk/src/fceu.cpp b/trunk/src/fceu.cpp index da418b92..f986152b 100644 --- a/trunk/src/fceu.cpp +++ b/trunk/src/fceu.cpp @@ -579,9 +579,9 @@ void FCEUI_Kill(void) { FreeBuffers(); } -int rapidAlternator = 0; -int AutoFirePattern[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; -int AutoFirePatternLength = 2; +static int rapidAlternator = 0; +static int AutoFirePattern[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; +static int AutoFirePatternLength = 2; void SetAutoFirePattern(int onframes, int offframes) { int i; @@ -619,6 +619,10 @@ void AutoFire(void) { } } +int GetRapidAlternatorState() { + return rapidAlternator; +} + void UpdateAutosave(void); ///Emulates a single frame. diff --git a/trunk/src/fceu.h b/trunk/src/fceu.h index 2e8d6545..ca80aa35 100644 --- a/trunk/src/fceu.h +++ b/trunk/src/fceu.h @@ -31,6 +31,8 @@ void PowerNES(void); void SetAutoFireOffset(int offset); void SetAutoFirePattern(int onframes, int offframes); void AutoFire(void); +int GetRapidAlternatorState(void); + void FCEUI_RewindToLastAutosave(void); //mbg 7/23/06 diff --git a/trunk/src/git.h b/trunk/src/git.h index d541cf1a..71ebd94c 100644 --- a/trunk/src/git.h +++ b/trunk/src/git.h @@ -64,20 +64,20 @@ enum ESIFC { SIFC_UNSET = -1, SIFC_NONE = 0, - SIFC_ARKANOID = 1, - SIFC_SHADOW = 2, - SIFC_4PLAYER = 3, - SIFC_FKB = 4, - SIFC_SUBORKB = 5, - SIFC_PEC586KB = 6, - SIFC_HYPERSHOT = 7, - SIFC_MAHJONG = 8, - SIFC_QUIZKING = 9, - SIFC_FTRAINERA = 10, - SIFC_FTRAINERB = 11, - SIFC_OEKAKIDS = 12, - SIFC_BWORLD = 13, - SIFC_TOPRIDER = 14, + SIFC_ARKANOID, + SIFC_SHADOW, + SIFC_4PLAYER, + SIFC_FKB, + SIFC_SUBORKB, + SIFC_PEC586KB, + SIFC_HYPERSHOT, + SIFC_MAHJONG, + SIFC_PARTYTAP, + SIFC_FTRAINERA, + SIFC_FTRAINERB, + SIFC_OEKAKIDS, + SIFC_BBATTLER, + SIFC_TOPRIDER, SIFC_COUNT = SIFC_TOPRIDER }; @@ -96,11 +96,11 @@ inline const char* ESIFC_Name(ESIFC esifc) "PEC586 Keyboard", "HyperShot Pads", "Mahjong", - "Quiz King Buzzers", + "Party Tap Buzzers", "Family Trainer A", "Family Trainer B", "Oeka Kids Tablet", - "Barcode World", + "Barcode Battler", "Top Rider" }; diff --git a/trunk/src/ines.cpp b/trunk/src/ines.cpp index 8b7629c4..6fa8ad16 100644 --- a/trunk/src/ines.cpp +++ b/trunk/src/ines.cpp @@ -148,7 +148,7 @@ static void SetInput(void) { {0x0f141525, SI_UNSET, SI_UNSET, SIFC_ARKANOID }, // Arkanoid 2(J) {0x32fb0583, SI_UNSET, SI_ARKANOID, SIFC_NONE }, // Arkanoid(NES) {0x60ad090a, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERA }, // Athletic World - {0x48ca0ee1, SI_GAMEPAD, SI_GAMEPAD, SIFC_BWORLD }, // Barcode World + {0x48ca0ee1, SI_GAMEPAD, SI_GAMEPAD, SIFC_BBATTLER }, // Barcode World {0x4318a2f8, SI_UNSET, SI_ZAPPER, SIFC_NONE }, // Barker Bill's Trick Shooting {0x6cca1c1f, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, // Dai Undoukai {0x24598791, SI_UNSET, SI_ZAPPER, SIFC_NONE }, // Duck Hunt @@ -161,8 +161,8 @@ static void SetInput(void) { {0xea90f3e2, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, // Family Trainer: Running Stadium {0xbba58be5, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, // Family Trainer: Manhattan Police {0x3e58a87e, SI_UNSET, SI_ZAPPER, SIFC_NONE }, // Freedom Force - {0xd9f45be9, SI_GAMEPAD, SI_GAMEPAD, SIFC_QUIZKING }, // Gimme a Break ... - {0x1545bd13, SI_GAMEPAD, SI_GAMEPAD, SIFC_QUIZKING }, // Gimme a Break ... 2 + {0xd9f45be9, SI_GAMEPAD, SI_GAMEPAD, SIFC_PARTYTAP }, // Gimme a Break ... + {0x1545bd13, SI_GAMEPAD, SI_GAMEPAD, SIFC_PARTYTAP }, // Gimme a Break ... 2 {0x4e959173, SI_UNSET, SI_ZAPPER, SIFC_NONE }, // Gotcha! - The Sport! {0xbeb8ab01, SI_UNSET, SI_ZAPPER, SIFC_NONE }, // Gumshoe {0xff24d794, SI_UNSET, SI_ZAPPER, SIFC_NONE }, // Hogan's Alley diff --git a/trunk/src/input.cpp b/trunk/src/input.cpp index 58765e75..b3cdb26a 100644 --- a/trunk/src/input.cpp +++ b/trunk/src/input.cpp @@ -35,6 +35,7 @@ #include "vsuni.h" #include "fds.h" #include "driver.h" +#include "utils/bitflags.h" #ifdef WIN32 #include "drivers/win/main.h" @@ -71,12 +72,12 @@ extern INPUTCFC *FCEU_InitSuborKB(void); extern INPUTCFC *FCEU_InitPEC586KB(void); extern INPUTCFC *FCEU_InitHS(void); extern INPUTCFC *FCEU_InitMahjong(void); -extern INPUTCFC *FCEU_InitQuizKing(void); +extern INPUTCFC *FCEU_InitPartyTap(void); extern INPUTCFC *FCEU_InitFamilyTrainerA(void); extern INPUTCFC *FCEU_InitFamilyTrainerB(void); extern INPUTCFC *FCEU_InitOekaKids(void); extern INPUTCFC *FCEU_InitTopRider(void); -extern INPUTCFC *FCEU_InitBarcodeWorld(void); +extern INPUTCFC *FCEU_InitBarcodeBattler(void); //--------------- //global lag variables @@ -87,11 +88,13 @@ extern bool frameAdvanceLagSkip; extern bool movieSubtitles; //------------- +static int CommandMapping[EMUCMD_MAX]; + static uint8 joy_readbit[2]; uint8 joy[4]={0,0,0,0}; //HACK - should be static but movie needs it static uint8 LastStrobe; -bool replaceP2StartWithMicrophone = false; +static bool replaceP2StartWithMicrophone = false; //This function is a quick hack to get the NSF player to use emulated gamepad input. uint8 FCEU_GetJoyJoy(void) @@ -442,8 +445,8 @@ static void SetInputStuffFC() case SIFC_MAHJONG: portFC.driver=FCEU_InitMahjong(); break; - case SIFC_QUIZKING: - portFC.driver=FCEU_InitQuizKing(); + case SIFC_PARTYTAP: + portFC.driver=FCEU_InitPartyTap(); break; case SIFC_FTRAINERA: portFC.driver=FCEU_InitFamilyTrainerA(); @@ -451,8 +454,8 @@ static void SetInputStuffFC() case SIFC_FTRAINERB: portFC.driver=FCEU_InitFamilyTrainerB(); break; - case SIFC_BWORLD: - portFC.driver=FCEU_InitBarcodeWorld(); + case SIFC_BBATTLER: + portFC.driver=FCEU_InitBarcodeBattler(); break; case SIFC_TOPRIDER: portFC.driver=FCEU_InitTopRider(); @@ -505,13 +508,20 @@ bool FCEUI_GetInputFourscore() { return FSAttached; } +void FCEUI_SetInputFourscore(bool attachFourscore) +{ + FSAttached = attachFourscore; +} bool FCEUI_GetInputMicrophone() { return replaceP2StartWithMicrophone; } -void FCEUI_SetInputFourscore(bool attachFourscore) +void FCEUI_SetInputMicrophone(bool set) { - FSAttached = attachFourscore; + replaceP2StartWithMicrophone = set; +} +bool& _FIXME_GetReplaceP2StartWithMicrophoneVar() { + return replaceP2StartWithMicrophone; } //mbg 6/18/08 HACK @@ -528,6 +538,29 @@ SFORMAT FCEUCTRL_STATEINFO[]={ { 0 } }; +KeyCombo GetCommandKeyCombo(EMUCMD command) { + return KeyCombo(CommandMapping[command]); +} + +void SetCommandKeyCombo(EMUCMD command, KeyCombo combo) { + // there is no difference between left and right modifiers when command is triggered, + // reduce l/r modifiers to only left modifiers here to simplify testing + if(FL_TEST(combo.get(), KeyCombo::CTRL_BIT) != 0) { + combo.clearModifiers(KeyCombo::RCTRL_BIT); + combo.setModifiers(KeyCombo::LCTRL_BIT); + } + if(FL_TEST(combo.get(), KeyCombo::SHIFT_BIT) != 0) { + combo.clearModifiers(KeyCombo::RSHIFT_BIT); + combo.setModifiers(KeyCombo::LSHIFT_BIT); + } + if(FL_TEST(combo.get(), KeyCombo::ALT_BIT) != 0) { + combo.clearModifiers(KeyCombo::RALT_BIT); + combo.setModifiers(KeyCombo::LALT_BIT); + } + + CommandMapping[command] = combo.get(); +} + void FCEU_DoSimpleCommand(int cmd) { switch(cmd) @@ -811,9 +844,67 @@ struct EMUCMDTABLE FCEUI_CommandTable[]= #define NUM_EMU_CMDS (sizeof(FCEUI_CommandTable)/sizeof(FCEUI_CommandTable[0])) -static int execcmd, i; +static EMUCMD execcmd; +static int i; -void FCEUI_HandleEmuCommands(TestCommandState* testfn) + +keyCombo_::keyCombo_(uint32 combo) + : mCombo(combo) +{} + +uint32 KeyCombo::get() const { + return mCombo; +} + +void KeyCombo::assign(uint32 combo) { + mCombo = combo; +} + +uint32 KeyCombo::getKey() const { + return FL_TEST(mCombo, KEY_MASK); +} + +void KeyCombo::setKey(int keyCode) { + keyCode = FL_TEST(keyCode, KEY_MASK); // make sure only code bits are affected + FL_CLEAR(mCombo, KEY_MASK); + mCombo |= keyCode; +} + +uint32 KeyCombo::getMeta() const { + return FL_TEST(mCombo, META_MASK); +} + +void KeyCombo::setMeta(int meta) { + meta = FL_TEST(meta, META_MASK); // make sure only meta bits are affected + FL_CLEAR(mCombo, META_MASK); + FL_SET(mCombo, meta); +} + +uint32 KeyCombo::getModifiers() const { + return FL_TEST(mCombo, MOD_MASK); +} + +void KeyCombo::setModifiers(uint32 mask) { + mask = FL_TEST(mask, MOD_MASK); // make sure only modifier bits are affected + FL_SET(mCombo, mask); +} + +void KeyCombo::clearModifiers(uint32 mask) { + mask = FL_TEST(mask, MOD_MASK); // make sure only modifier bits are affected + FL_CLEAR(mCombo, mask); +} + +bool KeyCombo::isEmpty() const { + return (mCombo == 0); +} + + +static TestCommandState* testCommandCallback = NULL; +void FCEUI_SetTestCommandHotkeyCallback(TestCommandState* cbf) { + testCommandCallback = cbf; +} + +void FCEUI_HandleEmuCommands() { bool taseditor = FCEUMOV_Mode(MOVIEMODE_TASEDITOR); for(i=0; i +// macro def used to isolate transformer board specific code +#define KEYBOARDTRANSFORMER_SPECIFIC + + void LagCounterToggle(void); class MovieRecord; @@ -105,16 +109,13 @@ void FCEU_DoSimpleCommand(int cmd); enum EMUCMD { - EMUCMD_POWER=0, + EMUCMD_NONE=0, + EMUCMD_POWER, EMUCMD_RESET, EMUCMD_PAUSE, EMUCMD_FRAME_ADVANCE, EMUCMD_SCREENSHOT, EMUCMD_HIDE_MENU_TOGGLE, - //fixed: current command key handling handle only command table record index with - //the same as cmd enumerarot index, or else does wrong key mapping, fixed it but placed this enum here anyway - //...i returned it back. - //adelikat, try to find true cause of problem before reversing it EMUCMD_EXIT, EMUCMD_SPEED_SLOWEST, @@ -274,8 +275,8 @@ enum EMUCMDFLAG struct EMUCMDTABLE { - int cmd; - int type; + EMUCMD cmd; + EMUCMDTYPE type; EMUCMDFN* fn_on; EMUCMDFN* fn_off; int state; @@ -285,10 +286,64 @@ struct EMUCMDTABLE extern struct EMUCMDTABLE FCEUI_CommandTable[]; +// emulator command key combo (key scan + optional modifiers) +typedef struct keyCombo_ { +public: + keyCombo_(uint32 combo); + +public: + uint32 get(void) const; + void assign(uint32 combo); + + uint32 getKey(void) const; // get key scan code + void setKey(int keyCode); + + uint32 getMeta() const; // get combo WITHOUT key scan code + void setMeta(int meta); + + uint32 getModifiers(void) const; // get modifier flags + void setModifiers(uint32 mask); + void clearModifiers(uint32 mask); + + bool isEmpty(void) const; + +public: + static const uint32 KEY_MASK = 0xff; + static const uint32 META_MASK = (~KEY_MASK); + static const uint32 MOD_MASK = 0xffff0000; + static const uint32 LSHIFT_BIT = (1<<16); + static const uint32 RSHIFT_BIT = (1<<17); + static const uint32 SHIFT_BIT = LSHIFT_BIT|RSHIFT_BIT; + static const uint32 LCTRL_BIT = (1<<18); + static const uint32 RCTRL_BIT = (1<<19); + static const uint32 CTRL_BIT = LCTRL_BIT|RCTRL_BIT; + static const uint32 LALT_BIT = (1<<20); + static const uint32 RALT_BIT = (1<<21); + static const uint32 ALT_BIT = LALT_BIT|RALT_BIT; + +private: + uint32 mCombo; +} KeyCombo; + +KeyCombo GetCommandKeyCombo(EMUCMD command); +void SetCommandKeyCombo(EMUCMD command, KeyCombo combo); + +///A callback that the emu core uses to poll the state of a given emulator command key +typedef int TestCommandState(EMUCMD cmd); +///Assign callback function to test command keycombo state +void FCEUI_SetTestCommandHotkeyCallback(TestCommandState* cbf); +///Signals the emu core to poll for emulator commands and take actions +void FCEUI_HandleEmuCommands(void); + extern unsigned int lagCounter; extern bool lagCounterDisplay; extern char lagFlag; extern bool turbo; void LagCounterReset(); + +bool& _FIXME_GetReplaceP2StartWithMicrophoneVar(void); +int* _FIXME_GetCommandMappingVar(void); +int _FIXME_GetCommandMappingVarSize(void); + #endif //_INPUT_H_ diff --git a/trunk/src/input/bworld.cpp b/trunk/src/input/bworld.cpp index 27d784cc..04f36fc3 100644 --- a/trunk/src/input/bworld.cpp +++ b/trunk/src/input/bworld.cpp @@ -65,10 +65,10 @@ static void Update(void *data, int arg) } } -static INPUTCFC BarcodeWorld={Read,Write,0,Update,0,0}; +static INPUTCFC BarcodeBattler={Read,Write,0,Update,0,0}; -INPUTCFC *FCEU_InitBarcodeWorld(void) +INPUTCFC *FCEU_InitBarcodeBattler(void) { - return(&BarcodeWorld); + return(&BarcodeBattler); } diff --git a/trunk/src/input/fkb.h b/trunk/src/input/fkb.h index d635d9d3..9dd822de 100644 --- a/trunk/src/input/fkb.h +++ b/trunk/src/input/fkb.h @@ -1,3 +1,5 @@ +#define NUMKEYS_FAMIKB (72) + #define FKB_F1 0x01 #define FKB_F2 0x02 #define FKB_F3 0x03 diff --git a/trunk/src/input/ftrainer.h b/trunk/src/input/ftrainer.h new file mode 100644 index 00000000..03a7f69f --- /dev/null +++ b/trunk/src/input/ftrainer.h @@ -0,0 +1 @@ +#define NUMKEYS_FAMITRAINER (12) diff --git a/trunk/src/input/gamepad.h b/trunk/src/input/gamepad.h new file mode 100644 index 00000000..973def79 --- /dev/null +++ b/trunk/src/input/gamepad.h @@ -0,0 +1,14 @@ +#define GPAD_COUNT 4 // max number of gamepads +#define GPAD_NUMKEYS 10 // number of CONFIGURABLE keys per gamepad + // as an input device gamepad still have only 8 'ports' (10 + // minus turbo A and B, delivered through normal A and B buttons) + +// gamepad state bitmasks +#define GPAD_A 0x1 +#define GPAD_B 0x2 +#define GPAD_SELECT 0x4 +#define GPAD_START 0x8 +#define GPAD_UP 0x10 +#define GPAD_DOWN 0x20 +#define GPAD_LEFT 0x40 +#define GPAD_RIGHT 0x80 diff --git a/trunk/src/input/hypershot.h b/trunk/src/input/hypershot.h new file mode 100644 index 00000000..aa257b2c --- /dev/null +++ b/trunk/src/input/hypershot.h @@ -0,0 +1 @@ +#define NUMKEYS_HYPERSHOT (4) diff --git a/trunk/src/input/mahjong.h b/trunk/src/input/mahjong.h new file mode 100644 index 00000000..21d16a3d --- /dev/null +++ b/trunk/src/input/mahjong.h @@ -0,0 +1 @@ +#define NUMKEYS_MAHJONG (21) diff --git a/trunk/src/input/pec586kb.cpp b/trunk/src/input/pec586kb.cpp index 5288760e..e81f1ce9 100644 --- a/trunk/src/input/pec586kb.cpp +++ b/trunk/src/input/pec586kb.cpp @@ -22,7 +22,7 @@ #include "share.h" #include "suborkb.h" -#define AK(x) FKB_ ## x +#define AK(x) SBRKB_ ## x static uint8 bufit[0x66]; static uint8 kspos, kstrobe; diff --git a/trunk/src/input/powerpad.cpp b/trunk/src/input/powerpad.cpp index 98e51aa7..fe4bcae3 100644 --- a/trunk/src/input/powerpad.cpp +++ b/trunk/src/input/powerpad.cpp @@ -20,6 +20,7 @@ #include #include +#include "powerpad.h" #include "share.h" @@ -29,18 +30,18 @@ static uint32 pprdata[2]; static uint8 ReadPP(int w) { - uint8 ret=0; - ret|=((pprdata[w]>>pprsb[w])&1)<<3; - ret|=((pprdata[w]>>(pprsb[w]+8))&1)<<4; - if(pprsb[w]>=4) - { - ret|=0x10; - if(pprsb[w]>=8) - ret|=0x08; - } - if(!fceuindbg) - pprsb[w]++; - return ret; + uint8 ret=0; + ret|=((pprdata[w]>>pprsb[w])&1)<<3; + ret|=((pprdata[w]>>(pprsb[w]+8))&1)<<4; + if(pprsb[w]>=4) + { + ret|=0x10; + if(pprsb[w]>=8) + ret|=0x08; + } + if(!fceuindbg) + pprsb[w]++; + return ret; } static void StrobePP(int w) @@ -50,17 +51,17 @@ static void StrobePP(int w) void UpdatePP(int w, void *data, int arg) { - static const char shifttableA[12]={8,9,0,1,11,7,4,2,10,6,5,3}; - static const char shifttableB[12]={1,0,9,8,2,4,7,11,3,5,6,10}; + static const char shifttableA[NUMKEYS_POWERPAD]={8,9,0,1,11,7,4,2,10,6,5,3}; + static const char shifttableB[NUMKEYS_POWERPAD]={1,0,9,8,2,4,7,11,3,5,6,10}; int x; pprdata[w]=0; if(side=='A') - for(x=0;x<12;x++) + for(x=0;x>x)&1)<>x)&1)< #include "share.h" #include "suborkb.h" -#define AK(x) FKB_ ## x +#define AK(x) SBRKB_ ## x static uint8 bufit[0x66]; static uint8 ksmode; diff --git a/trunk/src/input/suborkb.h b/trunk/src/input/suborkb.h index db01bd4e..a2ac49e6 100644 --- a/trunk/src/input/suborkb.h +++ b/trunk/src/input/suborkb.h @@ -1,102 +1,103 @@ -#define FKB_ESCAPE 0x01 -#define FKB_F1 0x02 -#define FKB_F2 0x03 -#define FKB_F3 0x04 -#define FKB_F4 0x05 -#define FKB_F5 0x06 -#define FKB_F6 0x07 -#define FKB_F7 0x08 -#define FKB_F8 0x09 -#define FKB_F9 0x0A -#define FKB_F10 0x0B -#define FKB_F11 0x0C -#define FKB_F12 0x0D -#define FKB_PAUSE 0x0E -#define FKB_GRAVE 0x0F -#define FKB_1 0x10 -#define FKB_2 0x11 -#define FKB_3 0x12 -#define FKB_4 0x13 -#define FKB_5 0x14 -#define FKB_6 0x15 -#define FKB_7 0x16 -#define FKB_8 0x17 -#define FKB_9 0x18 -#define FKB_0 0x19 -#define FKB_MINUS 0x1A -#define FKB_EQUALS 0x1B -#define FKB_BACK 0x1C -#define FKB_INSERT 0x1D -#define FKB_HOME 0x1E -#define FKB_PRIOR 0x1F -#define FKB_NUMLOCK 0x20 -#define FKB_DIVIDE 0x21 -#define FKB_MULTIPLY 0x22 -#define FKB_SUBTRACT 0x23 -#define FKB_TAB 0x24 -#define FKB_Q 0x25 -#define FKB_W 0x26 -#define FKB_E 0x27 -#define FKB_R 0x28 -#define FKB_T 0x29 -#define FKB_Y 0x2A -#define FKB_U 0x2B -#define FKB_I 0x2C -#define FKB_O 0x2D -#define FKB_P 0x2E -#define FKB_LBRACKET 0x2F -#define FKB_RBRACKET 0x30 -#define FKB_RETURN 0x31 -#define FKB_DELETE 0x32 -#define FKB_END 0x33 -#define FKB_NEXT 0x34 -#define FKB_NUMPAD7 0x35 -#define FKB_NUMPAD8 0x36 -#define FKB_NUMPAD9 0x37 -#define FKB_ADD 0x38 -#define FKB_CAPITAL 0x39 -#define FKB_A 0x3A -#define FKB_S 0x3B -#define FKB_D 0x3C -#define FKB_F 0x3D -#define FKB_G 0x3E -#define FKB_H 0x3F -#define FKB_J 0x40 -#define FKB_K 0x41 -#define FKB_L 0x42 -#define FKB_SEMICOLON 0x43 -#define FKB_APOSTROPHE 0x44 -#define FKB_NUMPAD4 0x45 -#define FKB_NUMPAD5 0x46 -#define FKB_NUMPAD6 0x47 -#define FKB_LSHIFT 0x48 -#define FKB_Z 0x49 -#define FKB_X 0x4A -#define FKB_C 0x4B -#define FKB_V 0x4C -#define FKB_B 0x4D -#define FKB_N 0x4E -#define FKB_M 0x4F -#define FKB_COMMA 0x50 -#define FKB_PERIOD 0x51 -#define FKB_SLASH 0x52 -#define FKB_BACKSLASH 0x53 -#define FKB_UP 0x54 -#define FKB_NUMPAD1 0x55 -#define FKB_NUMPAD2 0x56 -#define FKB_NUMPAD3 0x57 -#define FKB_LCONTROL 0x58 -#define FKB_LMENU 0x59 -#define FKB_SPACE 0x5A -#define FKB_LEFT 0x5B -#define FKB_DOWN 0x5C -#define FKB_RIGHT 0x5D -#define FKB_NUMPAD0 0x5E -#define FKB_DECIMAL 0x5F -#define FKB_RSHIFT 0x60 -#define FKB_RMENU 0x61 -#define FKB_RCONTROL 0x62 -#define FKB_BREAK 0x63 -#define FKB_RESET 0x64 -#define FKB_GRETURN 0x65 +#define NUMKEYS_SUBORKB (101) +#define SBRKB_ESCAPE 0x01 +#define SBRKB_F1 0x02 +#define SBRKB_F2 0x03 +#define SBRKB_F3 0x04 +#define SBRKB_F4 0x05 +#define SBRKB_F5 0x06 +#define SBRKB_F6 0x07 +#define SBRKB_F7 0x08 +#define SBRKB_F8 0x09 +#define SBRKB_F9 0x0A +#define SBRKB_F10 0x0B +#define SBRKB_F11 0x0C +#define SBRKB_F12 0x0D +#define SBRKB_PAUSE 0x0E +#define SBRKB_GRAVE 0x0F +#define SBRKB_1 0x10 +#define SBRKB_2 0x11 +#define SBRKB_3 0x12 +#define SBRKB_4 0x13 +#define SBRKB_5 0x14 +#define SBRKB_6 0x15 +#define SBRKB_7 0x16 +#define SBRKB_8 0x17 +#define SBRKB_9 0x18 +#define SBRKB_0 0x19 +#define SBRKB_MINUS 0x1A +#define SBRKB_EQUALS 0x1B +#define SBRKB_BACK 0x1C +#define SBRKB_INSERT 0x1D +#define SBRKB_HOME 0x1E +#define SBRKB_PRIOR 0x1F +#define SBRKB_NUMLOCK 0x20 +#define SBRKB_DIVIDE 0x21 +#define SBRKB_MULTIPLY 0x22 +#define SBRKB_SUBTRACT 0x23 +#define SBRKB_TAB 0x24 +#define SBRKB_Q 0x25 +#define SBRKB_W 0x26 +#define SBRKB_E 0x27 +#define SBRKB_R 0x28 +#define SBRKB_T 0x29 +#define SBRKB_Y 0x2A +#define SBRKB_U 0x2B +#define SBRKB_I 0x2C +#define SBRKB_O 0x2D +#define SBRKB_P 0x2E +#define SBRKB_LBRACKET 0x2F +#define SBRKB_RBRACKET 0x30 +#define SBRKB_RETURN 0x31 +#define SBRKB_DELETE 0x32 +#define SBRKB_END 0x33 +#define SBRKB_NEXT 0x34 +#define SBRKB_NUMPAD7 0x35 +#define SBRKB_NUMPAD8 0x36 +#define SBRKB_NUMPAD9 0x37 +#define SBRKB_ADD 0x38 +#define SBRKB_CAPITAL 0x39 +#define SBRKB_A 0x3A +#define SBRKB_S 0x3B +#define SBRKB_D 0x3C +#define SBRKB_F 0x3D +#define SBRKB_G 0x3E +#define SBRKB_H 0x3F +#define SBRKB_J 0x40 +#define SBRKB_K 0x41 +#define SBRKB_L 0x42 +#define SBRKB_SEMICOLON 0x43 +#define SBRKB_APOSTROPHE 0x44 +#define SBRKB_NUMPAD4 0x45 +#define SBRKB_NUMPAD5 0x46 +#define SBRKB_NUMPAD6 0x47 +#define SBRKB_LSHIFT 0x48 +#define SBRKB_Z 0x49 +#define SBRKB_X 0x4A +#define SBRKB_C 0x4B +#define SBRKB_V 0x4C +#define SBRKB_B 0x4D +#define SBRKB_N 0x4E +#define SBRKB_M 0x4F +#define SBRKB_COMMA 0x50 +#define SBRKB_PERIOD 0x51 +#define SBRKB_SLASH 0x52 +#define SBRKB_BACKSLASH 0x53 +#define SBRKB_UP 0x54 +#define SBRKB_NUMPAD1 0x55 +#define SBRKB_NUMPAD2 0x56 +#define SBRKB_NUMPAD3 0x57 +#define SBRKB_LCONTROL 0x58 +#define SBRKB_LMENU 0x59 +#define SBRKB_SPACE 0x5A +#define SBRKB_LEFT 0x5B +#define SBRKB_DOWN 0x5C +#define SBRKB_RIGHT 0x5D +#define SBRKB_NUMPAD0 0x5E +#define SBRKB_DECIMAL 0x5F +#define SBRKB_RSHIFT 0x60 +#define SBRKB_RMENU 0x61 +#define SBRKB_RCONTROL 0x62 +#define SBRKB_BREAK 0x63 +#define SBRKB_RESET 0x64 +#define SBRKB_GRETURN 0x65 diff --git a/trunk/src/input/toprider.h b/trunk/src/input/toprider.h new file mode 100644 index 00000000..870e5c1e --- /dev/null +++ b/trunk/src/input/toprider.h @@ -0,0 +1 @@ +#define NUMKEYS_TOPRIDER (8) diff --git a/trunk/src/lua-engine.cpp b/trunk/src/lua-engine.cpp index 53774f7f..ba1dae37 100644 --- a/trunk/src/lua-engine.cpp +++ b/trunk/src/lua-engine.cpp @@ -27,6 +27,7 @@ #ifdef WIN32 #include "drivers/win/common.h" +#include "drivers/win/input.h" #include "drivers/win/taseditor/selection.h" #include "drivers/win/taseditor/laglog.h" #include "drivers/win/taseditor/markers.h" @@ -2394,8 +2395,7 @@ static int joypad_getimmediate(lua_State *L) } // Currently only supports Windows, sorry... #ifdef WIN32 - extern uint32 GetGamepadPressedImmediate(); - uint8 buttons = GetGamepadPressedImmediate() >> ((which - 1) * 8); + uint8 buttons = GetGamepadPressedPhysical() >> ((which - 1) * 8); lua_newtable(L); for (int i = 0; i < 8; ++i) diff --git a/trunk/src/utils/bitflags.h b/trunk/src/utils/bitflags.h index c198766a..6ae26633 100644 --- a/trunk/src/utils/bitflags.h +++ b/trunk/src/utils/bitflags.h @@ -2,9 +2,9 @@ #define BITFLAGS_H // Flag test / set / clear macros for convenience and clarity -#define FL_TEST(var, mask) (var & mask) -#define FL_SET(var, mask) (var |= mask) -#define FL_CLEAR(var, mask) (var &= ~mask) -#define FL_FROMBOOL(var, mask, b) (var = (b)? var|mask:var&(~mask)) +#define FL_TEST(var, mask) ((var) & (mask)) +#define FL_SET(var, mask) ((var) |= (mask)) +#define FL_CLEAR(var, mask) ((var) &= (~mask)) +#define FL_FROMBOOL(var, mask, b) (var = (b)? (var)|(mask):(var)&(~mask)) #endif // BITFLAGS_H diff --git a/trunk/src/video.cpp b/trunk/src/video.cpp index 095d4105..1c93efaf 100644 --- a/trunk/src/video.cpp +++ b/trunk/src/video.cpp @@ -228,7 +228,6 @@ void FCEU_PutImage(void) //Fancy input display code if(input_display) { - extern uint32 JSAutoHeld; uint32 held; int controller, c, ci, color; @@ -253,11 +252,12 @@ void FCEU_PutImage(void) // This doesn't work in anything except windows for now. // It doesn't get set anywhere in other ports. + // FIXME make it work or make it go #ifdef WIN32 - if (!oldInputDisplay) ci = FCEUMOV_Mode(MOVIEMODE_PLAY) ? 0:GetGamepadPressedImmediate() >> (controller * 8); + if (!oldInputDisplay) ci = FCEUMOV_Mode(MOVIEMODE_PLAY) ? 0:GetGamepadPressedPhysical() >> (controller * 8); else ci = 0; - if (!oldInputDisplay && !FCEUMOV_Mode(MOVIEMODE_PLAY)) held = (JSAutoHeld >> (controller * 8)); + if (!oldInputDisplay && !FCEUMOV_Mode(MOVIEMODE_PLAY)) held = (GetAutoHoldMask())[controller]; else held = 0; #else // Put other port info here diff --git a/trunk/vc/vc10_fceux.vcxproj b/trunk/vc/vc10_fceux.vcxproj index 35180975..702e6d4c 100644 --- a/trunk/vc/vc10_fceux.vcxproj +++ b/trunk/vc/vc10_fceux.vcxproj @@ -104,6 +104,7 @@ EditAndContinue Default true + $(IntDir)/%(RelativeDir)/ Rpcrt4.lib;comctl32.lib;vfw32.lib;winmm.lib;ws2_32.lib;htmlhelp.lib;../src/drivers/win/directx/dsound.lib;../src/drivers/win/directx/dxguid.lib;../src/drivers/win/directx/ddraw.lib;../src/drivers/win/directx/dinput.lib;../src/drivers/win/lua/win32/lua51.lib;LuaPerks.lib;psapi.lib;mpr.lib;%(AdditionalDependencies) @@ -393,6 +394,7 @@ + @@ -428,6 +430,8 @@ + + @@ -442,6 +446,7 @@ $(IntDir)%(Filename)1.obj $(IntDir)%(Filename)1.xdc + @@ -868,6 +873,7 @@ + @@ -883,11 +889,15 @@ + + + + @@ -965,8 +975,15 @@ + + + + + + + @@ -978,6 +995,7 @@ + diff --git a/trunk/vc/vc10_fceux.vcxproj.filters b/trunk/vc/vc10_fceux.vcxproj.filters index 920dff8a..38630c0c 100644 --- a/trunk/vc/vc10_fceux.vcxproj.filters +++ b/trunk/vc/vc10_fceux.vcxproj.filters @@ -31,9 +31,6 @@ {8770e1b4-9ef8-4253-bdcd-7c4d5a51461b} - - {aec82faa-87f7-44b0-963e-01b07ce40e82} - {5f356733-cee3-4440-aa40-cf138dcfbd8c} @@ -49,270 +46,18 @@ {cfac36a2-cdfd-4c0a-be8e-353b1303a909} + + {b6b22772-fdf2-4c0b-9f8d-e4082a298865} + - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - drivers\win @@ -629,9 +374,6 @@ drivers\win\lua - - boards - @@ -673,12 +415,6 @@ - - drivers\common - - - boards - drivers\win @@ -739,115 +475,34 @@ drivers\win\taseditor - - boards - drivers\win\taseditor drivers\win\taseditor - + + utils + + boards - + + boards + + boards boards + + boards + boards - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - + boards @@ -856,28 +511,7 @@ boards - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - - boards - - + boards @@ -892,6 +526,9 @@ boards + + boards + boards @@ -901,9 +538,24 @@ boards + + boards + boards + + boards + + + boards + + + boards + + + boards + boards @@ -919,77 +571,410 @@ boards + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + boards - + boards - + boards - + boards - + boards - + boards - + boards - + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + boards boards + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + boards + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + + + boards + boards - - utils - - + boards + + boards + + + boards + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + input + + drivers\win\directinput + + + drivers\win\directinput + + + drivers\win + + + drivers\common + - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - - - drivers\common - drivers\win @@ -1272,15 +1257,6 @@ utils - - drivers\common - - - drivers\common - - - drivers\common - drivers\win @@ -1347,129 +1323,124 @@ drivers\win\taseditor - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - - - include files - utils - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + drivers\common + + + + drivers\win\directinput + + + drivers\win\directinput + + + drivers\win + + + drivers\win + + input + + input + + + input + + + input + + + input + + + input + + + input + + + utils + + + drivers\common +