win/input cleanup, refactoring

This commit is contained in:
rpahut 2014-02-23 15:05:32 +00:00
parent 833649621a
commit 85a6c7fd32
71 changed files with 4023 additions and 3399 deletions

View File

@ -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]) {

View File

@ -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

View File

@ -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;
}

View File

@ -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 <Windows.h>
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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},

View File

@ -7,7 +7,6 @@
#include "drivers/win/video.h"
//extern WAVEFORMATEX wf;
//extern int soundo;
extern int soundrate;

View File

@ -29,7 +29,7 @@
extern HWND hAppWnd;
extern HINSTANCE fceu_hInstance;
extern int NoWaiting;
extern int skipVSync;
extern int eoptions;

View File

@ -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),

View File

@ -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];

View File

@ -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;
}

View File

@ -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

View File

@ -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 <vector>
#include <map>
#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<GUID, directinput::joystick::DEVIDX, compareGUID_> GUID2IDXMAP;
static GUID2IDXMAP guidToIdx;
static std::vector<directinput::joystick::DEVICE*> 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<GUID, directinput::joystick::DEVIDX>(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<directinput::joystick::DEVICE*>::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];
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 <windows.h>
#include <commctrl.h>
#include <sstream>
#include <iomanip>
#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<btnCfg.NumC; btnIdx++) {
if(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);
}

View File

@ -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

View File

@ -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

View File

