From 2efd0e19e03843db41f9e77db22c1dabb6d844f2 Mon Sep 17 00:00:00 2001 From: mtabachenko Date: Sat, 17 Jan 2009 11:47:13 +0000 Subject: [PATCH] core: - fix lid folding; - fix rumblePak addon; winport: - added feedback support & analog joysticks; --- desmume/README.WIN | 1 + desmume/src/NDSSystem.cpp | 35 +++--- desmume/src/addons.h | 1 + desmume/src/addons/rumblepak.cpp | 51 ++++---- desmume/src/windows/inputdx.cpp | 210 +++++++++++++++++++++++++------ 5 files changed, 215 insertions(+), 83 deletions(-) diff --git a/desmume/README.WIN b/desmume/README.WIN index d059ebbf0..0d293b9ba 100644 --- a/desmume/README.WIN +++ b/desmume/README.WIN @@ -72,6 +72,7 @@ change): w - Right Trigger Enter - Start button Right Shift - Select button + Backspace - Lid fold/unfold n - Frame advance Space - Pause/Unpause diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index d724ed5c3..0f96d3fee 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -44,7 +44,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //#define USE_REAL_BIOS static BOOL LidClosed = FALSE; -static u8 LidKeyCount = 0; +static u8 countLid = 0; static u8 pathToROMwithoutExt[MAX_PATH]; /* the count of bytes copied from the firmware into memory */ @@ -546,7 +546,7 @@ void NDS_Reset( void) _MMU_write08(0x04000136, 0x43); LidClosed = FALSE; - LidKeyCount = 0; + countLid = 0; /* * Setup a copy of the firmware user settings in memory. @@ -1764,7 +1764,6 @@ void NDS_setPadFromMovie(u16 pad) void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,bool X,bool W,bool E,bool G, bool F) { - //this macro is the opposite of what you would expect #define FIX(b) (b?0:0x80) @@ -1798,27 +1797,27 @@ void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,b ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] = (u16)pad; ((u16 *)MMU.ARM7_REG)[0x130>>1] = (u16)pad; + // todo: mute sound when Lided close + if (!f && !countLid) + { + LidClosed = (!LidClosed) & 0x01; + if (!LidClosed) + NDS_makeARM7Int(22); + countLid = 30; + } + else + { + if (countLid > 0) + countLid = countLid--; + } + u16 padExt = (((u16 *)MMU.ARM7_REG)[0x136>>1] & 0x0070) | ((x) >> 7) | ((y) >> 6) | ((g) >> 4) | + ((LidClosed) << 7) | 0x0034; - // todo: mute sound when Lided close - if (!f) - { - LidKeyCount++; - if (LidKeyCount > 50) - { - LidKeyCount = 0; - LidClosed = (!LidClosed) & 0x01; - if (!LidClosed) - NDS_makeARM7Int(22); - } - } else LidKeyCount = 0; - - if (LidClosed) padExt |= 1 << 7; - ((u16 *)MMU.ARM7_REG)[0x136>>1] = (u16)padExt; //put into the format we want for the movie system diff --git a/desmume/src/addons.h b/desmume/src/addons.h index 15023391c..9e18cfe72 100644 --- a/desmume/src/addons.h +++ b/desmume/src/addons.h @@ -77,6 +77,7 @@ extern char CFlashPath[MAX_PATH]; // path to compact flash directory extern u8 CFlashUsePath; // true is used path from CFlashPath for cflash folder extern u8 CFlashUseRomPath; // true is used path to rom file for cflash folder extern char GBAgameName[MAX_PATH]; // file name for GBA game (rom) +extern void (*FeedbackON)(BOOL enable); // feedback on/off extern BOOL addonsInit(); // Init addons extern void addonsClose(); // Shutdown addons diff --git a/desmume/src/addons/rumblepak.cpp b/desmume/src/addons/rumblepak.cpp index 91f53f474..7f4b93f81 100644 --- a/desmume/src/addons/rumblepak.cpp +++ b/desmume/src/addons/rumblepak.cpp @@ -25,62 +25,57 @@ #include "../mem.h" #include "../MMU.h" #include - -u8 rumble_hdr[0xC0]; + +void (*FeedbackON)(BOOL enable) = NULL; BOOL RumblePak_init(void) { return (TRUE); }; + void RumblePak_reset(void) { - memset(rumble_hdr, 0, sizeof(rumble_hdr)); - memcpy(rumble_hdr + 0x04, gba_header_data_0x04, 156); - memcpy(rumble_hdr + 0xA0, "Rumble Pak ", 12); - rumble_hdr[0xB2] = 0x96; - rumble_hdr[0xBE] = 0x45; }; + void RumblePak_close(void) {}; + void RumblePak_config(void) {}; + void RumblePak_write08(u32 adr, u8 val) { - //INFO("write08 0x%X\n", val); }; + void RumblePak_write16(u32 adr, u16 val) { - //INFO("write16 0x%X\n", val); + if (!FeedbackON) return; + + // CrazyMax 17/01/2009 + // i don't know how send to feedback (PC) impulse with small latency. + if (adr == 0x08000000) + FeedbackON(val); + if (adr == 0x08001000) + FeedbackON(val); }; + void RumblePak_write32(u32 adr, u32 val) { - //INFO("write32 0x%X\n", val); }; + u8 RumblePak_read08(u32 adr) { - u8 val = 0; - - if (adr >= 0x08000000 && adr < 0x080000C0) - val = rumble_hdr[adr & 0xFF]; - if (adr == 0x0801FFFE) val = 0x45; - - return ((u8)val); + return (0); }; u16 RumblePak_read16(u32 adr) { - u16 val = 0; - - if (adr >= 0x08000000 && adr < 0x080000C0) - val = T1ReadWord(rumble_hdr, adr & 0xFF ); - if (adr == 0x0801FFFE) val = 0x0045; + u16 val = ( (adr & 0x1FFFF) >> 1 ) & 0xFFFD; + if (adr == 0x0801FFFE) val = 0x005D; // hack!!! anybody have docs for RumblePak? return ((u16)val); }; + u32 RumblePak_read32(u32 adr) { - u32 val = 0; - if (adr >= 0x08000000 && adr < 0x080000C0) - val = T1ReadLong(rumble_hdr, adr & 0xFF ); - if (adr == 0x0801FFFE) val = 0x00000045; - - return ((u32)val); + return (0); }; + void RumblePak_info(char *info) { strcpy(info, "NDS Rumble Pak (need joystick)"); }; ADDONINTERFACE addonRumblePak = { diff --git a/desmume/src/windows/inputdx.cpp b/desmume/src/windows/inputdx.cpp index 75a2cce1c..c433f9adb 100644 --- a/desmume/src/windows/inputdx.cpp +++ b/desmume/src/windows/inputdx.cpp @@ -2,7 +2,7 @@ yopyop156@ifrance.com yopyop156.ifrance.com - Copyright (C) 2006-2008 DeSmuME team + Copyright (C) 2006-2009 DeSmuME team This file is part of DeSmuME @@ -28,6 +28,7 @@ #include "..\debug.h" #include "..\MMU.h" #include "..\common.h" +#include "..\addons.h" #include "resource.h" #include "NDSSystem.h" @@ -208,6 +209,8 @@ const int inputIDs[15]={ IDC_EDIT06, IDC_EDIT05, IDC_EDIT11, IDC_EDIT12, IDC_EDI u16 keyPad[15]; extern INPUTCLASS *input; +void NDS_inputFeedback(BOOL enable); + // ==================================================== Config Input INPUTCLASS *inputCfg = NULL; HWND g_hWnd = NULL; @@ -398,6 +401,8 @@ void NDS_inputInit() } } } + + FeedbackON = NDS_inputFeedback; } void NDS_inputPost(BOOL paused, LPSTR buf) @@ -422,6 +427,11 @@ void NDS_inputPost(BOOL paused, LPSTR buf) NDS_setPad( R, L, D, U, T, S, B, A, Y, X, W, E, G, F); } +void NDS_inputFeedback(BOOL enable) +{ + input->JoystickFeedback(enable); +} + // TODO // ==================================================== GUI input // ======================================================================= @@ -431,6 +441,12 @@ void NDS_inputPost(BOOL paused, LPSTR buf) // =============================================================== // =============================================================== // =============================================================== +static LPDIRECTINPUT8 tmp_pDI = NULL; +static BOOL tmp_Feedback = FALSE; +static char tmp_device_name[255] = { 0 }; +static LPDIRECTINPUTDEVICE8 tmp_Device = NULL; +static LPDIRECTINPUTDEVICE8 tmp_Joystick = NULL; + INPUTCLASS::INPUTCLASS() { hParentWnd = NULL; @@ -443,20 +459,81 @@ INPUTCLASS::~INPUTCLASS() { if (pKeyboard != NULL) { - IDirectInputDevice8_Unacquire(pKeyboard); - IDirectInputDevice8_Release(pKeyboard); + pKeyboard->Unacquire(); + pKeyboard->Release(); pKeyboard = NULL; } if (pJoystick != NULL) { - IDirectInputDevice8_Unacquire(pJoystick); - IDirectInputDevice8_Release(pJoystick); + pEffect->Stop(); + pEffect->Release(); + pJoystick->Unacquire(); + pJoystick->Release(); pJoystick = NULL; } + pDI->Release(); } } +extern BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) +{ + DI_CLASS *tmp = (DI_CLASS *)lpddi; + return tmp->EnumCallback(lpddi, pvRef); +} + +LPDIRECTINPUTDEVICE8 DI_CLASS::EnumDevices(LPDIRECTINPUT8 pDI) +{ + tmp_pDI = pDI; + tmp_Feedback = FALSE; + memset(tmp_device_name, 0, 255); + if( FAILED( pDI->EnumDevices(DI8DEVCLASS_GAMECTRL, + ::EnumCallback, + NULL, + DIEDFL_ATTACHEDONLY) ) ) + return NULL; + Feedback = tmp_Feedback; + strcpy(JoystickName, tmp_device_name); + return tmp_Device; +} + +BOOL DI_CLASS::EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) +{ + if ( FAILED( tmp_pDI->CreateDevice(lpddi->guidInstance, &tmp_Device, NULL) ) ) + { + tmp_Device = NULL; + return DIENUM_CONTINUE; + } + + strcpy(tmp_device_name, lpddi->tszProductName); + if (lpddi->guidFFDriver.Data1) tmp_Feedback = TRUE; + return DIENUM_STOP; +} + +extern BOOL CALLBACK EnumObjects(const DIDEVICEOBJECTINSTANCE* pdidoi,VOID* pContext) +{ + DI_CLASS *tmp = (DI_CLASS *)pdidoi; + return tmp->EnumObjects(pdidoi, pContext); +} + +BOOL CALLBACK DI_CLASS::EnumObjects(const DIDEVICEOBJECTINSTANCE* pdidoi,VOID* pContext) +{ + if( pdidoi->dwType & DIDFT_AXIS ) + { + DIPROPRANGE diprg; + diprg.diph.dwSize = sizeof(DIPROPRANGE); + diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); + diprg.diph.dwHow = DIPH_BYID; + diprg.diph.dwObj = pdidoi->dwType; + diprg.lMin = -3; + diprg.lMax = 3; + + if( FAILED(tmp_Joystick->SetProperty(DIPROP_RANGE, &diprg.diph)) ) + return DIENUM_STOP; + } + return DIENUM_CONTINUE; +} + BOOL INPUTCLASS::Init(HWND hParentWnd, INPUTPROC inputProc) { if (hParentWnd == NULL) return FALSE; @@ -467,59 +544,109 @@ BOOL INPUTCLASS::Init(HWND hParentWnd, INPUTPROC inputProc) pDI = NULL; pKeyboard = NULL; pJoystick = NULL; + Feedback = FALSE; memset(cDIBuf, 0, sizeof(cDIBuf)); + memset(JoystickName, 0, sizeof(JoystickName)); if(FAILED(DirectInput8Create(GetModuleHandle(NULL),DIRECTINPUT_VERSION,IID_IDirectInput8,(void**)&pDI,NULL))) return FALSE; - if (!FAILED(IDirectInput8_CreateDevice(pDI,GUID_SysKeyboard,&pKeyboard,NULL))) + if (!FAILED(pDI->CreateDevice(GUID_SysKeyboard,&pKeyboard,NULL))) { - if (!FAILED(IDirectInputDevice8_SetDataFormat(pKeyboard,&c_dfDIKeyboard))) + if (!FAILED(pKeyboard->SetDataFormat(&c_dfDIKeyboard))) { - if (FAILED(IDirectInputDevice8_SetCooperativeLevel(pKeyboard,hParentWnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE))) + if (FAILED(pKeyboard->SetCooperativeLevel(hParentWnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE))) { - IDirectInputDevice8_Release(pKeyboard); + pKeyboard->Release(); pKeyboard = NULL; } } else { - IDirectInputDevice8_Release(pKeyboard); + pKeyboard->Release(); pKeyboard = NULL; } } - if (!FAILED(IDirectInput8_CreateDevice(pDI,GUID_Joystick,&pJoystick,NULL))) + pJoystick = EnumDevices(pDI); + + if (pJoystick) { - if(!FAILED(IDirectInputDevice8_SetDataFormat(pJoystick,&c_dfDIJoystick2))) + if(!FAILED(pJoystick->SetDataFormat(&c_dfDIJoystick2))) { - if(FAILED(IDirectInputDevice8_SetCooperativeLevel(pJoystick,hParentWnd,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE))) + if(FAILED(pJoystick->SetCooperativeLevel(hParentWnd,DISCL_FOREGROUND|DISCL_EXCLUSIVE))) { - IDirectInputDevice8_Release(pJoystick); + pJoystick->Release(); pJoystick = NULL; } else { + tmp_Joystick = pJoystick; + pJoystick->EnumObjects(::EnumObjects, (VOID*)hParentWnd, DIDFT_ALL); memset(&DIJoycap,0,sizeof(DIDEVCAPS)); DIJoycap.dwSize=sizeof(DIDEVCAPS); - IDirectInputDevice8_GetCapabilities(pJoystick,&DIJoycap); + pJoystick->GetCapabilities(&DIJoycap); } } else { - IDirectInputDevice8_Release(pJoystick); + pJoystick->Release(); pJoystick = NULL; } } + if (pJoystick) + { + DIPROPDWORD dipdw; + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = 0; + if ( !FAILED( pJoystick->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph) ) ) + { + DWORD rgdwAxes[1] = { DIJOFS_Y }; + LONG rglDirection[2] = { 0 }; + DICONSTANTFORCE cf = { 0 }; + DIEFFECT eff; + + cf.lMagnitude = (DI_FFNOMINALMAX * 100); + + memset(&eff, 0, sizeof(eff)); + eff.dwSize = sizeof(DIEFFECT); + eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + eff.dwDuration = INFINITE; + eff.dwSamplePeriod = 0; + eff.dwGain = DI_FFNOMINALMAX; + eff.dwTriggerButton = DIEB_NOTRIGGER; + eff.dwTriggerRepeatInterval = 0; + eff.cAxes = 1; + eff.rgdwAxes = rgdwAxes; + eff.rglDirection = rglDirection; + eff.lpEnvelope = 0; + eff.cbTypeSpecificParams = sizeof( DICONSTANTFORCE ); + eff.lpvTypeSpecificParams = &cf; + eff.dwStartDelay = 0; + + if( FAILED( pJoystick->CreateEffect(GUID_ConstantForce, &eff, &pEffect, NULL) ) ) + Feedback = FALSE; + } + else + Feedback = FALSE; + } + if (pKeyboard == NULL && pJoystick == NULL) return FALSE; this->inputProc = inputProc; -#if 1 - if (pKeyboard != NULL) INFO("DirectX Input: keyboard is initialised\n"); - if (pJoystick != NULL) INFO("DirectX Input: joystick is initialised\n"); -#endif + INFO("DirectX Input: \n"); + if (pKeyboard != NULL) INFO(" - keyboard successfully inited\n"); + if (pJoystick != NULL) + { + INFO(" - gamecontrol successfully inited: %s\n", JoystickName); + if (Feedback) INFO("\t\t\t\t (with FeedBack support)\n"); + } + paused = FALSE; return TRUE; @@ -539,32 +666,30 @@ void INPUTCLASS::process() if (pKeyboard) { - hr=IDirectInputDevice8_GetDeviceState(pKeyboard,256,cDIBuf); + hr=pKeyboard->GetDeviceState(256,cDIBuf); if (FAILED(hr)) - { - //LOG("DInput: keyboard acquire\n"); - IDirectInputDevice8_Acquire(pKeyboard); - } + pKeyboard->Acquire(); } if (pJoystick) { DIJOYSTATE2 JoyStatus; - hr=IDirectInputDevice8_Poll(pJoystick); - if (FAILED(hr)) IDirectInputDevice8_Acquire(pJoystick); + hr=pJoystick->Poll(); + if (FAILED(hr)) + pJoystick->Acquire(); else { - hr=IDirectInputDevice8_GetDeviceState(pJoystick,sizeof(JoyStatus),&JoyStatus); - if (FAILED(hr)) hr=IDirectInputDevice8_Acquire(pJoystick); + hr=pJoystick->GetDeviceState(sizeof(JoyStatus),&JoyStatus); + if (FAILED(hr)) hr=pJoystick->Acquire(); else { - memset(cDIBuf+255,0,sizeof(cDIBuf)-255); - //TODO: analog - //if (JoyStatus.lX<-1) cDIBuf[258]=-128; - //if (JoyStatus.lX>1) cDIBuf[259]=-128; - //if (JoyStatus.lY<-1) cDIBuf[256]=-128; - //if (JoyStatus.lY>1) cDIBuf[257]=-128; + memset(cDIBuf+255, 0, sizeof(cDIBuf)-255); + + if (JoyStatus.lX<-1) cDIBuf[258]=-128; + if (JoyStatus.lX>1) cDIBuf[259]=-128; + if (JoyStatus.lY<-1) cDIBuf[256]=-128; + if (JoyStatus.lY>1) cDIBuf[257]=-128; if (JoyStatus.rgdwPOV[0]==0) cDIBuf[256]=-128; if (JoyStatus.rgdwPOV[0]==4500) { cDIBuf[256]=-128; cDIBuf[259]=-128;} @@ -574,11 +699,22 @@ void INPUTCLASS::process() if (JoyStatus.rgdwPOV[0]==22500) { cDIBuf[257]=-128; cDIBuf[258]=-128;} if (JoyStatus.rgdwPOV[0]==27000) cDIBuf[258]=-128; if (JoyStatus.rgdwPOV[0]==31500) { cDIBuf[258]=-128; cDIBuf[256]=-128;} - memcpy(cDIBuf+260,JoyStatus.rgbButtons,sizeof(JoyStatus.rgbButtons)); + memcpy(cDIBuf+260, JoyStatus.rgbButtons, sizeof(JoyStatus.rgbButtons)); } } } this->inputProc(paused, (LPSTR)&cDIBuf); } -// ==================================================== END INPUTCLASS \ No newline at end of file + +void INPUTCLASS::JoystickFeedback(BOOL on) +{ + if (!Feedback) return; + if (!pEffect) return; + + if (on) + pEffect->Start(2, 0); + else + pEffect->Stop(); +} +// ==================================================== END INPUTCLASS