From 6956f4e5f82f285f4a02b3c8b712c9355517f40e Mon Sep 17 00:00:00 2001 From: tomch Date: Tue, 31 Dec 2013 22:40:10 +0000 Subject: [PATCH] v1.24.0 & (C) 2014 Changed config for joystick emulation by keyboard: {keybd+standard, keybd+centering} -> {keybd:cursor, keybd:numpad} . Added new UI Checkbox for centering control (keybd only) This keeps backward compatibility, but extends to allow joystick emu by cursor keys. NB. Added a warning message when selecting this new joystick emu, as there are limitations. --- AppleWin/resource/Applewin.rc | 13 +- AppleWin/resource/resource.h | 3 +- AppleWin/source/Applewin.cpp | 50 ++++- AppleWin/source/Common.h | 8 +- .../source/Configuration/IPropertySheet.h | 6 +- AppleWin/source/Configuration/PageInput.cpp | 30 +-- AppleWin/source/Configuration/PageInput.h | 13 +- AppleWin/source/Configuration/PropertySheet.h | 6 +- AppleWin/source/Joystick.cpp | 187 ++++++++++-------- AppleWin/source/Joystick.h | 7 + AppleWin/source/SaveState.cpp | 1 + AppleWin/source/StdAfx.h | 1 - 12 files changed, 204 insertions(+), 121 deletions(-) diff --git a/AppleWin/resource/Applewin.rc b/AppleWin/resource/Applewin.rc index 1efc821e..fb8c771e 100644 --- a/AppleWin/resource/Applewin.rc +++ b/AppleWin/resource/Applewin.rc @@ -128,7 +128,8 @@ BEGIN CONTROL "Spin1",IDC_SPIN_YTRIM,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY,161,53,10,14 CONTROL "Allow cursor keys to be read from keyboard ",IDC_CURSORCONTROL, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,75,155,10 - CONTROL "Auto-fire (all 3 buttons)",IDC_AUTOFIRE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,90,155,10 + CONTROL "Auto-fire (all 3 buttons)",IDC_AUTOFIRE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,90,89,10 + CONTROL "Keyboard auto-centering",IDC_CENTERINGCONTROL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,90,96,10 CONTROL "&Scroll Lock acts as toggle for full-speed CPU",IDC_SCROLLLOCK_TOGGLE, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,113,166,10 CONTROL "&Mouse interface in slot 4",IDC_MOUSE_IN_SLOT4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,127,106,10 @@ -249,8 +250,8 @@ DISK_ICON ICON "DISK.ICO" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,23,3,0 - PRODUCTVERSION 1,23,3,0 + FILEVERSION 1,24,0,0 + PRODUCTVERSION 1,24,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -268,12 +269,12 @@ BEGIN VALUE "Comments", "http://applewin.berlios.de" VALUE "CompanyName", "AppleWin" VALUE "FileDescription", "Apple //e Emulator for Windows" - VALUE "FileVersion", "1, 23, 3, 0" + VALUE "FileVersion", "1, 24, 0, 0" VALUE "InternalName", "APPLEWIN" - VALUE "LegalCopyright", " 1994-2013 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis" + VALUE "LegalCopyright", " 1994-2014 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis" VALUE "OriginalFilename", "APPLEWIN.EXE" VALUE "ProductName", "Apple //e Emulator" - VALUE "ProductVersion", "1, 23, 3, 0" + VALUE "ProductVersion", "1, 24, 0, 0" END END BLOCK "VarFileInfo" diff --git a/AppleWin/resource/resource.h b/AppleWin/resource/resource.h index 7d0ef83d..9009b167 100644 --- a/AppleWin/resource/resource.h +++ b/AppleWin/resource/resource.h @@ -103,6 +103,7 @@ #define IDC_APPLEWIN_ICON 1065 #define IDC_CURSORCONTROL 1066 #define IDC_AUTOFIRE 1067 +#define IDC_CENTERINGCONTROL 1068 #define IDM_EXIT 40001 #define IDM_HELP 40002 #define IDM_ABOUT 40003 @@ -122,7 +123,7 @@ #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 146 #define _APS_NEXT_COMMAND_VALUE 40012 -#define _APS_NEXT_CONTROL_VALUE 1068 +#define _APS_NEXT_CONTROL_VALUE 1069 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/AppleWin/source/Applewin.cpp b/AppleWin/source/Applewin.cpp index 9a1b471f..c32814f8 100644 --- a/AppleWin/source/Applewin.cpp +++ b/AppleWin/source/Applewin.cpp @@ -419,6 +419,40 @@ void GetProgramDirectory(void) } //=========================================================================== + +// Backwards compatibility with AppleWin <1.24.0 +static void LoadConfigOldJoystick(const UINT uJoyNum) +{ + DWORD dwOldJoyType; + if (!REGLOAD(TEXT(uJoyNum==0 ? REGVALUE_OLD_JOYSTICK0_EMU_TYPE : REGVALUE_OLD_JOYSTICK1_EMU_TYPE), &dwOldJoyType)) + return; // EG. Old AppleWin never installed + + UINT uNewJoyType; + switch (dwOldJoyType) + { + case 0: // Disabled + default: + uNewJoyType = J0C_DISABLED; + break; + case 1: // PC Joystick + uNewJoyType = J0C_JOYSTICK1; + break; + case 2: // Keyboard (standard) + uNewJoyType = J0C_KEYBD_NUMPAD; + sg_PropertySheet.SetJoystickCenteringControl(JOYSTICK_MODE_FLOATING); + break; + case 3: // Keyboard (centering) + uNewJoyType = J0C_KEYBD_NUMPAD; + sg_PropertySheet.SetJoystickCenteringControl(JOYSTICK_MODE_CENTERING); + break; + case 4: // Mouse + uNewJoyType = J0C_MOUSE; + break; + } + + joytype[uJoyNum] = uNewJoyType; +} + //Reads configuration from the registry entries void LoadConfiguration(void) { @@ -433,7 +467,7 @@ void LoadConfiguration(void) } else // Support older AppleWin registry entries { - REGLOAD(TEXT("Computer Emulation"), &dwComputerType); + REGLOAD(TEXT(REGVALUE_OLD_APPLE2_TYPE), &dwComputerType); switch (dwComputerType) { // NB. No A2TYPE_APPLE2E (this is correct) @@ -452,12 +486,16 @@ void LoadConfiguration(void) case A2TYPE_APPLE2EENHANCED:g_nCharsetType = 0; break; case A2TYPE_PRAVETS82: g_nCharsetType = 1; break; case A2TYPE_PRAVETS8A: g_nCharsetType = 2; break; - case A2TYPE_PRAVETS8M: g_nCharsetType = 3; break; //This charset has a very small difference with the PRAVETS82 one an probably has some misplaced characters. Still the Pravets82 charset is used, because settiong charset to 3 results in some problems. + case A2TYPE_PRAVETS8M: g_nCharsetType = 3; break; //This charset has a very small difference with the PRAVETS82 one an probably has some misplaced characters. Still the Pravets82 charset is used, because setting charset to 3 results in some problems. } + // + + if (!REGLOAD(TEXT(REGVALUE_JOYSTICK0_EMU_TYPE), &joytype[JN_JOYSTICK0])) + LoadConfigOldJoystick(JN_JOYSTICK0); + if (!REGLOAD(TEXT(REGVALUE_JOYSTICK1_EMU_TYPE), &joytype[JN_JOYSTICK1])) + LoadConfigOldJoystick(JN_JOYSTICK1); - REGLOAD(TEXT("Joystick 0 Emulation"),&joytype[0]); - REGLOAD(TEXT("Joystick 1 Emulation"),&joytype[1]); REGLOAD(TEXT("Sound Emulation") ,&soundtype); char aySerialPortName[ CSuperSerialCard::SIZEOF_SERIALCHOICE_ITEM ]; @@ -527,9 +565,11 @@ void LoadConfiguration(void) sg_PropertySheet.SetScrollLockToggle(dwTmp); if(REGLOAD(TEXT(REGVALUE_CURSOR_CONTROL), &dwTmp)) - sg_PropertySheet.SetCursorControl(dwTmp); + sg_PropertySheet.SetJoystickCursorControl(dwTmp); if(REGLOAD(TEXT(REGVALUE_AUTOFIRE), &dwTmp)) sg_PropertySheet.SetAutofire(dwTmp); + if(REGLOAD(TEXT(REGVALUE_CENTERING_CONTROL), &dwTmp)) + sg_PropertySheet.SetJoystickCenteringControl(dwTmp); if(REGLOAD(TEXT(REGVALUE_MOUSE_CROSSHAIR), &dwTmp)) sg_PropertySheet.SetMouseShowCrosshair(dwTmp); diff --git a/AppleWin/source/Common.h b/AppleWin/source/Common.h index 2849bc2f..ae136499 100644 --- a/AppleWin/source/Common.h +++ b/AppleWin/source/Common.h @@ -73,15 +73,21 @@ enum AppMode_e // Configuration #define REG_CONFIG "Configuration" #define REGVALUE_APPLE2_TYPE "Apple2 Type" +#define REGVALUE_OLD_APPLE2_TYPE "Computer Emulation" // Deprecated #define REGVALUE_SPKR_VOLUME "Speaker Volume" #define REGVALUE_MB_VOLUME "Mockingboard Volume" #define REGVALUE_SAVESTATE_FILENAME "Save State Filename" #define REGVALUE_SAVE_STATE_ON_EXIT "Save State On Exit" #define REGVALUE_HDD_ENABLED "Harddisk Enable" +#define REGVALUE_JOYSTICK0_EMU_TYPE "Joystick0 Emu Type" // Added at 1.24.0 (previously was "Joystick 0 Emulation") +#define REGVALUE_JOYSTICK1_EMU_TYPE "Joystick1 Emu Type" // Added at 1.24.0 (previously was "Joystick 1 Emulation") +#define REGVALUE_OLD_JOYSTICK0_EMU_TYPE "Joystick 0 Emulation" // Deprecated from 1.24.0 +#define REGVALUE_OLD_JOYSTICK1_EMU_TYPE "Joystick 1 Emulation" // Deprecated from 1.24.0 #define REGVALUE_PDL_XTRIM "PDL X-Trim" #define REGVALUE_PDL_YTRIM "PDL Y-Trim" #define REGVALUE_SCROLLLOCK_TOGGLE "ScrollLock Toggle" -#define REGVALUE_CURSOR_CONTROL "Cursor Control" +#define REGVALUE_CURSOR_CONTROL "Joystick Cursor Control" +#define REGVALUE_CENTERING_CONTROL "Joystick Centering Control" #define REGVALUE_AUTOFIRE "Autofire" #define REGVALUE_MOUSE_CROSSHAIR "Mouse crosshair" #define REGVALUE_MOUSE_RESTRICT_TO_WINDOW "Mouse restrict to window" diff --git a/AppleWin/source/Configuration/IPropertySheet.h b/AppleWin/source/Configuration/IPropertySheet.h index b526c469..c25b2ce8 100644 --- a/AppleWin/source/Configuration/IPropertySheet.h +++ b/AppleWin/source/Configuration/IPropertySheet.h @@ -8,8 +8,10 @@ __interface IPropertySheet UINT GetScrollLockToggle(void); void SetScrollLockToggle(UINT uValue); - UINT GetCursorControl(void); - void SetCursorControl(UINT uValue); + UINT GetJoystickCursorControl(void); + void SetJoystickCursorControl(UINT uValue); + UINT GetJoystickCenteringControl(void); + void SetJoystickCenteringControl(UINT uValue); UINT GetAutofire(UINT uButton); void SetAutofire(UINT uValue); UINT GetMouseShowCrosshair(void); diff --git a/AppleWin/source/Configuration/PageInput.cpp b/AppleWin/source/Configuration/PageInput.cpp index accd6fb4..7184ed98 100644 --- a/AppleWin/source/Configuration/PageInput.cpp +++ b/AppleWin/source/Configuration/PageInput.cpp @@ -8,8 +8,8 @@ CPageInput* CPageInput::ms_this = 0; // reinit'd in ctor const TCHAR CPageInput::m_szJoyChoice0[] = TEXT("Disabled\0"); const TCHAR CPageInput::m_szJoyChoice1[] = TEXT("PC Joystick #1\0"); const TCHAR CPageInput::m_szJoyChoice2[] = TEXT("PC Joystick #2\0"); -const TCHAR CPageInput::m_szJoyChoice3[] = TEXT("Keyboard (standard)\0"); -const TCHAR CPageInput::m_szJoyChoice4[] = TEXT("Keyboard (centering)\0"); +const TCHAR CPageInput::m_szJoyChoice3[] = TEXT("Keyboard (cursors)\0"); +const TCHAR CPageInput::m_szJoyChoice4[] = TEXT("Keyboard (numpad)\0"); const TCHAR CPageInput::m_szJoyChoice5[] = TEXT("Mouse\0"); const TCHAR* const CPageInput::m_pszJoy0Choices[J0C_MAX] = { @@ -166,6 +166,7 @@ BOOL CPageInput::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM CheckDlgButton(hWnd, IDC_CURSORCONTROL, m_uCursorControl ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hWnd, IDC_AUTOFIRE, m_bmAutofire ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hWnd, IDC_CENTERINGCONTROL, m_uCenteringControl == JOYSTICK_MODE_CENTERING ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hWnd, IDC_SCROLLLOCK_TOGGLE, m_uScrollLockToggle ? BST_CHECKED : BST_UNCHECKED); InitOptions(hWnd); @@ -185,12 +186,12 @@ void CPageInput::DlgOK(HWND hWnd) if (JoySetEmulationType(hWnd, m_nJoy0ChoiceTranlationTbl[uNewJoyType0], JN_JOYSTICK0, bIsSlot4Mouse)) { - REGSAVE(TEXT("Joystick 0 Emulation"), joytype[0]); + REGSAVE(TEXT(REGVALUE_JOYSTICK0_EMU_TYPE), joytype[0]); } if (JoySetEmulationType(hWnd, m_nJoy1ChoiceTranlationTbl[uNewJoyType1], JN_JOYSTICK1, bIsSlot4Mouse)) { - REGSAVE(TEXT("Joystick 1 Emulation"), joytype[1]); + REGSAVE(TEXT(REGVALUE_JOYSTICK1_EMU_TYPE), joytype[1]); } JoySetTrim((short)SendDlgItemMessage(hWnd, IDC_SPIN_XTRIM, UDM_GETPOS, 0, 0), true); @@ -198,6 +199,7 @@ void CPageInput::DlgOK(HWND hWnd) m_uCursorControl = IsDlgButtonChecked(hWnd, IDC_CURSORCONTROL) ? 1 : 0; m_bmAutofire = IsDlgButtonChecked(hWnd, IDC_AUTOFIRE) ? 7 : 0; // bitmap of 3 bits + m_uCenteringControl = IsDlgButtonChecked(hWnd, IDC_CENTERINGCONTROL) ? 1 : 0; m_uMouseShowCrosshair = IsDlgButtonChecked(hWnd, IDC_MOUSE_CROSSHAIR) ? 1 : 0; m_uMouseRestrictToWindow = IsDlgButtonChecked(hWnd, IDC_MOUSE_RESTRICT_TO_WINDOW) ? 1 : 0; @@ -206,6 +208,7 @@ void CPageInput::DlgOK(HWND hWnd) REGSAVE(TEXT(REGVALUE_SCROLLLOCK_TOGGLE), m_uScrollLockToggle); REGSAVE(TEXT(REGVALUE_CURSOR_CONTROL), m_uCursorControl); REGSAVE(TEXT(REGVALUE_AUTOFIRE), m_bmAutofire); + REGSAVE(TEXT(REGVALUE_CENTERING_CONTROL), m_uCenteringControl); REGSAVE(TEXT(REGVALUE_MOUSE_CROSSHAIR), m_uMouseShowCrosshair); REGSAVE(TEXT(REGVALUE_MOUSE_RESTRICT_TO_WINDOW), m_uMouseRestrictToWindow); @@ -222,7 +225,7 @@ void CPageInput::InitJoystickChoices(HWND hWnd, int nJoyNum, int nIdcValue) TCHAR* pnzJoystickChoices; int *pnJoyTranslationTbl; int nJoyTranslationTblSize; - unsigned short nJC_DISABLED, nJC_JOYSTICK, nJC_KEYBD_STANDARD, nJC_KEYBD_CENTERING, nJC_MOUSE, nJC_MAX; + unsigned short nJC_DISABLED, nJC_JOYSTICK, nJC_KEYBD_CURSORS, nJC_KEYBD_NUMPAD, nJC_MOUSE, nJC_MAX; TCHAR** ppszJoyChoices; int nOtherJoyNum = nJoyNum == JN_JOYSTICK0 ? JN_JOYSTICK1 : JN_JOYSTICK0; @@ -233,8 +236,8 @@ void CPageInput::InitJoystickChoices(HWND hWnd, int nJoyNum, int nIdcValue) nJoyTranslationTblSize = sizeof(m_nJoy0ChoiceTranlationTbl); nJC_DISABLED = J0C_DISABLED; nJC_JOYSTICK = J0C_JOYSTICK1; - nJC_KEYBD_STANDARD = J0C_KEYBD_STANDARD; - nJC_KEYBD_CENTERING = J0C_KEYBD_CENTERING; + nJC_KEYBD_CURSORS = J0C_KEYBD_CURSORS; + nJC_KEYBD_NUMPAD = J0C_KEYBD_NUMPAD; nJC_MOUSE = J0C_MOUSE; nJC_MAX = J0C_MAX; ppszJoyChoices = (TCHAR**) m_pszJoy0Choices; @@ -246,8 +249,8 @@ void CPageInput::InitJoystickChoices(HWND hWnd, int nJoyNum, int nIdcValue) nJoyTranslationTblSize = sizeof(m_nJoy1ChoiceTranlationTbl); nJC_DISABLED = J1C_DISABLED; nJC_JOYSTICK = J1C_JOYSTICK2; - nJC_KEYBD_STANDARD = J1C_KEYBD_STANDARD; - nJC_KEYBD_CENTERING = J1C_KEYBD_CENTERING; + nJC_KEYBD_CURSORS = J1C_KEYBD_CURSORS; + nJC_KEYBD_NUMPAD = J1C_KEYBD_NUMPAD; nJC_MOUSE = J1C_MOUSE; nJC_MAX = J1C_MAX; ppszJoyChoices = (TCHAR**) m_pszJoy1Choices; @@ -271,10 +274,10 @@ void CPageInput::InitJoystickChoices(HWND hWnd, int nJoyNum, int nIdcValue) // Now exclude: // . the other Joystick type (if it exists) from this new list // . the mouse if the mousecard is plugged in - for(UINT i=nJC_KEYBD_STANDARD; i> uButton) & 1; } // Get a specific button void SetAutofire(UINT uValue) { m_bmAutofire = uValue; } // Set all buttons UINT GetMouseShowCrosshair(void){ return m_uMouseShowCrosshair; } @@ -50,8 +54,6 @@ private: static CPageInput* ms_this; static const UINT MaxMenuChoiceLen = 40; - enum JOY0CHOICE {J0C_DISABLED=0, J0C_JOYSTICK1, J0C_KEYBD_STANDARD, J0C_KEYBD_CENTERING, J0C_MOUSE, J0C_MAX}; - enum JOY1CHOICE {J1C_DISABLED=0, J1C_JOYSTICK2, J1C_KEYBD_STANDARD, J1C_KEYBD_CENTERING, J1C_MOUSE, J1C_MAX}; static const TCHAR m_szJoyChoice0[]; static const TCHAR m_szJoyChoice1[]; static const TCHAR m_szJoyChoice2[]; @@ -75,7 +77,8 @@ private: CPropertySheetHelper& m_PropertySheetHelper; UINT m_uScrollLockToggle; - UINT m_uCursorControl; // 1 = Allow AppleII to read cursor keys from $C000 (when using keyboard as a joystick) + UINT m_uCursorControl; // 1 = Allow AppleII to read cursor keys from $C000 (when using keyboard for joystick emu) + UINT m_uCenteringControl; // 1 = Centering, 0=Floating (when using keyboard for joystick emu) UINT m_bmAutofire; // bitmask b2:0 UINT m_uMouseShowCrosshair; UINT m_uMouseRestrictToWindow; diff --git a/AppleWin/source/Configuration/PropertySheet.h b/AppleWin/source/Configuration/PropertySheet.h index eb852b0e..ba1dc6bb 100644 --- a/AppleWin/source/Configuration/PropertySheet.h +++ b/AppleWin/source/Configuration/PropertySheet.h @@ -27,8 +27,10 @@ public: virtual UINT GetScrollLockToggle(void){ return m_PageInput.GetScrollLockToggle(); } virtual void SetScrollLockToggle(UINT uValue){ m_PageInput.SetScrollLockToggle(uValue); } - virtual UINT GetCursorControl(void){ return m_PageInput.GetCursorControl(); } - virtual void SetCursorControl(UINT uValue){ m_PageInput.SetCursorControl(uValue); } + virtual UINT GetJoystickCursorControl(void){ return m_PageInput.GetJoystickCursorControl(); } + virtual void SetJoystickCursorControl(UINT uValue){ m_PageInput.SetJoystickCursorControl(uValue); } + virtual UINT GetJoystickCenteringControl(void){ return m_PageInput.GetJoystickCenteringControl(); } + virtual void SetJoystickCenteringControl(UINT uValue){ m_PageInput.SetJoystickCenteringControl(uValue); } virtual UINT GetAutofire(UINT uButton) { return m_PageInput.GetAutofire(uButton); } virtual void SetAutofire(UINT uValue) { m_PageInput.SetAutofire(uValue); } virtual UINT GetMouseShowCrosshair(void){ return m_PageInput.GetMouseShowCrosshair(); } diff --git a/AppleWin/source/Joystick.cpp b/AppleWin/source/Joystick.cpp index 0ec70ad8..e0716abb 100644 --- a/AppleWin/source/Joystick.cpp +++ b/AppleWin/source/Joystick.cpp @@ -41,29 +41,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "MouseInterface.h" #include "Configuration\PropertySheet.h" -#define BUTTONTIME 5000 +#define BUTTONTIME 5000 // TODO: Describe this magic number -#define DEVICE_NONE 0 -#define DEVICE_JOYSTICK 1 -#define DEVICE_KEYBOARD 2 -#define DEVICE_MOUSE 3 +enum {DEVICE_NONE=0, DEVICE_JOYSTICK, DEVICE_KEYBOARD, DEVICE_MOUSE}; -#define MODE_NONE 0 -#define MODE_STANDARD 1 -#define MODE_CENTERING 2 -#define MODE_SMOOTH 3 - -typedef struct -{ - int device; - int mode; -} joyinforec; - -static const joyinforec joyinfo[5] = {{DEVICE_NONE,MODE_NONE}, - {DEVICE_JOYSTICK,MODE_STANDARD}, - {DEVICE_KEYBOARD,MODE_STANDARD}, - {DEVICE_KEYBOARD,MODE_CENTERING}, - {DEVICE_MOUSE,MODE_STANDARD}}; +// Indexed by joytype[n] +static const DWORD joyinfo[5] = { DEVICE_NONE, + DEVICE_JOYSTICK, + DEVICE_KEYBOARD, // Cursors (prev: Numpad-Standard) + DEVICE_KEYBOARD, // Numpad (prev: Numpad-Centering) + DEVICE_MOUSE }; // Key pad [1..9]; Key pad 0,Key pad '.'; Left ALT,Right ALT enum JOYKEY { JK_DOWNLEFT=0, @@ -99,7 +86,8 @@ static int joyshry[2] = {8,8}; static int joysubx[2] = {0,0}; static int joysuby[2] = {0,0}; -DWORD joytype[2] = {DEVICE_JOYSTICK,DEVICE_NONE}; // Emulation Type for joysticks #0 & #1 +// Value persisted to Registry for REGVALUE_JOYSTICK0_EMU_TYPE +DWORD joytype[2] = {J0C_JOYSTICK1, J1C_DISABLED}; // Emulation Type for joysticks #0 & #1 static BOOL setbutton[3] = {0,0,0}; // Used when a mouse button is pressed/released @@ -125,11 +113,11 @@ void CheckJoystick0() if ((info.wButtons & JOY_BUTTON1) && !joybutton[0]) buttonlatch[0] = BUTTONTIME; if ((info.wButtons & JOY_BUTTON2) && !joybutton[1] && - (joyinfo[joytype[1]].device == DEVICE_NONE) // Only consider 2nd button if NOT emulating a 2nd Apple joystick + (joyinfo[joytype[1]] == DEVICE_NONE) // Only consider 2nd button if NOT emulating a 2nd Apple joystick ) buttonlatch[1] = BUTTONTIME; joybutton[0] = ((info.wButtons & JOY_BUTTON1) != 0); - if (joyinfo[joytype[1]].device == DEVICE_NONE) // Only consider 2nd button if NOT emulating a 2nd Apple joystick + if (joyinfo[joytype[1]] == DEVICE_NONE) // Only consider 2nd button if NOT emulating a 2nd Apple joystick joybutton[1] = ((info.wButtons & JOY_BUTTON2) != 0); xpos[0] = (info.wXpos-joysubx[0]) >> joyshrx[0]; @@ -155,12 +143,12 @@ void CheckJoystick1() if ((info.wButtons & JOY_BUTTON1) && !joybutton[2]) { buttonlatch[2] = BUTTONTIME; - if(joyinfo[joytype[1]].device != DEVICE_NONE) + if(joyinfo[joytype[1]] != DEVICE_NONE) buttonlatch[1] = BUTTONTIME; // Re-map this button when emulating a 2nd Apple joystick } joybutton[2] = ((info.wButtons & JOY_BUTTON1) != 0); - if(joyinfo[joytype[1]].device != DEVICE_NONE) + if(joyinfo[joytype[1]] != DEVICE_NONE) joybutton[1] = ((info.wButtons & JOY_BUTTON1) != 0); // Re-map this button when emulating a 2nd Apple joystick xpos[1] = (info.wXpos-joysubx[1]) >> joyshrx[1]; @@ -180,14 +168,14 @@ void CheckJoystick1() //=========================================================================== void JoyInitialize() { - // Emulated joystick #0 can only use JOYSTICKID1 (if no joystick, then use mouse) + // Emulated joystick #0 can only use JOYSTICKID1 (if no joystick, then use keyboard) // Emulated joystick #1 can only use JOYSTICKID2 (if no joystick, then disable) // // Init for emulated joystick #0: // - if (joyinfo[joytype[0]].device == DEVICE_JOYSTICK) + if (joyinfo[joytype[0]] == DEVICE_JOYSTICK) { JOYCAPS caps; if (joyGetDevCaps(JOYSTICKID1,&caps,sizeof(JOYCAPS)) == JOYERR_NOERROR) @@ -211,7 +199,7 @@ void JoyInitialize() } else { - joytype[0] = DEVICE_MOUSE; + joytype[0] = J0C_KEYBD_NUMPAD; } } @@ -219,7 +207,7 @@ void JoyInitialize() // Init for emulated joystick #1: // - if (joyinfo[joytype[1]].device == DEVICE_JOYSTICK) + if (joyinfo[joytype[1]] == DEVICE_JOYSTICK) { JOYCAPS caps; if (joyGetDevCaps(JOYSTICKID2,&caps,sizeof(JOYCAPS)) == JOYERR_NOERROR) @@ -243,7 +231,7 @@ void JoyInitialize() } else { - joytype[1] = DEVICE_NONE; + joytype[1] = J1C_DISABLED; } } } @@ -262,18 +250,14 @@ BOOL JoyProcessKey(int virtkey, BOOL extended, BOOL down, BOOL autorep) UINT32 Down:1; } CursorKeys = {0}; - if ( (joyinfo[joytype[0]].device != DEVICE_KEYBOARD) && - (joyinfo[joytype[1]].device != DEVICE_KEYBOARD) && + if ( (joyinfo[joytype[0]] != DEVICE_KEYBOARD) && + (joyinfo[joytype[1]] != DEVICE_KEYBOARD) && (virtkey != VK_MENU) // VK_MENU == ALT Key ) { return 0; } - // Joystick # which is being emulated by keyboard - int nJoyNum = (joyinfo[joytype[0]].device == DEVICE_KEYBOARD) ? 0 : 1; - int nCenteringType = joyinfo[joytype[nJoyNum]].mode; // MODE_STANDARD or MODE_CENTERING - // BOOL keychange = 0; @@ -286,37 +270,40 @@ BOOL JoyProcessKey(int virtkey, BOOL extended, BOOL down, BOOL autorep) } else if (!extended) { - keychange = 1; + if (JoyUsingKeyboardNumpad()) + { + keychange = 1; - if ((virtkey >= VK_NUMPAD1) && (virtkey <= VK_NUMPAD9)) // NumLock on - { - keydown[virtkey-VK_NUMPAD1] = down; - } - else // NumLock off - { - switch (virtkey) + if ((virtkey >= VK_NUMPAD1) && (virtkey <= VK_NUMPAD9)) // NumLock on { - case VK_END: keydown[JK_DOWNLEFT] = down; break; - case VK_DOWN: keydown[JK_DOWN] = down; break; - case VK_NEXT: keydown[JK_DOWNRIGHT] = down; break; - case VK_LEFT: keydown[JK_LEFT] = down; break; - case VK_CLEAR: keydown[JK_CENTRE] = down; break; - case VK_RIGHT: keydown[JK_RIGHT] = down; break; - case VK_HOME: keydown[JK_UPLEFT] = down; break; - case VK_UP: keydown[JK_UP] = down; break; - case VK_PRIOR: keydown[JK_UPRIGHT] = down; break; - case VK_NUMPAD0: keydown[JK_BUTTON0] = down; break; - case VK_DECIMAL: keydown[JK_BUTTON1] = down; break; - default: keychange = 0; break; + keydown[virtkey-VK_NUMPAD1] = down; + } + else // NumLock off + { + switch (virtkey) + { + case VK_END: keydown[JK_DOWNLEFT] = down; break; + case VK_DOWN: keydown[JK_DOWN] = down; break; + case VK_NEXT: keydown[JK_DOWNRIGHT] = down; break; + case VK_LEFT: keydown[JK_LEFT] = down; break; + case VK_CLEAR: keydown[JK_CENTRE] = down; break; + case VK_RIGHT: keydown[JK_RIGHT] = down; break; + case VK_HOME: keydown[JK_UPLEFT] = down; break; + case VK_UP: keydown[JK_UP] = down; break; + case VK_PRIOR: keydown[JK_UPRIGHT] = down; break; + case VK_NUMPAD0: keydown[JK_BUTTON0] = down; break; + case VK_DECIMAL: keydown[JK_BUTTON1] = down; break; + default: keychange = 0; break; + } } } } #ifdef SUPPORT_CURSOR_KEYS else if (extended) { - if (virtkey == VK_LEFT || virtkey == VK_UP || virtkey == VK_RIGHT || virtkey == VK_DOWN) + if (JoyUsingKeyboardCursors() && (virtkey == VK_LEFT || virtkey == VK_UP || virtkey == VK_RIGHT || virtkey == VK_DOWN)) { - keychange = 1; // This prevents cursors keys being available to the Apple II (eg. Lode Runner uses cursor left/right for game speed) + keychange = 1; // This prevents cursors keys being available to the Apple II (eg. Lode Runner uses cursor left/right for game speed & Ctrl-J/K for joystick/keyboard) bIsCursorKey = true; switch (virtkey) @@ -339,11 +326,11 @@ BOOL JoyProcessKey(int virtkey, BOOL extended, BOOL down, BOOL autorep) { if(down) { - if(joyinfo[joytype[1]].device != DEVICE_KEYBOARD) + if(joyinfo[joytype[1]] != DEVICE_KEYBOARD) { buttonlatch[0] = BUTTONTIME; } - else if(joyinfo[joytype[1]].device != DEVICE_NONE) + else if(joyinfo[joytype[1]] != DEVICE_NONE) { buttonlatch[2] = BUTTONTIME; buttonlatch[1] = BUTTONTIME; // Re-map this button when emulating a 2nd Apple joystick @@ -354,11 +341,11 @@ BOOL JoyProcessKey(int virtkey, BOOL extended, BOOL down, BOOL autorep) { if(down) { - if(joyinfo[joytype[1]].device != DEVICE_KEYBOARD) + if(joyinfo[joytype[1]] != DEVICE_KEYBOARD) buttonlatch[1] = BUTTONTIME; } } - else if ((down && !autorep) || (nCenteringType == MODE_CENTERING)) + else if ((down && !autorep) || (sg_PropertySheet.GetJoystickCenteringControl() == JOYSTICK_MODE_CENTERING)) { int xkeys = 0; int ykeys = 0; @@ -399,6 +386,9 @@ BOOL JoyProcessKey(int virtkey, BOOL extended, BOOL down, BOOL autorep) ykeys++; ytotal += keyvalue[JK_DOWN].y; } + // Joystick # which is being emulated by keyboard + int nJoyNum = (joyinfo[joytype[0]] == DEVICE_KEYBOARD) ? 0 : 1; + if (xkeys) xpos[nJoyNum] = xtotal / xkeys; else @@ -410,7 +400,7 @@ BOOL JoyProcessKey(int virtkey, BOOL extended, BOOL down, BOOL autorep) ypos[nJoyNum] = PDL_CENTRAL + g_nPdlTrimY; } - if (bIsCursorKey && sg_PropertySheet.GetCursorControl()) + if (bIsCursorKey && sg_PropertySheet.GetJoystickCursorControl()) { // Allow AppleII keyboard to see this cursor keypress too return 0; @@ -439,9 +429,9 @@ BYTE __stdcall JoyReadButton(WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft) { address &= 0xFF; - if(joyinfo[joytype[0]].device == DEVICE_JOYSTICK) + if(joyinfo[joytype[0]] == DEVICE_JOYSTICK) CheckJoystick0(); - if(joyinfo[joytype[1]].device == DEVICE_JOYSTICK) + if(joyinfo[joytype[1]] == DEVICE_JOYSTICK) CheckJoystick1(); BOOL pressed = 0; @@ -449,7 +439,7 @@ BYTE __stdcall JoyReadButton(WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft) { case 0x61: pressed = (buttonlatch[0] || joybutton[0] || setbutton[0] || keydown[JK_OPENAPPLE]); - if(joyinfo[joytype[1]].device != DEVICE_KEYBOARD) + if(joyinfo[joytype[1]] != DEVICE_KEYBOARD) pressed = (pressed || keydown[JK_BUTTON0]); buttonlatch[0] = 0; DoAutofire(0, pressed); @@ -457,14 +447,14 @@ BYTE __stdcall JoyReadButton(WORD, WORD address, BYTE, BYTE, ULONG nCyclesLeft) case 0x62: pressed = (buttonlatch[1] || joybutton[1] || setbutton[1] || keydown[JK_CLOSEDAPPLE]); - if(joyinfo[joytype[1]].device != DEVICE_KEYBOARD) + if(joyinfo[joytype[1]] != DEVICE_KEYBOARD) pressed = (pressed || keydown[JK_BUTTON1]); buttonlatch[1] = 0; DoAutofire(1, pressed); break; case 0x63: - if (IS_APPLE2 && (joyinfo[joytype[1]].device == DEVICE_NONE)) + if (IS_APPLE2 && (joyinfo[joytype[1]] == DEVICE_NONE)) { // Apple II/II+ with no joystick has the "SHIFT key mod" // See Sather's Understanding The Apple II p7-36 @@ -532,9 +522,9 @@ BYTE __stdcall JoyResetPosition(WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft) CpuCalcCycles(nCyclesLeft); g_nJoyCntrResetCycle = g_nCumulativeCycles; - if(joyinfo[joytype[0]].device == DEVICE_JOYSTICK) + if(joyinfo[joytype[0]] == DEVICE_JOYSTICK) CheckJoystick0(); - if(joyinfo[joytype[1]].device == DEVICE_JOYSTICK) + if(joyinfo[joytype[1]] == DEVICE_JOYSTICK) CheckJoystick1(); return MemReadFloatingBus(nCyclesLeft); @@ -549,11 +539,11 @@ void JoySetButton(eBUTTON number, eBUTTONSTATE down) return; // If 2nd joystick is enabled, then both joysticks only have 1 button - if((joyinfo[joytype[1]].device != DEVICE_NONE) && (number != 0)) + if((joyinfo[joytype[1]] != DEVICE_NONE) && (number != 0)) return; // If it is 2nd joystick that is being emulated with mouse, then re-map button # - if(joyinfo[joytype[1]].device == DEVICE_MOUSE) + if(joyinfo[joytype[1]] == DEVICE_MOUSE) { number = BUTTON1; // 2nd joystick controls Apple button #1 } @@ -570,7 +560,7 @@ BOOL JoySetEmulationType(HWND window, DWORD newtype, int nJoystickNumber, const if(joytype[nJoystickNumber] == newtype) return 1; // Already set to this type. Return OK. - if (joyinfo[newtype].device == DEVICE_JOYSTICK) + if (joyinfo[newtype] == DEVICE_JOYSTICK) { JOYCAPS caps; unsigned int nJoyID = nJoystickNumber == JN_JOYSTICK0 ? JOYSTICKID1 : JOYSTICKID2; @@ -586,8 +576,8 @@ BOOL JoySetEmulationType(HWND window, DWORD newtype, int nJoystickNumber, const return 0; } } - else if ((joyinfo[newtype].device == DEVICE_MOUSE) && - (joyinfo[joytype[nJoystickNumber]].device != DEVICE_MOUSE)) + else if ((joyinfo[newtype] == DEVICE_MOUSE) && + (joyinfo[joytype[nJoystickNumber]] != DEVICE_MOUSE)) { if (bMousecardActive) { @@ -611,6 +601,22 @@ BOOL JoySetEmulationType(HWND window, DWORD newtype, int nJoystickNumber, const TEXT("Configuration"), MB_ICONINFORMATION | MB_SETFOREGROUND); } + else if (joyinfo[newtype] == DEVICE_KEYBOARD) + { + if (newtype == J0C_KEYBD_CURSORS || newtype == J1C_KEYBD_CURSORS) + { + MessageBox(window, + TEXT("Using cursor keys to emulate a joystick can cause conflicts.\n\n") + TEXT("Be aware that 'cursor up' = CTRL+K, and 'cursor-down' = CTRL+J.\n") + TEXT("EG. Lode Runner uses CTRL+K/J to switch between keyboard/joystick modes ") + TEXT("(and cursor left/right to control speed).\n\n") + TEXT("Also if cursor keys are blocked from being read from the Apple keyboard ") + TEXT("then even simple AppleSoft command-line editing (cursor left/right) will not work."), + TEXT("Configuration"), + MB_ICONINFORMATION | MB_SETFOREGROUND); + } + } + joytype[nJoystickNumber] = newtype; JoyInitialize(); JoyReset(); @@ -623,7 +629,7 @@ BOOL JoySetEmulationType(HWND window, DWORD newtype, int nJoystickNumber, const // Called when mouse is being used as a joystick && mouse position changes void JoySetPosition(int xvalue, int xrange, int yvalue, int yrange) { - int nJoyNum = (joyinfo[joytype[0]].device == DEVICE_MOUSE) ? 0 : 1; + int nJoyNum = (joyinfo[joytype[0]] == DEVICE_MOUSE) ? 0 : 1; xpos[nJoyNum] = (xvalue*255)/xrange; ypos[nJoyNum] = (yvalue*255)/yrange; } @@ -640,22 +646,33 @@ void JoyUpdatePosition() BOOL JoyUsingMouse() { - return (joyinfo[joytype[0]].device == DEVICE_MOUSE) || (joyinfo[joytype[1]].device == DEVICE_MOUSE); + return (joyinfo[joytype[0]] == DEVICE_MOUSE) || (joyinfo[joytype[1]] == DEVICE_MOUSE); } BOOL JoyUsingKeyboard() { - return (joyinfo[joytype[0]].device == DEVICE_KEYBOARD) || (joyinfo[joytype[1]].device == DEVICE_KEYBOARD); + return (joyinfo[joytype[0]] == DEVICE_KEYBOARD) || (joyinfo[joytype[1]] == DEVICE_KEYBOARD); } + +BOOL JoyUsingKeyboardCursors() +{ + return (joytype[0] == J0C_KEYBD_CURSORS) || (joytype[1] == J1C_KEYBD_CURSORS); +} + +BOOL JoyUsingKeyboardNumpad() +{ + return (joytype[0] == J0C_KEYBD_NUMPAD) || (joytype[1] == J1C_KEYBD_NUMPAD); +} + //=========================================================================== void JoyDisableUsingMouse() { - if (joyinfo[joytype[0]].device == DEVICE_MOUSE) - joytype[0] = DEVICE_NONE; + if (joyinfo[joytype[0]] == DEVICE_MOUSE) + joytype[0] = J0C_DISABLED; - if (joyinfo[joytype[1]].device == DEVICE_MOUSE) - joytype[1] = DEVICE_NONE; + if (joyinfo[joytype[1]] == DEVICE_MOUSE) + joytype[1] = J1C_DISABLED; } //=========================================================================== @@ -669,9 +686,9 @@ void JoySetTrim(short nValue, bool bAxisX) int nJoyNum = -1; - if(joyinfo[joytype[0]].device == DEVICE_KEYBOARD) + if(joyinfo[joytype[0]] == DEVICE_KEYBOARD) nJoyNum = 0; - else if(joyinfo[joytype[1]].device == DEVICE_KEYBOARD) + else if(joyinfo[joytype[1]] == DEVICE_KEYBOARD) nJoyNum = 1; if(nJoyNum >= 0) diff --git a/AppleWin/source/Joystick.h b/AppleWin/source/Joystick.h index d9901952..c4d42477 100644 --- a/AppleWin/source/Joystick.h +++ b/AppleWin/source/Joystick.h @@ -2,8 +2,13 @@ enum JOYNUM {JN_JOYSTICK0=0, JN_JOYSTICK1}; +enum JOY0CHOICE {J0C_DISABLED=0, J0C_JOYSTICK1, J0C_KEYBD_CURSORS, J0C_KEYBD_NUMPAD, J0C_MOUSE, J0C_MAX}; +enum JOY1CHOICE {J1C_DISABLED=0, J1C_JOYSTICK2, J1C_KEYBD_CURSORS, J1C_KEYBD_NUMPAD, J1C_MOUSE, J1C_MAX}; + extern DWORD joytype[2]; +enum {JOYSTICK_MODE_FLOATING=0, JOYSTICK_MODE_CENTERING}; // Joystick centering control + void JoyInitialize(); BOOL JoyProcessKey(int,BOOL,BOOL,BOOL); void JoyReset(); @@ -13,6 +18,8 @@ void JoySetPosition(int,int,int,int); void JoyUpdatePosition(); BOOL JoyUsingMouse(); BOOL JoyUsingKeyboard(); +BOOL JoyUsingKeyboardCursors(); +BOOL JoyUsingKeyboardNumpad(); void JoyDisableUsingMouse(); void JoySetTrim(short nValue, bool bAxisX); short JoyGetTrim(bool bAxisX); diff --git a/AppleWin/source/SaveState.cpp b/AppleWin/source/SaveState.cpp index ac31a9c1..a037ffdf 100644 --- a/AppleWin/source/SaveState.cpp +++ b/AppleWin/source/SaveState.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "StdAfx.h" +#include "Joystick.h" #define DEFAULT_SNAPSHOT_NAME "SaveState.aws" diff --git a/AppleWin/source/StdAfx.h b/AppleWin/source/StdAfx.h index a757d3d2..e4305592 100644 --- a/AppleWin/source/StdAfx.h +++ b/AppleWin/source/StdAfx.h @@ -51,7 +51,6 @@ #include "Debug.h" #include "Disk.h" #include "Frame.h" -#include "Joystick.h" #include "Keyboard.h" #include "Log.h" #include "Memory.h"