@ -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];
static int numjoysticks = 0;
static int HavePolled[MAX_JOYSTICKS];
static int background = 0;
static DIJOYSTATE2 StatusSave[MAX_JOYSTICKS];
static DIJOYSTATE2 StatusSaveImmediate[MAX_JOYSTICKS];
static int FindByGUID(GUID how)
{
int x;
for(x=0; x<numjoysticks; x++)
if(!memcmp(&JoyGUID[x], &how, sizeof(GUID)))
return(x);
return(0xFF);
}
#define FPOV_CENTER 16
#define AXIS_DEADZONE (0x10000)
static int POVFix(long pov, int roundpos)
typedef struct {
bool x;
bool y;
} AXES_;
static vector<AXES_> axisHelperFlag;
// some temporary flags to handle axes correctly during input config
static int backgroundAccessBits = 0;
int driver::input::joystick::Init()
{
long lowpov;
directinput::joystick::InitDevices();
return 1;
}
if(LOWORD(pov) == 65535)
return(FPOV_CENTER);
if(roundpos == -1) /* Special case for button configuration */
int driver::input::joystick::Kill()
{
pov /= 4500;
directinput::joystick::ReleaseDevices();
return 1;
}
void driver::input::joystick::Update()
{
int count = directinput::joystick::GetDeviceCount();
for(int i=0; i<count; ++i) {
directinput::joystick::DEVICE* joy = directinput::joystick::GetDevice(i);
if(joy != NULL) joy->isUpdated = false;
}
}
// Convert system pov value [0, 36000) to internal range [0, 4)
static int povToRange(long pov) {
static const int QUARTER = 9000;
static const int EIGHT = QUARTER/2;
if(LOWORD(pov) == 0xFFFF) return FPOV_CENTER;
pov /= EIGHT;
pov = (pov >> 1) + (pov & 1);
pov &= 3;
return(pov);
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);
// 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;
}
typedef struct
bool driver::input::joystick::TestButton(const BtnConfig *btnConfig)
{
LONG MinX;
LONG MaxX;
LONG MinY;
LONG MaxY;
LONG MinZ;
LONG MaxZ;
} POWER_RANGER;
bool isPressed = false;
static POWER_RANGER ranges[MAX_JOYSTICKS];
for(uint32 btnIdx=0; btnIdx<btnConfig->NumC; btnIdx++) {
directinput::joystick::DEVICE* device = directinput::joystick::GetDevice(btnConfig->DeviceInstance[btnIdx]);
if(device == NULL) continue;
// r=diprg.lMax-diprg.lMin;
// JoyXMax[w]=diprg.lMax-(r>>2);
// JoyXMin[w]=diprg.lMin+(r>>2);
if(btnConfig->ButtType[btnIdx] != BtnConfig::BT_JOYSTICK) continue;
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;x<bc->NumC;x++)
{
HRESULT dival;
int n = bc->DeviceNum[x];
if(n == 0xFF)
if(!device->isUpdated) {
if(!directinput::GetState(device->handle, sizeof(DIJOYSTATE2), &device->state)) {
continue;
}
device->isUpdated = true;
}
if(bc->ButtType[x] != BUTTC_JOYSTICK) continue;
if(n >= numjoysticks) continue;
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(!HavePolled[n])
if((btnConfig->IsAxisNegative(btnIdx) && val <= -AXIS_DEADZONE) ||
(!btnConfig->IsAxisNegative(btnIdx) && val >= AXIS_DEADZONE))
{
while((dival = IDirectInputDevice7_Poll(Joysticks[n])) != DI_OK)
{
if(dival == DI_NOEFFECT) break;
isPressed = true;
break;
}
}
else if(btnConfig->IsPovButton(btnIdx)) {
// POV Hat
int srcpov = device->state.rgdwPOV[btnConfig->GetPovController(btnIdx)];
int targetDir = btnConfig->GetPovDir(btnIdx);
if(!JoyAutoRestore(dival,Joysticks[n]))
{
return(0);
if(IsPovInRange(srcpov, targetDir, true)) {
isPressed = true;
break;
}
}
else {
// Button
if(device->state.rgbButtons[btnConfig->GetJoyButton(btnIdx)] & 0x80) {
isPressed = true;
break;
}
}
}
IDirectInputDevice7_GetDeviceState(Joysticks[n],sizeof(DIJOYSTATE2),&StatusSave[n]);
HavePolled[n] = 1;
return isPressed;
}
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)
void driver::input::joystick::BeginWaitButton(PLATFORM_DIALOG_ARGUMENT hwnd)
{
int n;
unsigned int count = directinput::joystick::GetDeviceCount();
axisHelperFlag.resize(count);
for(unsigned int n=0; n<count; ++n) {
axisHelperFlag[n].x = false;
axisHelperFlag[n].y = false;
//StatusSave = malloc(sizeof(DIJOYSTATE2) * numjoysticks);
memset(canax, 0, sizeof(canax));
for(n=0; n<numjoysticks; n++)
{
IDirectInputDevice7_Unacquire(Joysticks[n]);
IDirectInputDevice7_SetCooperativeLevel(Joysticks[n],hwnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);
IDirectInputDevice7_Acquire(Joysticks[n]);
IDirectInputDevice7_Poll(Joysticks[n]);
IDirectInputDevice7_GetDeviceState(Joysticks[n],sizeof(DIJOYSTATE2),&StatusSave[n]);
directinput::SetCoopLevel(directinput::joystick::GetDevice(n)->handle, hwnd, false);
}
}
int DoJoyWaitTest(GUID *guid, uint8 *devicenum, uint16 *buttonnum)
int driver::input::joystick::GetButtonPressedTest(JOYINSTANCEID *guid, uint8 *devicenum, uint16 *buttonnum)
{
int n;
int x;
unsigned int count = directinput::joystick::GetDeviceCount();
for(unsigned int devIdx=0; devIdx<count; ++devIdx) {
directinput::joystick::DEVICE* device = directinput::joystick::GetDevice(devIdx);
for(n=0; n<numjoysticks; n++)
{
HRESULT dival;
DIJOYSTATE2 JoyStatus;
int ba;
while((dival = IDirectInputDevice7_Poll(Joysticks[n])) != DI_OK)
{
if(dival == DI_NOEFFECT) break;
if(!JoyAutoRestore(dival,Joysticks[n])) return(0);
}
dival = IDirectInputDevice7_GetDeviceState(Joysticks[n],sizeof(DIJOYSTATE2),&JoyStatus);
for(ba = 0; ba < 128; ba++)
if((JoyStatus.rgbButtons[ba]&0x80) && !(StatusSave[n].rgbButtons[ba]&0x80))
{
*devicenum = n;
*buttonnum = ba;
*guid = JoyGUID[n];
//memcpy(&StatusSave[n], &JoyStatus, sizeof(DIJOYSTATE2));
memcpy(StatusSave[n].rgbButtons, JoyStatus.rgbButtons, 128);
return(1);
DIJOYSTATE2 immediateState;
if(!directinput::GetState(device->handle, sizeof(DIJOYSTATE2), &immediateState)) {
return 0;
}
memcpy(StatusSave[n].rgbButtons, JoyStatus.rgbButtons, 128);
// 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);
// lX, lY, lZ
long dax, day, daz;
long source,psource;
dax = ranges[n].MaxX - ranges[n].MinX;
day = ranges[n].MaxY - ranges[n].MinY;
daz = ranges[n].MaxZ - ranges[n].MinZ;
if(dax)
{
source=((int64)JoyStatus.lX - ranges[n].MinX) * 262144 / dax - 131072;
psource=((int64)StatusSave[n].lX - ranges[n].MinX) * 262144 / dax - 131072;
if(abs(source) >= 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);
return 1;
}
}
memcpy(&StatusSave[n], &JoyStatus, sizeof(DIJOYSTATE2));
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;
}
return(0);
}
void EndJoyWait(HWND hwnd)
{
int n;
for(n=0; n<numjoysticks; n++)
{
IDirectInputDevice7_Unacquire(Joysticks[n]);
IDirectInputDevice7_SetCooperativeLevel(Joysticks[n],hwnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);
else if(abs(value) <= 0x8000) {
axisHelperFlag[devIdx].x = true;
}
}
int KillJoysticks (void)
{
int x;
long rangeY = device->ranges.range[1];
if(rangeY != 0) {
long value = ((int64)immediateState.lY - device->ranges.base[1]) * 0x40000 / rangeY - 0x20000;
for(x=0; x<numjoysticks; x++)
{
IDirectInputDevice7_Unacquire(Joysticks[x]);
IDirectInputDevice7_Release(Joysticks[x]);
Joysticks[x] = NULL;
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;
}
numjoysticks = 0;
return(1);
}
void JoyClearBC(ButtConfig *bc)
{
uint32 x; //mbg merge 7/17/06 changed to uint
for(x=0; x<bc->NumC; 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; n<numjoysticks; n++)
{
IDirectInputDevice7_Unacquire(Joysticks[n]);
if(background)
IDirectInputDevice7_SetCooperativeLevel(Joysticks[n],hAppWnd,DISCL_BACKGROUND|DISCL_NONEXCLUSIVE);
else
IDirectInputDevice7_SetCooperativeLevel(Joysticks[n],hAppWnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);
IDirectInputDevice7_Acquire(Joysticks[n]);
else if(abs(value) <= 0x8000) {
axisHelperFlag[devIdx].y = true;
}
}
void JoystickSetBackgroundAccessBit(int bit)
{
background |= (1<<bit);
UpdateBackgroundAccess(background != 0);
// 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;
}
void JoystickClearBackgroundAccessBit(int bit)
{
background &= ~(1<<bit);
UpdateBackgroundAccess(background != 0);
}
memcpy(&device->state, &immediateState, sizeof(DIJOYSTATE2));
}
void JoystickSetBackgroundAccess(bool on)
{
if(on)
JoystickSetBackgroundAccessBit(JOYBACKACCESS_OLDSTYLE);
else
JoystickClearBackgroundAccessBit(JOYBACKACCESS_OLDSTYLE);
return 0;
}
void driver::input::joystick::EndWaitButton(PLATFORM_DIALOG_ARGUMENT hwnd)
{
unsigned int count = directinput::joystick::GetDeviceCount();
for(unsigned int n=0; n<count; ++n)
{
directinput::SetCoopLevel(directinput::joystick::GetDevice(n)->handle, 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; n<count; ++n) {
directinput::joystick::DEVICE* device = directinput::joystick::GetDevice(n);
directinput::SetCoopLevel(device->handle, GetMainHWND(), (backgroundAccessBits!=0));
directinput::Acquire(device->handle);
}
}
}
void driver::input::joystick::SetBackgroundAccessBit(driver::input::joystick::BKGINPUT bit)
{
FL_SET(backgroundAccessBits, 1<<bit);
UpdateBackgroundAccess(backgroundAccessBits != 0);
}
void driver::input::joystick::ClearBackgroundAccessBit(driver::input::joystick::BKGINPUT bit)
{
FL_CLEAR(backgroundAccessBits, 1<<bit);
UpdateBackgroundAccess(backgroundAccessBits != 0);
}

View File

@ -4,24 +4,47 @@
#include "common.h"
#include "dinput.h"
#include "input.h"
#include "joystick.h"
#include "directinput/joystick.h"
int InitJoysticks(HWND wnd);
int KillJoysticks(void);
void BeginJoyWait(HWND hwnd);
int DoJoyWaitTest(GUID *guid, uint8 *devicenum, uint16 *buttonnum);
void EndJoyWait(HWND hwnd);
void JoyClearBC(ButtConfig *bc);
void UpdateJoysticks(void);
int DTestButtonJoy(ButtConfig *bc);
#define JOYBACKACCESS_OLDSTYLE 1
#define JOYBACKACCESS_TASEDITOR 2
void JoystickSetBackgroundAccessBit(int bit);
void JoystickClearBackgroundAccessBit(int bit);
void JoystickSetBackgroundAccess(bool on);
namespace driver {
namespace input {
namespace joystick {
#ifdef WIN32
typedef HWND PLATFORM_DIALOG_ARGUMENT;
#else
// TODO
#endif
typedef enum {
BKGINPUT_GENERAL = 1,
BKGINPUT_TASEDITOR
} BKGINPUT;
int Init(void);
int Kill(void);
// Called during normal emulator operation, not during button configuration.
void Update(void);
// Returns true if any of buttons listed in btnConfig is pressed
// Make sure to Update() before testing buttons
bool TestButton(const BtnConfig *bc);
void BeginWaitButton(PLATFORM_DIALOG_ARGUMENT arg);
// Updates input, returns 0 if no buttons pressed, otherwise fills
// arguments with button parameters and returns 1
int GetButtonPressedTest(JOYINSTANCEID *guid, uint8 *devicenum, uint16 *buttonnum);
void EndWaitButton(PLATFORM_DIALOG_ARGUMENT arg);
// Change background access mode for joysticks
void SetBackgroundAccessBit(BKGINPUT bit);
void ClearBackgroundAccessBit(BKGINPUT bit);
};
};
};
#endif // _JOYSTICK_H_

View File

@ -21,208 +21,311 @@
#include "common.h"
#include "dinput.h"
#include "main.h"
#include "window.h"
#include "throttle.h"
#include "input.h"
#include "directinput/directinput.h"
#include "keyboard.h"
#include "keyscan.h"
#include "utils/bitflags.h"
static HRESULT ddrval; //mbg merge 7/17/06 made static
static int background = 0;
static LPDIRECTINPUTDEVICE7 lpdid=0;
void KeyboardClose(void)
{
if(lpdid) IDirectInputDevice7_Unacquire(lpdid);
lpdid=0;
}
static int backgroundInputBits = 0;
static LPDIRECTINPUTDEVICE7 deviceHandle=0;
static unsigned int keys[256] = {0,}; // with repeat
static unsigned int keys_nr[256] = {0,}; // non-repeating
static unsigned int keys_jd[256] = {0,}; // just-down
static unsigned int keys_jd_lock[256] = {0,}; // just-down released lock
int autoHoldKey = 0, autoHoldClearKey = 0;
int ctr=0;
void KeyboardUpdateState(void)
{
unsigned char tk[256];
static driver::input::keyboard::KeysState keyStates = {0,}; // last registered key states
// zero for released keys, non-zero for pressed key
static driver::input::keyboard::KeysState keyStatesDownEvent = {0,}; // non-zero only for keys that were pressed down on last state update
static driver::input::keyboard::KeysState keys_jd_lock = {0,}; // set after key was pressed and held down through at least one state update
static driver::input::keyboard::KeysState validKeyMask = {0,}; // contains 0 for key array elements that aren't mapped to anything
ddrval=IDirectInputDevice7_GetDeviceState(lpdid,256,tk);
if (tk[0]) tk[0] = 0; //adelikat: HACK. If a keyboard key is recognized as this, the effect is that all non assigned hotkeys are run. This prevents the key from being used, but also prevent "hotkey explosion". Also, they essentially couldn't use it anyway since FCEUX doesn't know it is a shift key, and it can't be assigned in the hotkeys
// HACK because DirectInput is totally wacky about recognizing the PAUSE/BREAK key
if(GetAsyncKeyState(VK_PAUSE)) // normally this should have & 0x8000, but apparently this key is too special for that to work
tk[0xC5] = 0x80;
switch(ddrval)
{
case DI_OK: //memcpy(keys,tk,256);break;
break;
//mbg 10/8/2008
//previously only these two cases were handled. this made dwedit's laptop volume keys freak out.
//we're trying this instead
default:
//case DIERR_INPUTLOST:
//case DIERR_NOTACQUIRED:
memset(tk,0,256);
IDirectInputDevice7_Acquire(lpdid);
break;
}
//process keys
extern int soundoptions;
#define SO_OLDUP 32
extern int soundo;
extern int32 fps_scale;
int notAlternateThrottle = !(soundoptions&SO_OLDUP) && soundo && ((NoWaiting&1)?(256*16):fps_scale) >= 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;
}
ddrval=IDirectInputDevice7_SetDataFormat(lpdid,&c_dfDIKeyboard);
if(ddrval != DI_OK)
{
FCEUD_PrintError("DirectInput: Error setting keyboard data format.");
return 0;
}
directinput::Acquire(deviceHandle);
////--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;
// 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;
//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)
void driver::input::keyboard::Update()
{
unsigned char deviceState[256];
bool gotState = directinput::GetState(deviceHandle, sizeof(deviceState), deviceState);
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
// 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;
}
}
}
#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
}
bool driver::input::keyboard::TestButton(const BtnConfig* bc) {
for(uint32 x=0; x<bc->NumC; ++x) {
if(bc->ButtType[x] == BtnConfig::BT_KEYBOARD) {
if(keyStates[bc->GetScanCode(x)]) {
return true;
}
}
}
return false;
}
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;
ddrval=IDirectInputDevice7_Unacquire(lpdid);
static bool bkgModeEnabled = false;
if(bkgModeEnabled != enable) {
bkgModeEnabled = enable;
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)
if(!directinput::SetCoopLevel(deviceHandle, GetMainHWND(), bkgModeEnabled))
{
FCEUD_PrintError("DirectInput: Error setting keyboard cooperative level.");
return;
}
ddrval=IDirectInputDevice7_Acquire(lpdid);
return;
directinput::Acquire(deviceHandle);
}
}
void KeyboardSetBackgroundAccessBit(int bit)
void driver::input::keyboard::SetBackgroundAccessBit(int bit)
{
background |= (1<<bit);
UpdateBackgroundAccess(background != 0);
}
void KeyboardClearBackgroundAccessBit(int bit)
{
background &= ~(1<<bit);
UpdateBackgroundAccess(background != 0);
FL_SET(backgroundInputBits, 1<<bit);
UpdateBackgroundAccess(backgroundInputBits != 0);
}
void KeyboardSetBackgroundAccess(bool on)
void driver::input::keyboard::ClearBackgroundAccessBit(int bit)
{
if(on)
KeyboardSetBackgroundAccessBit(KEYBACKACCESS_OLDSTYLE);
else
KeyboardClearBackgroundAccessBit(KEYBACKACCESS_OLDSTYLE);
FL_CLEAR(backgroundInputBits, 1<<bit);
UpdateBackgroundAccess(backgroundInputBits != 0);
}

