From dce168b0c276729c4a0821bbb52d9ae3e4e25f36 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sat, 10 Jun 2006 06:50:50 +0000 Subject: [PATCH] international keyboard support --- stepmania/src/RageInput.cpp | 17 +++++++++ stepmania/src/RageInput.h | 1 + stepmania/src/RageInputDevice.cpp | 22 ------------ stepmania/src/RageInputDevice.h | 2 -- stepmania/src/ScreenNameEntryTraditional.cpp | 3 +- stepmania/src/ScreenNetSelectBase.cpp | 3 +- stepmania/src/ScreenNetSelectMusic.cpp | 3 +- stepmania/src/ScreenTextEntry.cpp | 8 ++--- stepmania/src/StepMania.dsp | 8 ++--- .../src/arch/InputHandler/InputHandler.cpp | 23 +++++++++++- .../src/arch/InputHandler/InputHandler.h | 1 + .../InputHandler/InputHandler_DirectInput.cpp | 36 +++++++++++++++++++ .../InputHandler/InputHandler_DirectInput.h | 1 + 13 files changed, 90 insertions(+), 38 deletions(-) diff --git a/stepmania/src/RageInput.cpp b/stepmania/src/RageInput.cpp index 7a18050908..28e0ef80d2 100644 --- a/stepmania/src/RageInput.cpp +++ b/stepmania/src/RageInput.cpp @@ -97,6 +97,23 @@ RString RageInput::GetDeviceSpecificInputString( const DeviceInput &di ) return di.ToString(); } +char RageInput::DeviceButtonToChar( DeviceButton button ) +{ + FOREACH( InputHandler*, m_pDevices, i ) + { + vector vDevices; + (*i)->GetDevicesAndDescriptions( vDevices ); + + FOREACH_CONST( InputDeviceInfo, vDevices, idi ) + { + if( idi->id == DEVICE_KEYBOARD ) + return (*i)->DeviceButtonToChar(button); + } + } + + return '\0'; +} + InputDeviceState RageInput::GetInputDeviceState( InputDevice id ) { FOREACH( InputHandler*, m_pDevices, i ) diff --git a/stepmania/src/RageInput.h b/stepmania/src/RageInput.h index 9189ef1efc..4d02fca1d3 100644 --- a/stepmania/src/RageInput.h +++ b/stepmania/src/RageInput.h @@ -21,6 +21,7 @@ public: void WindowReset(); void AddHandler( InputHandler *pHandler ); RString GetDeviceSpecificInputString( const DeviceInput &di ); + char DeviceButtonToChar( DeviceButton button ); InputDeviceState GetInputDeviceState( InputDevice id ); RString GetDisplayDevicesString() const; diff --git a/stepmania/src/RageInputDevice.cpp b/stepmania/src/RageInputDevice.cpp index 22c6146350..c7edb3ae00 100644 --- a/stepmania/src/RageInputDevice.cpp +++ b/stepmania/src/RageInputDevice.cpp @@ -273,28 +273,6 @@ bool DeviceInput::FromString( const RString &s ) return true; } - -char DeviceInput::ToChar() const -{ - if( button < 127 ) - return (char) button; - - if( button >= KEY_KP_C0 && button <= KEY_KP_C9 ) - return (char) (button - KEY_KP_C0) + '0'; - - switch( button ) - { - case KEY_KP_SLASH: return '/'; - case KEY_KP_ASTERISK: return '*'; - case KEY_KP_HYPHEN: return '-'; - case KEY_KP_PLUS: return '+'; - case KEY_KP_PERIOD: return '.'; - case KEY_KP_EQUAL: return '='; - } - - return '\0'; -} - /* * Copyright (c) 2001-2002 Chris Danford * All rights reserved. diff --git a/stepmania/src/RageInputDevice.h b/stepmania/src/RageInputDevice.h index 49d5b0d76a..0afc0240dd 100644 --- a/stepmania/src/RageInputDevice.h +++ b/stepmania/src/RageInputDevice.h @@ -337,8 +337,6 @@ public: bool IsValid() const { return device != DEVICE_NONE; }; void MakeInvalid() { device = DEVICE_NONE; }; - char ToChar() const; - bool IsJoystick() const { return ::IsJoystick(device); } }; diff --git a/stepmania/src/ScreenNameEntryTraditional.cpp b/stepmania/src/ScreenNameEntryTraditional.cpp index 6690878c0e..fc40fb56cc 100644 --- a/stepmania/src/ScreenNameEntryTraditional.cpp +++ b/stepmania/src/ScreenNameEntryTraditional.cpp @@ -23,6 +23,7 @@ #include "ScreenDimensions.h" #include "Command.h" #include "InputEventPlus.h" +#include "RageInput.h" // // Defines specific to ScreenNameEntryTraditional @@ -515,7 +516,7 @@ void ScreenNameEntryTraditional::Input( const InputEventPlus &input ) if( input.DeviceI == DeviceInput(DEVICE_KEYBOARD, KEY_BACK) ) c = CHAR_BACK; else - c = toupper( input.DeviceI.ToChar() ); + c = toupper( INPUTMAN->DeviceButtonToChar( input.DeviceI.button ) ); if( c ) { PlayerNumber pn = GAMESTATE->m_MasterPlayerNumber; diff --git a/stepmania/src/ScreenNetSelectBase.cpp b/stepmania/src/ScreenNetSelectBase.cpp index 5b0674d174..c19c2bb887 100644 --- a/stepmania/src/ScreenNetSelectBase.cpp +++ b/stepmania/src/ScreenNetSelectBase.cpp @@ -13,6 +13,7 @@ #include "RageUtil.h" #include "GameState.h" #include "InputEventPlus.h" +#include "RageInput.h" #define CHATINPUT_WIDTH THEME->GetMetricF(m_sName,"ChatInputBoxWidth") #define CHATINPUT_HEIGHT THEME->GetMetricF(m_sName,"ChatInputBoxHeight") @@ -123,7 +124,7 @@ void ScreenNetSelectBase::Input( const InputEventPlus &input ) break; default: char c; - c = input.DeviceI.ToChar(); + c = INPUTMAN->DeviceButtonToChar( input.DeviceI.button ); if( bHoldingShift && !bHoldingCtrl ) { diff --git a/stepmania/src/ScreenNetSelectMusic.cpp b/stepmania/src/ScreenNetSelectMusic.cpp index 692d7e9498..e4900bd8ca 100644 --- a/stepmania/src/ScreenNetSelectMusic.cpp +++ b/stepmania/src/ScreenNetSelectMusic.cpp @@ -22,6 +22,7 @@ #include "RageLog.h" #include "song.h" #include "InputEventPlus.h" +#include "RageInput.h" AutoScreenMessage( SM_NoSongs ) AutoScreenMessage( SM_ChangeSong ) @@ -128,7 +129,7 @@ void ScreenNetSelectMusic::Input( const InputEventPlus &input ) INPUTFILTER->IsBeingPressed(DeviceInput(DEVICE_KEYBOARD, KEY_RCTRL)) || (!NSMAN->useSMserver); //If we are disconnected, assume no chatting - char c = (char) toupper(input.DeviceI.ToChar() ); + char c = (char) toupper( INPUTMAN->DeviceButtonToChar(input.DeviceI.button) ); if ( bHoldingCtrl && ( c >= 'A' ) && ( c <= 'Z' ) ) { diff --git a/stepmania/src/ScreenTextEntry.cpp b/stepmania/src/ScreenTextEntry.cpp index fedbb13551..7878e6f9d0 100644 --- a/stepmania/src/ScreenTextEntry.cpp +++ b/stepmania/src/ScreenTextEntry.cpp @@ -10,7 +10,7 @@ #include "ScreenPrompt.h" #include "ActorUtil.h" #include "InputEventPlus.h" - +#include "RageInput.h" static const char* g_szKeys[NUM_KEYBOARD_ROWS][KEYS_PER_ROW] = { @@ -183,15 +183,15 @@ void ScreenTextEntry::Input( const InputEventPlus &input ) } else if( input.type == IET_FIRST_PRESS ) { - if( input.DeviceI.ToChar() >= ' ' ) + char c = INPUTMAN->DeviceButtonToChar( input.DeviceI.button ); + if( c >= ' ' ) { bool bIsHoldingShift = INPUTFILTER->IsBeingPressed( DeviceInput(input.DeviceI.device, KEY_RSHIFT)) || INPUTFILTER->IsBeingPressed( DeviceInput(input.DeviceI.device, KEY_LSHIFT)); - char c = input.DeviceI.ToChar(); if( bIsHoldingShift ) { - c = (char)toupper( input.DeviceI.ToChar() ); + c = (char)toupper( c ); switch( c ) { case '`': c='~'; break; diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index 3dbaee0fb3..104f1b4522 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -62,7 +62,7 @@ IntDir=.\../Debug6 TargetDir=\cvs\stepmania\Program TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=archutils\Win32\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -99,7 +99,7 @@ IntDir=.\../Release6 TargetDir=\cvs\stepmania-clean\Program TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=archutils\Win32\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -654,10 +654,6 @@ SOURCE=.\RageUtil_WorkerThread.cpp SOURCE=.\RageUtil_WorkerThread.h # End Source File -# Begin Source File - -SOURCE=.\RageUtilLua.cpp -# End Source File # End Group # Begin Group "Data Structures" diff --git a/stepmania/src/arch/InputHandler/InputHandler.cpp b/stepmania/src/arch/InputHandler/InputHandler.cpp index 23773d1a3a..2d6ceafb1d 100644 --- a/stepmania/src/arch/InputHandler/InputHandler.cpp +++ b/stepmania/src/arch/InputHandler/InputHandler.cpp @@ -34,11 +34,32 @@ void InputHandler::ButtonPressed( DeviceInput di, bool Down ) } } +char InputHandler::DeviceButtonToChar( DeviceButton button ) +{ + if( button < 127 ) + return (char) button; + + if( button >= KEY_KP_C0 && button <= KEY_KP_C9 ) + return (char) (button - KEY_KP_C0) + '0'; + + switch( button ) + { + case KEY_KP_SLASH: return '/'; + case KEY_KP_ASTERISK: return '*'; + case KEY_KP_HYPHEN: return '-'; + case KEY_KP_PLUS: return '+'; + case KEY_KP_PERIOD: return '.'; + case KEY_KP_EQUAL: return '='; + } + + return '\0'; +} + RString InputHandler::GetDeviceSpecificInputString( const DeviceInput &di ) { if( di.device == DEVICE_KEYBOARD ) { - char c = di.ToChar(); + char c = DeviceButtonToChar( di.button ); if( c ) { if( c == ' ' ) diff --git a/stepmania/src/arch/InputHandler/InputHandler.h b/stepmania/src/arch/InputHandler/InputHandler.h index 804fbfa1e7..4c7660a328 100644 --- a/stepmania/src/arch/InputHandler/InputHandler.h +++ b/stepmania/src/arch/InputHandler/InputHandler.h @@ -33,6 +33,7 @@ public: // Override to return a pretty string that's specific to the controller type. virtual RString GetDeviceSpecificInputString( const DeviceInput &di ); + virtual char DeviceButtonToChar( DeviceButton button ); // Override to find out whether the controller is currently plugged in. // Not all InputHandlers will support this. Not applicable to all InputHandlers. diff --git a/stepmania/src/arch/InputHandler/InputHandler_DirectInput.cpp b/stepmania/src/arch/InputHandler/InputHandler_DirectInput.cpp index 6607c79aa3..33e4ae6e19 100644 --- a/stepmania/src/arch/InputHandler/InputHandler_DirectInput.cpp +++ b/stepmania/src/arch/InputHandler/InputHandler_DirectInput.cpp @@ -645,6 +645,42 @@ void InputHandler_DInput::GetDevicesAndDescriptions( vector& vD vDevicesOut.push_back( InputDeviceInfo(Devices[i].dev, Devices[i].m_sName) ); } +char InputHandler_DInput::DeviceButtonToChar( DeviceButton button ) +{ + FOREACH_CONST( DIDevice, Devices, d ) + { + if( d->type != DIDevice::KEYBOARD ) + continue; + + FOREACH_CONST( input_t, d->Inputs, i ) + { + if( button != i->num ) + continue; + + DWORD scancode = i->ofs; + + HKL layout = GetKeyboardLayout(0); // 0 == current thread + + unsigned char state[256]; + // Don't fill key state. We'll do the shift/ctrl/alt + // translations ourself in ScreenTextEntry. + ZERO( state ); + + UINT vk = MapVirtualKeyEx( scancode, 1, layout ); + + unsigned short result[2]; // ToAscii writes a max of 2 chars + ZERO( result ); + // TODO: Use ToUnicodeEx + int iNum = ToAsciiEx( vk, scancode, state, result, 0, layout ); + if( iNum == 1 ) + return (char)result[0]; + // iNum == 2 will happen only for dead keys. See MSDN for ToAsciiEx. + } + } + + return InputHandler::DeviceButtonToChar( button ); +} + /* * (c) 2003-2004 Glenn Maynard * All rights reserved. diff --git a/stepmania/src/arch/InputHandler/InputHandler_DirectInput.h b/stepmania/src/arch/InputHandler/InputHandler_DirectInput.h index 996d79a49d..e51dd1412c 100644 --- a/stepmania/src/arch/InputHandler/InputHandler_DirectInput.h +++ b/stepmania/src/arch/InputHandler/InputHandler_DirectInput.h @@ -11,6 +11,7 @@ public: InputHandler_DInput(); ~InputHandler_DInput(); void GetDevicesAndDescriptions( vector& vDevicesOut ); + char DeviceButtonToChar( DeviceButton button ); void Update(); bool DevicesChanged(); void WindowReset();