- fix lid folding;
- fix rumblePak addon;
winport:
- added feedback support & analog joysticks;
This commit is contained in:
mtabachenko 2009-01-17 11:47:13 +00:00
parent 02b6c46751
commit 2efd0e19e0
5 changed files with 215 additions and 83 deletions

View File

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

View File

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

View File

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

View File

@ -25,62 +25,57 @@
#include "../mem.h"
#include "../MMU.h"
#include <string.h>
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 = {

View File

@ -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
void INPUTCLASS::JoystickFeedback(BOOL on)
{
if (!Feedback) return;
if (!pEffect) return;
if (on)
pEffect->Start(2, 0);
else
pEffect->Stop();
}
// ==================================================== END INPUTCLASS