View File

@ -1,11 +1,46 @@
void KeyboardClose(void);
int KeyboardInitialize(void);
void KeyboardUpdate(void);
unsigned int *GetKeyboard(void);
unsigned int *GetKeyboard_nr(void);
unsigned int *GetKeyboard_jd(void);
#define KEYBACKACCESS_OLDSTYLE 1
#define KEYBACKACCESS_TASEDITOR 2
void KeyboardSetBackgroundAccessBit(int bit);
void KeyboardClearBackgroundAccessBit(int bit);
void KeyboardSetBackgroundAccess(bool on);
#include "input.h"
namespace driver {
namespace input {
namespace keyboard {
static const int KEYCOUNT = 256;
typedef enum {
BKGINPUT_GENERAL = 1,
BKGINPUT_TASEDITOR
} BKGINPUT;
int Init(void);
void Kill(void);
void Update(void);
// Returns true if any of buttons listed in btnConfig is pressed
// Make sure to Update() before testing buttons
bool TestButton(const BtnConfig* bc);
typedef uint8 KeysState[KEYCOUNT];
typedef const uint8 (& KeysState_const)[KEYCOUNT];
// Returned array indicates currently pressed keys
KeysState_const GetState(void);
// Returned array indicates keys that were just pressed
KeysState_const GetStateJustPressed(void);
// Set/clear particular bit of the background kb input variable
// Background input is enabled if any bit is set and disabled when
// all bits are cleared
void SetBackgroundAccessBit(int bit);
void ClearBackgroundAccessBit(int bit);
};
};
};
#ifdef KEYBOARDTRANSFORMER_SPECIFIC
// !!!Special feature, do not use for anything besides 'Keyboard
// Transformer' board
unsigned int *GetKeyboardAutorepeated(void);
#endif // KEYBOARDTRANSFORMER_SPECIFIC

View File

@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
// TODO: replace literals with proper DirectInput DIK_* symbols
#define SCAN_TILDE 0x29
#define SCAN_1 0x02
#define SCAN_2 0x03
@ -125,5 +127,5 @@
#define SCAN_F11 0x57
#define SCAN_F12 0x58
#define MKK(k) SCAN_##k
#define SCANCODE(k) SCAN_##k
#define MKK_COUNT (256)

View File

@ -176,10 +176,9 @@ int windowedfailed = 0;
static volatile int _userpause = 0; //mbg merge 7/18/06 changed tasbuild was using this only in a couple of places
extern int autoHoldKey, autoHoldClearKey;
extern int frame_display, input_display;
int soundo = 1;
int isSoundEnabled = 1;
int srendlinen = 8;
int erendlinen = 231;
@ -287,7 +286,6 @@ void CreateDirs()
//Fills the BaseDirectory string
//TODO: Potential buffer overflow caused by limited size of BaseDirectory?
void GetBaseDirectory(void)
{
char temp[2048];
@ -485,14 +483,19 @@ void DoPriority()
int DriverInitialize()
{
if(soundo)
soundo = InitSound();
if(!isSoundEnabled || InitSound()) {
InitVideoDriver();
InitInputStuff(); /* Initialize DInput interfaces. */
{
if(InitInputDriver()) {
return 1;
}
ShutdownVideoDriver();
}
if(isSoundEnabled) TrashSoundNow();
}
return 0;
}
static void DriverKill(void)
{
@ -501,11 +504,11 @@ static void DriverKill(void)
sprintf(TempArray, "%s/%s", BaseDirectory.c_str(),cfgFile.c_str());
SaveConfig(TempArray);
DestroyInput();
KillInputDriver();
ShutdownVideoDriver();
if(soundo)
if(isSoundEnabled)
{
TrashSoundNow();
}
@ -646,15 +649,20 @@ int main(int argc,char *argv[])
{
FCEUI_SetGameGenie(genie!=0);
soundo = !!soundo;
isSoundEnabled = !!isSoundEnabled;
frame_display = !!frame_display;
allowUDLR = !!allowUDLR;
pauseAfterPlayback = !!pauseAfterPlayback;
closeFinishedMovie = !!closeFinishedMovie;
EnableBackgroundInput = !!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);
}
FCEUI_SetSoundVolume(soundvolume);
FCEUI_SetSoundQuality(soundquality);
@ -665,10 +673,6 @@ int main(int argc,char *argv[])
FCEUI_SetPCMVolume(soundPCMvol);
}
//Since a game doesn't have to be loaded before the GUI can be used, make
//sure the temporary input type variables are set.
ParseGIInput(NULL);
// Initialize default directories
CreateDirs();
SetDirs();
@ -722,12 +726,6 @@ int main(int argc,char *argv[])
}
}
if(!InitDInput())
{
do_exit();
return 1;
}
if(!DriverInitialize())
{
do_exit();
@ -849,8 +847,11 @@ doloopy:
//xbsave = NULL;
RedrawWindow(hAppWnd,0,0,RDW_ERASE|RDW_INVALIDATE);
}
else
UpdateRawInputAndHotkeys();
else {
// no game; still handle input
FCEUD_UpdateInput(UPDATEINPUT_KEYBOARD|UPDATEINPUT_JOYSTICKS|UPDATEINPUT_COMMANDS);
}
Sleep(50);
if(!exiting)
goto doloopy;
@ -888,7 +889,7 @@ void win_debuggerLoop()
while(FCEUI_EmulationPaused() && !FCEUI_EmulationFrameStepped())
{
Sleep(50);
FCEUD_UpdateInput();
FCEUD_UpdateInput(UPDATEINPUT_EVERYTHING);
_updateWindow();
// HACK: break when Frame Advance is pressed
extern bool frameAdvanceRequested;
@ -910,7 +911,7 @@ void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count)
win_SoundSetScale(fps_scale); //If turboing and mute turbo is true, bypass this
//write all the sound we generated.
if(soundo && Buffer && Count && !(muteTurbo && turbo)) {
if(isSoundEnabled && Buffer && Count && !(muteTurbo && turbo)) {
win_SoundWriteData(Buffer,Count); //If turboing and mute turbo is true, bypass this
}
@ -933,7 +934,7 @@ void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count)
bool throttle = true;
if( (eoptions&EO_NOTHROTTLE) )
{
if(!soundo) throttle = false;
if(!isSoundEnabled) throttle = false;
}
if(throttle) //if throttling is enabled..
@ -943,7 +944,7 @@ void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count)
)
//then throttle
while(SpeedThrottle()) {
FCEUD_UpdateInput();
FCEUD_UpdateInput(UPDATEINPUT_EVERYTHING);
_updateWindow();
}
@ -973,7 +974,7 @@ void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count)
//}
//make sure to update the input once per frame
FCEUD_UpdateInput();
FCEUD_UpdateInput(UPDATEINPUT_EVERYTHING);
}

View File

@ -45,7 +45,6 @@ extern int status_icon;
extern int frame_display;
extern int rerecord_display;
extern int input_display;
extern int allowUDLR;
extern int pauseAfterPlayback;
extern int closeFinishedMovie;
extern int suggestReadOnlyReplay;
@ -116,7 +115,7 @@ static int changerecursive=0;
/// Contains the base directory of FCE
extern std::string BaseDirectory;
extern int soundo;
extern int isSoundEnabled;
extern int eoptions;
extern int soundoptions;
extern uint8 *xbsave;

View File

@ -1,6 +1,6 @@
#include "common.h"
#include "mapinput.h"
#include "input.h"
#include "../../input.h"
#include "keyscan.h"
#include "keyboard.h"
#include "gui.h"
@ -8,7 +8,6 @@
#include <commctrl.h>
#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;
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 ((c & CMD_KEY_CTRL) == CMD_KEY_CTRL)
{
if(!combo.isEmpty()) {
uint32 mods = combo.getModifiers() & KeyCombo::CTRL_BIT;
if (mods == KeyCombo::CTRL_BIT) {
strcat(text, "Ctrl + ");
}
else if ((c & CMD_KEY_CTRL) == CMD_KEY_LCTRL)
{
else if (mods == KeyCombo::LCTRL_BIT) {
strcat(text, "Left Ctrl + ");
}
else if ((c & CMD_KEY_CTRL) == CMD_KEY_RCTRL)
{
else if (mods == KeyCombo::RCTRL_BIT) {
strcat(text, "Right Ctrl + ");
}
if ((c & CMD_KEY_ALT) == CMD_KEY_ALT)
{
mods = combo.getModifiers() & KeyCombo::ALT_BIT;
if (mods == KeyCombo::ALT_BIT) {
strcat(text, "Alt + ");
}
else if ((c & CMD_KEY_ALT) == CMD_KEY_LALT)
{
else if (mods == KeyCombo::LALT_BIT) {
strcat(text, "Left Alt + ");
}
else if ((c & CMD_KEY_ALT) == CMD_KEY_RALT)
{
else if (mods == KeyCombo::RALT_BIT) {
strcat(text, "Right Alt + ");
}
if ((c & CMD_KEY_SHIFT) == CMD_KEY_SHIFT)
{
mods = combo.getModifiers() & KeyCombo::SHIFT_BIT;
if (mods == KeyCombo::SHIFT_BIT) {
strcat(text, "Shift + ");
}
else if ((c & CMD_KEY_SHIFT) == CMD_KEY_LSHIFT)
{
else if (mods == KeyCombo::LSHIFT_BIT) {
strcat(text, "Left Shift + ");
}
else if ((c & CMD_KEY_SHIFT) == CMD_KEY_RSHIFT)
{
else if (mods == KeyCombo::RSHIFT_BIT) {
strcat(text, "Right Shift + ");
}
strcat(text, GetKeyName(c & CMD_KEY_MASK));
strcat(text, GetKeyName(combo.getKey()));
}
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));
}
free(backupmapping);
for(unsigned int i = 0; i < EMUCMD_MAX; ++i) {
SetCommandKeyCombo((EMUCMD)i, KeyCombo(backupmapping[i]));
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -26,6 +26,7 @@ Window - User Interface
#include "../taseditor.h"
#include <htmlhelp.h>
#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

View File

@ -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;
};

View File

@ -1,3 +1,5 @@
extern int32 fps_scale;
void InitSpeedThrottle(void);
int SpeedThrottle(void);
void RefreshThrottleFPS();

View File

@ -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;

View File

@ -26,6 +26,7 @@
#include "gui.h"
#include "../../fceu.h"
#include "../../video.h"
#include "sound.h"
#include "input.h"
#include "mapinput.h"
#include <math.h>
@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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.

View File

@ -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

View File

@ -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"
};

View File

@ -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

View File

@ -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<NUM_EMU_CMDS; ++i)
@ -821,7 +912,7 @@ void FCEUI_HandleEmuCommands(TestCommandState* testfn)
int new_state;
int old_state = FCEUI_CommandTable[i].state;
execcmd = FCEUI_CommandTable[i].cmd;
new_state = (*testfn)(execcmd);
new_state = (testCommandCallback != NULL)? (*testCommandCallback)(execcmd):0;
// in TAS Editor mode forbid commands without EMUCMDFLAG_TASEDITOR flag
bool allow = true;
if(taseditor && !(FCEUI_CommandTable[i].flags & EMUCMDFLAG_TASEDITOR))
@ -1211,3 +1302,12 @@ static void TaseditorCommand(void)
handleEmuCmdByTaseditor(execcmd);
#endif
}
int* _FIXME_GetCommandMappingVar() {
return CommandMapping;
}
int _FIXME_GetCommandMappingVarSize() {
return sizeof(CommandMapping);
}

View File

@ -6,6 +6,10 @@
#include <ostream>
// 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_

View File

@ -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);
}

View File

@ -1,3 +1,5 @@
#define NUMKEYS_FAMIKB (72)
#define FKB_F1 0x01
#define FKB_F2 0x02
#define FKB_F3 0x03

View File

@ -0,0 +1 @@
#define NUMKEYS_FAMITRAINER (12)

14
trunk/src/input/gamepad.h Normal file
View File

@ -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

View File

@ -0,0 +1 @@
#define NUMKEYS_HYPERSHOT (4)

View File

@ -0,0 +1 @@
#define NUMKEYS_MAHJONG (21)

View File

@ -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;

View File

@ -20,6 +20,7 @@
#include <string.h>
#include <stdlib.h>
#include "powerpad.h"
#include "share.h"
@ -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<NUMKEYS_POWERPAD;x++)
pprdata[w]|=(((*(uint32 *)data)>>x)&1)<<shifttableA[x];
else
for(x=0;x<12;x++)
for(x=0;x<NUMKEYS_POWERPAD;x++)
pprdata[w]|=(((*(uint32 *)data)>>x)&1)<<shifttableB[x];
}

View File

@ -0,0 +1 @@
#define NUMKEYS_POWERPAD (12)

View File

@ -66,10 +66,10 @@ static void QZ_Update(void *data, int arg)
QZVal=*(uint8 *)data;
}
static INPUTCFC QuizKing={QZ_Read,QZ_Write,QZ_Strobe,QZ_Update,0,0};
static INPUTCFC PartyTap={QZ_Read,QZ_Write,QZ_Strobe,QZ_Update,0,0};
INPUTCFC *FCEU_InitQuizKing(void)
INPUTCFC *FCEU_InitPartyTap(void)
{
QZVal=QZValR=0;
return(&QuizKing);
return(&PartyTap);
}

1
trunk/src/input/quiz.h Normal file
View File

@ -0,0 +1 @@
#define NUMKEYS_PARTYTAP (6)

View File

@ -21,7 +21,7 @@
#include <string.h>
#include "share.h"
#include "suborkb.h"
#define AK(x) FKB_ ## x
#define AK(x) SBRKB_ ## x
static uint8 bufit[0x66];
static uint8 ksmode;

View File

@ -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

View File

@ -0,0 +1 @@
#define NUMKEYS_TOPRIDER (8)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -104,6 +104,7 @@
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
</ClCompile>
<Link>
<AdditionalDependencies>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)</AdditionalDependencies>
@ -393,6 +394,7 @@
<ClCompile Include="..\src\drivers\common\config.cpp" />
<ClCompile Include="..\src\drivers\common\hq2x.cpp" />
<ClCompile Include="..\src\drivers\common\hq3x.cpp" />
<ClCompile Include="..\src\drivers\common\input.cpp" />
<ClCompile Include="..\src\drivers\common\nes_ntsc.c" />
<ClCompile Include="..\src\drivers\common\scale2x.cpp" />
<ClCompile Include="..\src\drivers\common\scale3x.cpp" />
@ -428,6 +430,8 @@
</ClCompile>
<ClCompile Include="..\src\drivers\win\debugger.cpp" />
<ClCompile Include="..\src\drivers\win\debuggersp.cpp" />
<ClCompile Include="..\src\drivers\win\directinput\directInput.cpp" />
<ClCompile Include="..\src\drivers\win\directinput\joystick.cpp" />
<ClCompile Include="..\src\drivers\win\directories.cpp" />
<ClCompile Include="..\src\drivers\win\gui.cpp" />
<ClCompile Include="..\src\drivers\win\guiconfig.cpp" />
@ -442,6 +446,7 @@
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename)1.obj</ObjectFileName>
<XMLDocumentationFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename)1.xdc</XMLDocumentationFileName>
</ClCompile>
<ClCompile Include="..\src\drivers\win\inputConfigUI.cpp" />
<ClCompile Include="..\src\drivers\win\joystick.cpp" />
<ClCompile Include="..\src\drivers\win\keyboard.cpp" />
<ClCompile Include="..\src\drivers\win\log.cpp" />
@ -868,6 +873,7 @@
<ClInclude Include="..\src\drivers\common\config.h" />
<ClInclude Include="..\src\drivers\common\hq2x.h" />
<ClInclude Include="..\src\drivers\common\hq3x.h" />
<ClInclude Include="..\src\drivers\common\input.h" />
<ClInclude Include="..\src\drivers\common\nes_ntsc.h" />
<ClInclude Include="..\src\drivers\common\nes_ntsc_config.h" />
<ClInclude Include="..\src\drivers\common\nes_ntsc_impl.h" />
@ -883,11 +889,15 @@
<ClInclude Include="..\src\drivers\win\config.h" />
<ClInclude Include="..\src\drivers\win\debugger.h" />
<ClInclude Include="..\src\drivers\win\debuggersp.h" />
<ClInclude Include="..\src\drivers\win\directinput\directinput.h" />
<ClInclude Include="..\src\drivers\win\directinput\joystick.h" />
<ClInclude Include="..\src\drivers\win\directories.h" />
<ClInclude Include="..\src\drivers\win\gui.h" />
<ClInclude Include="..\src\drivers\win\guiconfig.h" />
<ClInclude Include="..\src\drivers\win\help.h" />
<ClInclude Include="..\src\drivers\win\input.h" />
<ClInclude Include="..\src\drivers\win\inputConfigUI.h" />
<ClInclude Include="..\src\drivers\win\inputDevKeyMap.h" />
<ClInclude Include="..\src\drivers\win\joystick.h" />
<ClInclude Include="..\src\drivers\win\keyboard.h" />
<ClInclude Include="..\src\drivers\win\keyscan.h" />
@ -965,8 +975,15 @@
<ClInclude Include="..\src\ines.h" />
<ClInclude Include="..\src\input.h" />
<ClInclude Include="..\src\input\fkb.h" />
<ClInclude Include="..\src\input\ftrainer.h" />
<ClInclude Include="..\src\input\gamepad.h" />
<ClInclude Include="..\src\input\hypershot.h" />
<ClInclude Include="..\src\input\mahjong.h" />
<ClInclude Include="..\src\input\powerpad.h" />
<ClInclude Include="..\src\input\quiz.h" />
<ClInclude Include="..\src\input\share.h" />
<ClInclude Include="..\src\input\suborkb.h" />
<ClInclude Include="..\src\input\toprider.h" />
<ClInclude Include="..\src\movie.h" />
<ClInclude Include="..\src\netplay.h" />
<ClInclude Include="..\src\nsf.h" />
@ -978,6 +995,7 @@
<ClInclude Include="..\src\types-des.h" />
<ClInclude Include="..\src\types.h" />
<ClInclude Include="..\src\unif.h" />
<ClInclude Include="..\src\utils\bitflags.h" />
<ClInclude Include="..\src\utils\ConvertUTF.h" />
<ClInclude Include="..\src\utils\crc32.h" />
<ClInclude Include="..\src\utils\endian.h" />

File diff suppressed because it is too large Load Diff