2009-09-02 21:00:45 +00:00
|
|
|
|
2008-12-08 05:25:12 +00:00
|
|
|
// Project description
|
2009-09-08 16:07:13 +00:00
|
|
|
// -------------------
|
2009-01-15 06:48:15 +00:00
|
|
|
// Name: nJoy
|
2008-12-08 05:25:12 +00:00
|
|
|
// Description: A Dolphin Compatible Input Plugin
|
|
|
|
//
|
|
|
|
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
|
|
|
// Site: www.multigesture.net
|
2009-07-28 21:32:10 +00:00
|
|
|
// Copyright (C) 2003 Dolphin Project.
|
2008-12-08 05:25:12 +00:00
|
|
|
//
|
2009-09-02 21:00:45 +00:00
|
|
|
|
2008-12-08 05:25:12 +00:00
|
|
|
//
|
|
|
|
// Licensetype: GNU General Public License (GPL)
|
|
|
|
//
|
|
|
|
// 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, version 2.0.
|
|
|
|
//
|
|
|
|
// 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 2.0 for more details.
|
|
|
|
//
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
//
|
|
|
|
// Official SVN repository and contact information can be found at
|
|
|
|
// http://code.google.com/p/dolphin-emu/
|
|
|
|
//
|
2009-09-02 21:00:45 +00:00
|
|
|
|
2008-12-26 02:42:15 +00:00
|
|
|
// Include
|
2009-09-08 16:07:13 +00:00
|
|
|
// ---------
|
2008-12-08 05:25:12 +00:00
|
|
|
#include "nJoy.h"
|
2009-07-12 21:58:32 +00:00
|
|
|
#include "LogManager.h"
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2008-12-27 11:32:03 +00:00
|
|
|
// Declare config window so that we can write debugging info to it from functions in this file
|
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
2009-07-03 03:01:58 +00:00
|
|
|
PADConfigDialognJoy* m_ConfigFrame = NULL;
|
2008-12-27 11:32:03 +00:00
|
|
|
#endif
|
2009-09-02 21:00:45 +00:00
|
|
|
|
2008-12-27 11:32:03 +00:00
|
|
|
|
2009-09-02 21:00:45 +00:00
|
|
|
|
2008-12-08 05:25:12 +00:00
|
|
|
// Variables
|
2009-09-08 16:07:13 +00:00
|
|
|
// ---------
|
2009-02-10 14:02:01 +00:00
|
|
|
#define _EXCLUDE_MAIN_ // Avoid certain declarations in nJoy.h
|
2008-12-08 05:25:12 +00:00
|
|
|
FILE *pFile;
|
2009-02-10 14:02:01 +00:00
|
|
|
std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
|
|
|
|
InputCommon::CONTROLLER_STATE PadState[4];
|
|
|
|
InputCommon::CONTROLLER_MAPPING PadMapping[4];
|
|
|
|
bool g_EmulatorRunning = false;
|
2010-01-01 03:19:46 +00:00
|
|
|
bool g_SearchDeviceDone = false;
|
2009-11-14 17:08:32 +00:00
|
|
|
int NumPads = 0, NumGoodPads = 0, LastPad = 0;
|
2009-02-11 10:30:02 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
HWND m_hWnd = NULL, m_hConsole = NULL; // Handle to window
|
|
|
|
#endif
|
2009-02-01 20:45:27 +00:00
|
|
|
SPADInitialize *g_PADInitialize = NULL;
|
2009-03-18 17:17:58 +00:00
|
|
|
PLUGIN_GLOBALS* globals = NULL;
|
2008-12-26 09:20:01 +00:00
|
|
|
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-07-03 03:01:58 +00:00
|
|
|
// Standard crap to make wxWidgets happy
|
|
|
|
#ifdef _WIN32
|
|
|
|
HINSTANCE g_hInstance;
|
|
|
|
|
2008-12-26 02:42:15 +00:00
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
2009-07-03 03:01:58 +00:00
|
|
|
class wxDLLApp : public wxApp
|
|
|
|
{
|
|
|
|
bool OnInit()
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-07-03 03:01:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
IMPLEMENT_APP_NO_MAIN(wxDLLApp)
|
2008-12-26 02:42:15 +00:00
|
|
|
WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
|
2008-12-14 23:52:01 +00:00
|
|
|
#endif
|
2008-12-26 02:42:15 +00:00
|
|
|
|
2009-07-03 03:01:58 +00:00
|
|
|
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
|
|
|
|
DWORD dwReason, // reason called
|
|
|
|
LPVOID lpvReserved) // reserved
|
2009-01-15 06:48:15 +00:00
|
|
|
{
|
2008-12-08 05:25:12 +00:00
|
|
|
switch (dwReason)
|
|
|
|
{
|
2009-07-03 03:01:58 +00:00
|
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
{
|
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
2008-12-08 05:25:12 +00:00
|
|
|
wxSetInstance((HINSTANCE)hinstDLL);
|
|
|
|
int argc = 0;
|
|
|
|
char **argv = NULL;
|
|
|
|
wxEntryStart(argc, argv);
|
2009-07-03 03:01:58 +00:00
|
|
|
if (!wxTheApp || !wxTheApp->CallOnInit())
|
2008-12-08 05:25:12 +00:00
|
|
|
return FALSE;
|
2009-07-03 03:01:58 +00:00
|
|
|
#endif
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-07-03 03:01:58 +00:00
|
|
|
break;
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-07-03 03:01:58 +00:00
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
|
|
|
wxEntryCleanup();
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
default:
|
2008-12-08 05:25:12 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-01-15 06:48:15 +00:00
|
|
|
|
2009-07-03 03:01:58 +00:00
|
|
|
g_hInstance = hinstDLL;
|
2008-12-08 05:25:12 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-07-03 03:01:58 +00:00
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
|
|
|
wxWindow* GetParentedWxWindow(HWND Parent)
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
wxSetInstance((HINSTANCE)g_hInstance);
|
|
|
|
#endif
|
|
|
|
wxWindow *win = new wxWindow();
|
|
|
|
#ifdef _WIN32
|
|
|
|
win->SetHWND((WXHWND)Parent);
|
|
|
|
win->AdoptAttributesFromHWND();
|
|
|
|
#endif
|
|
|
|
return win;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-01-19 17:47:00 +00:00
|
|
|
|
2009-09-02 21:00:45 +00:00
|
|
|
|
2008-12-08 05:25:12 +00:00
|
|
|
// Input Plugin Functions (from spec's)
|
2009-09-08 16:07:13 +00:00
|
|
|
// ------------------------------------
|
2008-12-08 05:25:12 +00:00
|
|
|
|
|
|
|
// Get properties of plugin
|
2009-09-08 16:07:13 +00:00
|
|
|
// ------------------------
|
2008-12-08 05:25:12 +00:00
|
|
|
void GetDllInfo(PLUGIN_INFO* _PluginInfo)
|
|
|
|
{
|
|
|
|
_PluginInfo->Version = 0x0100;
|
|
|
|
_PluginInfo->Type = PLUGIN_TYPE_PAD;
|
|
|
|
|
2009-01-15 06:48:15 +00:00
|
|
|
#ifdef DEBUGFAST
|
2009-10-24 00:18:21 +00:00
|
|
|
sprintf(_PluginInfo->Name, "nJoy (DebugFast) by Falcon4ever");
|
2008-12-08 05:25:12 +00:00
|
|
|
#else
|
|
|
|
#ifndef _DEBUG
|
2009-10-24 00:18:21 +00:00
|
|
|
sprintf(_PluginInfo->Name, "nJoy by Falcon4ever");
|
2008-12-08 05:25:12 +00:00
|
|
|
#else
|
2009-10-24 00:18:21 +00:00
|
|
|
sprintf(_PluginInfo->Name, "nJoy (Debug) by Falcon4ever");
|
2008-12-08 05:25:12 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2009-03-18 17:17:58 +00:00
|
|
|
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
|
|
|
|
{
|
|
|
|
globals = _pPluginGlobals;
|
|
|
|
LogManager::SetInstance((LogManager *)globals->logManager);
|
|
|
|
}
|
|
|
|
|
2009-01-08 12:12:15 +00:00
|
|
|
|
2008-12-08 05:25:12 +00:00
|
|
|
// Call config dialog
|
2009-09-08 16:07:13 +00:00
|
|
|
// ------------------
|
2008-12-08 05:25:12 +00:00
|
|
|
void DllConfig(HWND _hParent)
|
2009-01-15 06:48:15 +00:00
|
|
|
{
|
2010-01-01 03:19:46 +00:00
|
|
|
if (!g_SearchDeviceDone)
|
2009-12-31 17:42:55 +00:00
|
|
|
{
|
|
|
|
g_Config.Load(); // load settings
|
|
|
|
// Init Joystick + Haptic (force feedback) subsystem on SDL 1.3
|
|
|
|
// Populate joyinfo for all attached devices
|
|
|
|
Search_Devices(joyinfo, NumPads, NumGoodPads);
|
2010-01-01 03:19:46 +00:00
|
|
|
g_SearchDeviceDone = true;
|
2009-12-31 17:42:55 +00:00
|
|
|
}
|
2009-01-23 21:28:55 +00:00
|
|
|
|
2009-07-03 03:01:58 +00:00
|
|
|
#if defined(HAVE_WX) && HAVE_WX
|
|
|
|
if (!m_ConfigFrame)
|
|
|
|
m_ConfigFrame = new PADConfigDialognJoy(GetParentedWxWindow(_hParent));
|
|
|
|
else if (!m_ConfigFrame->GetParent()->IsShown())
|
|
|
|
m_ConfigFrame->Close(true);
|
|
|
|
|
|
|
|
// Only allow one open at a time
|
|
|
|
if (!m_ConfigFrame->IsShown())
|
2009-11-14 17:08:32 +00:00
|
|
|
m_ConfigFrame->ShowModal();
|
2009-07-03 03:01:58 +00:00
|
|
|
else
|
2009-11-14 17:08:32 +00:00
|
|
|
m_ConfigFrame->Hide();
|
2009-07-03 03:01:58 +00:00
|
|
|
#endif
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
|
|
|
|
2009-01-24 22:13:53 +00:00
|
|
|
void DllDebugger(HWND _hParent, bool Show) {}
|
2008-12-17 17:49:38 +00:00
|
|
|
|
2009-01-15 06:48:15 +00:00
|
|
|
|
2008-12-08 05:25:12 +00:00
|
|
|
// Init PAD (start emulation)
|
2009-09-08 16:07:13 +00:00
|
|
|
// --------------------------
|
2009-01-15 06:48:15 +00:00
|
|
|
void Initialize(void *init)
|
|
|
|
{
|
2009-12-14 02:23:14 +00:00
|
|
|
INFO_LOG(PAD, "Initialize: %i", SDL_WasInit(0));
|
2009-02-01 16:29:35 +00:00
|
|
|
g_PADInitialize = (SPADInitialize*)init;
|
2009-02-10 14:02:01 +00:00
|
|
|
g_EmulatorRunning = true;
|
2009-04-02 21:13:58 +00:00
|
|
|
|
2009-12-31 17:42:55 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
m_hWnd = (HWND)g_PADInitialize->hWnd;
|
|
|
|
#endif
|
2009-01-15 06:48:15 +00:00
|
|
|
|
2009-12-31 17:42:55 +00:00
|
|
|
#ifdef _DEBUG
|
|
|
|
DEBUG_INIT();
|
|
|
|
#endif
|
2009-12-14 02:23:14 +00:00
|
|
|
|
2010-01-01 03:19:46 +00:00
|
|
|
if (!g_SearchDeviceDone)
|
2009-12-31 17:42:55 +00:00
|
|
|
{
|
|
|
|
g_Config.Load(); // load settings
|
|
|
|
// Populate joyinfo for all attached devices
|
|
|
|
Search_Devices(joyinfo, NumPads, NumGoodPads);
|
2010-01-01 03:19:46 +00:00
|
|
|
g_SearchDeviceDone = true;
|
2009-12-31 17:42:55 +00:00
|
|
|
}
|
2008-12-27 11:32:03 +00:00
|
|
|
}
|
|
|
|
|
2009-12-14 02:23:14 +00:00
|
|
|
void Close_Devices()
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-10-24 00:18:21 +00:00
|
|
|
PAD_RumbleClose();
|
2009-01-24 22:13:53 +00:00
|
|
|
/* Close all devices carefully. We must check that we are not accessing any undefined
|
|
|
|
vector elements or any bad devices */
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
{
|
2009-12-13 04:31:38 +00:00
|
|
|
if (SDL_WasInit(0) && joyinfo.size() > (u32)PadMapping[i].ID)
|
|
|
|
if (PadState[i].joy && joyinfo.at(PadMapping[i].ID).Good)
|
2009-11-14 17:08:32 +00:00
|
|
|
if(SDL_JoystickOpened(PadMapping[i].ID))
|
|
|
|
{
|
|
|
|
SDL_JoystickClose(PadState[i].joy);
|
|
|
|
PadState[i].joy = NULL;
|
|
|
|
}
|
2009-01-24 22:13:53 +00:00
|
|
|
}
|
2009-01-23 10:00:59 +00:00
|
|
|
|
2009-02-10 14:02:01 +00:00
|
|
|
// Clear the physical device info
|
|
|
|
joyinfo.clear();
|
2009-02-11 10:30:02 +00:00
|
|
|
NumPads = 0;
|
2009-11-14 17:08:32 +00:00
|
|
|
NumGoodPads = 0;
|
2009-12-14 02:23:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Shutdown PAD (stop emulation)
|
|
|
|
// -----------------------------
|
|
|
|
/* Information: This function can not be run twice without an Initialize in between. If
|
|
|
|
it's run twice the SDL_...() functions below will cause a crash.
|
|
|
|
Called from: The Dolphin Core, PADConfigDialognJoy::OnClose() */
|
|
|
|
void Shutdown()
|
|
|
|
{
|
|
|
|
INFO_LOG(PAD, "Shutdown: %i", SDL_WasInit(0));
|
|
|
|
|
|
|
|
// Always change this variable
|
|
|
|
g_EmulatorRunning = false;
|
|
|
|
|
|
|
|
// Stop debugging
|
|
|
|
#ifdef _DEBUG
|
|
|
|
DEBUG_QUIT();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Close_Devices();
|
2009-02-10 14:02:01 +00:00
|
|
|
|
|
|
|
// Finally close SDL
|
2009-12-13 04:31:38 +00:00
|
|
|
if (SDL_WasInit(0))
|
|
|
|
SDL_Quit();
|
2009-01-23 10:00:59 +00:00
|
|
|
|
2009-02-11 10:30:02 +00:00
|
|
|
// Remove the pointer to the initialize data
|
|
|
|
g_PADInitialize = NULL;
|
2010-01-03 23:05:52 +00:00
|
|
|
g_SearchDeviceDone = false;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
|
|
|
|
2008-12-26 02:42:15 +00:00
|
|
|
|
2009-02-03 10:17:01 +00:00
|
|
|
// Set buttons status from keyboard input. Currently this is done from wxWidgets in the main application.
|
2009-09-08 16:07:13 +00:00
|
|
|
// --------------
|
2009-01-19 17:47:00 +00:00
|
|
|
void PAD_Input(u16 _Key, u8 _UpDown)
|
2008-12-28 18:50:24 +00:00
|
|
|
{
|
2009-02-01 20:45:27 +00:00
|
|
|
// Check that Dolphin is in focus, otherwise don't update the pad status
|
2009-02-03 10:17:01 +00:00
|
|
|
if (!IsFocus()) return;
|
2009-02-01 16:29:35 +00:00
|
|
|
|
2008-12-28 18:50:24 +00:00
|
|
|
// Check if the keys are interesting, and then update it
|
|
|
|
for(int i = 0; i < 4; i++)
|
|
|
|
{
|
2009-12-25 22:10:56 +00:00
|
|
|
if (!PadMapping[i].enable)
|
|
|
|
continue;
|
|
|
|
|
2009-02-10 14:02:01 +00:00
|
|
|
for(int j = InputCommon::CTL_L_SHOULDER; j <= InputCommon::CTL_START; j++)
|
2008-12-28 18:50:24 +00:00
|
|
|
{
|
2009-01-21 18:09:31 +00:00
|
|
|
if (PadMapping[i].buttons[j] == _Key)
|
2009-01-24 22:13:53 +00:00
|
|
|
{ PadState[i].buttons[j] = _UpDown; break; }
|
2008-12-28 18:50:24 +00:00
|
|
|
}
|
2009-01-19 17:47:00 +00:00
|
|
|
|
2009-02-10 14:02:01 +00:00
|
|
|
for(int j = InputCommon::CTL_D_PAD_UP; j <= InputCommon::CTL_D_PAD_RIGHT; j++)
|
2009-01-19 17:47:00 +00:00
|
|
|
{
|
2009-01-21 18:09:31 +00:00
|
|
|
if (PadMapping[i].dpad2[j] == _Key)
|
2009-01-24 22:13:53 +00:00
|
|
|
{ PadState[i].dpad2[j] = _UpDown; break; }
|
2009-01-19 17:47:00 +00:00
|
|
|
}
|
2008-12-28 18:50:24 +00:00
|
|
|
}
|
2009-01-15 06:48:15 +00:00
|
|
|
}
|
2008-12-28 18:50:24 +00:00
|
|
|
|
2009-01-19 17:47:00 +00:00
|
|
|
|
|
|
|
// Save state
|
2009-09-08 16:07:13 +00:00
|
|
|
// --------------
|
2009-02-18 23:26:16 +00:00
|
|
|
void DoState(unsigned char **ptr, int mode)
|
|
|
|
{
|
|
|
|
#ifdef RERECORDING
|
|
|
|
Recording::DoState(ptr, mode);
|
|
|
|
#endif
|
|
|
|
}
|
2009-01-19 17:47:00 +00:00
|
|
|
|
Now you can switch between Emulated and Real WiiMotes, connect more Real Wiimotes and even pair them up (if you have MS BT Stack) during gameplay!
All you gotta do is Pause the emulation! That's useful for when your batteries run out during gameplay, for example...
But if you change the WiiMote source (between Emulated, Real or Inactive) you must disconnect and reconnect (Menu Tools -> Connect WiiMote) the WiiMotes affected by the change...
Thanks to jack.fr0st who did all the emulation state notification work!
Now every plugin has a way to know the current emulation state (paused, stopped or playing)
@ayuanx: I thought about doing a PostMessage(g_WiimoteInitialize.hWnd, WM_USER, WIIMOTE_DISCONNECT, current_number); so that the user gets asked to reconnect that WiiMote, trying to avoid having to disconnect and reconnect, but it didn't work because shooting that message only asks to reconnect, doesn't do a disconnect... Do you have any ideas on how to accomplish that?
Also, if anyone could check if Issue 1916 is finally fixed... Or at least when is the cursor being hidden or not...
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4789 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-01-06 19:26:52 +00:00
|
|
|
void EmuStateChange(PLUGIN_EMUSTATE newState)
|
|
|
|
{
|
|
|
|
}
|
2009-01-19 17:47:00 +00:00
|
|
|
|
|
|
|
// Set PAD status
|
2009-09-08 16:07:13 +00:00
|
|
|
// --------------
|
2009-01-22 00:31:12 +00:00
|
|
|
// Called from: SI_DeviceGCController.cpp
|
2009-01-19 05:49:25 +00:00
|
|
|
// Function: Gives the current pad status to the Core
|
2008-12-08 05:25:12 +00:00
|
|
|
void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
|
|
|
{
|
2009-10-24 00:18:21 +00:00
|
|
|
// Check if the pad is avaliable, currently we don't disable pads just because they are
|
|
|
|
// disconnected
|
2009-12-25 22:10:56 +00:00
|
|
|
if (!PadState[_numPAD].joy)
|
2009-12-14 02:23:14 +00:00
|
|
|
return;
|
2009-01-15 06:48:15 +00:00
|
|
|
|
2008-12-26 02:42:15 +00:00
|
|
|
// Clear pad status
|
2008-12-08 05:25:12 +00:00
|
|
|
memset(_pPADStatus, 0, sizeof(SPADStatus));
|
|
|
|
|
2009-02-10 14:02:01 +00:00
|
|
|
// Check that Dolphin is in focus, otherwise don't update the pad status
|
2009-02-11 10:30:02 +00:00
|
|
|
if (g_Config.bCheckFocus || IsFocus())
|
2009-11-14 17:08:32 +00:00
|
|
|
GetJoyState(PadState[_numPAD], PadMapping[_numPAD], _numPAD, joyinfo[PadMapping[_numPAD].ID].NumButtons);
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-01-20 05:28:30 +00:00
|
|
|
// Get type
|
2009-01-21 18:09:31 +00:00
|
|
|
int TriggerType = PadMapping[_numPAD].triggertype;
|
2009-04-02 21:13:58 +00:00
|
|
|
int TriggerValue = PadState[_numPAD].halfpress ? 100 : 255;
|
2009-01-15 06:48:15 +00:00
|
|
|
|
2009-09-02 21:00:45 +00:00
|
|
|
|
2009-01-19 17:47:00 +00:00
|
|
|
// The analog controls
|
2008-12-27 11:32:03 +00:00
|
|
|
// -----------
|
|
|
|
|
2009-01-19 17:47:00 +00:00
|
|
|
// Read axis values
|
2009-02-10 14:02:01 +00:00
|
|
|
int i_main_stick_x = PadState[_numPAD].axis[InputCommon::CTL_MAIN_X];
|
|
|
|
int i_main_stick_y = -PadState[_numPAD].axis[InputCommon::CTL_MAIN_Y];
|
|
|
|
int i_sub_stick_x = PadState[_numPAD].axis[InputCommon::CTL_SUB_X];
|
|
|
|
int i_sub_stick_y = -PadState[_numPAD].axis[InputCommon::CTL_SUB_Y];
|
|
|
|
int TriggerLeft = PadState[_numPAD].axis[InputCommon::CTL_L_SHOULDER];
|
|
|
|
int TriggerRight = PadState[_numPAD].axis[InputCommon::CTL_R_SHOULDER];
|
2009-01-19 17:47:00 +00:00
|
|
|
|
2008-12-27 11:32:03 +00:00
|
|
|
// Check if we should make adjustments
|
2009-07-09 07:58:36 +00:00
|
|
|
if (PadMapping[_numPAD].bSquareToCircle) InputCommon::Square2Circle(i_main_stick_x, i_main_stick_y, _numPAD, PadMapping[_numPAD].SDiagonal);
|
2009-07-09 00:48:07 +00:00
|
|
|
// Radius adjustment
|
2009-07-09 07:58:36 +00:00
|
|
|
if (PadMapping[_numPAD].bRadiusOnOff) InputCommon::RadiusAdjustment(i_main_stick_x, i_main_stick_y, _numPAD, PadMapping[_numPAD].SRadius);
|
|
|
|
// C-stick
|
|
|
|
if (PadMapping[_numPAD].bSquareToCircleC) InputCommon::Square2Circle(i_sub_stick_x, i_sub_stick_y, _numPAD, PadMapping[_numPAD].SDiagonalC);
|
|
|
|
if (PadMapping[_numPAD].bRadiusOnOffC) InputCommon::RadiusAdjustment(i_sub_stick_x, i_sub_stick_y, _numPAD, PadMapping[_numPAD].SRadiusC);
|
2008-12-27 11:32:03 +00:00
|
|
|
|
2009-01-20 05:28:30 +00:00
|
|
|
// Convert axis values
|
2009-02-10 14:02:01 +00:00
|
|
|
u8 main_stick_x = InputCommon::Pad_Convert(i_main_stick_x);
|
|
|
|
u8 main_stick_y = InputCommon::Pad_Convert(i_main_stick_y);
|
|
|
|
u8 sub_stick_x = InputCommon::Pad_Convert(i_sub_stick_x);
|
|
|
|
u8 sub_stick_y = InputCommon::Pad_Convert(i_sub_stick_y);
|
2009-01-20 05:28:30 +00:00
|
|
|
|
2009-02-01 20:19:21 +00:00
|
|
|
// Convert the triggers values, if we are using analog triggers at all
|
2009-04-02 21:13:58 +00:00
|
|
|
if (PadMapping[_numPAD].triggertype == InputCommon::CTL_TRIGGER_SDL)
|
2009-01-20 14:25:33 +00:00
|
|
|
{
|
2009-04-02 21:13:58 +00:00
|
|
|
if (PadMapping[_numPAD].buttons[InputCommon::CTL_L_SHOULDER] >= 1000) TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
|
|
|
|
if (PadMapping[_numPAD].buttons[InputCommon::CTL_R_SHOULDER] >= 1000) TriggerRight = InputCommon::Pad_Convert(TriggerRight);
|
2009-01-20 14:25:33 +00:00
|
|
|
}
|
2008-12-27 11:32:03 +00:00
|
|
|
|
2009-04-02 21:13:58 +00:00
|
|
|
// Set Deadzone
|
|
|
|
float deadzone = (128.00 * (float)(PadMapping[_numPAD].deadzone + 1.00)) / 100.00;
|
|
|
|
float distance_main = (float)sqrt((float)(main_stick_x * main_stick_x) + (float)(main_stick_y * main_stick_y));
|
|
|
|
float distance_sub = (float)sqrt((float)(sub_stick_x * sub_stick_x) + (float)(sub_stick_y * sub_stick_y));
|
2008-12-27 11:32:03 +00:00
|
|
|
|
|
|
|
// Send values to Dolpin if they are outside the deadzone
|
2009-04-02 21:13:58 +00:00
|
|
|
if (distance_main > deadzone)
|
|
|
|
{
|
|
|
|
_pPADStatus->stickX = main_stick_x;
|
|
|
|
_pPADStatus->stickY = main_stick_y;
|
|
|
|
}
|
|
|
|
if (distance_sub > deadzone)
|
|
|
|
{
|
|
|
|
_pPADStatus->substickX = sub_stick_x;
|
|
|
|
_pPADStatus->substickY = sub_stick_y;
|
|
|
|
}
|
2009-01-15 06:48:15 +00:00
|
|
|
|
2009-09-02 21:00:45 +00:00
|
|
|
|
2009-01-19 17:47:00 +00:00
|
|
|
// The L and R triggers
|
2009-04-02 21:13:58 +00:00
|
|
|
// -----------
|
2009-02-01 20:19:21 +00:00
|
|
|
|
2009-04-02 21:13:58 +00:00
|
|
|
// Neutral value, no button pressed
|
|
|
|
_pPADStatus->button |= PAD_USE_ORIGIN;
|
2008-12-27 11:32:03 +00:00
|
|
|
|
2009-02-01 20:19:21 +00:00
|
|
|
// Check if the digital L button is pressed
|
2009-02-10 14:02:01 +00:00
|
|
|
if (PadState[_numPAD].buttons[InputCommon::CTL_L_SHOULDER])
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-04-02 21:13:58 +00:00
|
|
|
if (!PadState[_numPAD].halfpress)
|
|
|
|
_pPADStatus->button |= PAD_TRIGGER_L;
|
2009-01-20 06:38:29 +00:00
|
|
|
_pPADStatus->triggerLeft = TriggerValue;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-02-22 04:24:53 +00:00
|
|
|
// no the digital L button is not pressed, but the analog left trigger is
|
2009-04-02 21:13:58 +00:00
|
|
|
else if (TriggerLeft > 0)
|
2009-01-19 18:09:03 +00:00
|
|
|
_pPADStatus->triggerLeft = TriggerLeft;
|
2009-01-19 17:47:00 +00:00
|
|
|
|
2009-02-01 20:19:21 +00:00
|
|
|
// Check if the digital R button is pressed
|
2009-02-10 14:02:01 +00:00
|
|
|
if (PadState[_numPAD].buttons[InputCommon::CTL_R_SHOULDER])
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-04-02 21:13:58 +00:00
|
|
|
if (!PadState[_numPAD].halfpress)
|
|
|
|
_pPADStatus->button |= PAD_TRIGGER_R;
|
2009-01-20 06:38:29 +00:00
|
|
|
_pPADStatus->triggerRight = TriggerValue;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-02-22 04:24:53 +00:00
|
|
|
// no the digital R button is not pressed, but the analog right trigger is
|
2009-04-02 21:13:58 +00:00
|
|
|
else if (TriggerRight > 0)
|
2009-01-19 17:47:00 +00:00
|
|
|
_pPADStatus->triggerRight = TriggerRight;
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-04-02 21:13:58 +00:00
|
|
|
// Update the buttons in analog mode too
|
|
|
|
if (TriggerLeft > 0xf0) _pPADStatus->button |= PAD_TRIGGER_L;
|
|
|
|
if (TriggerRight > 0xf0) _pPADStatus->button |= PAD_TRIGGER_R;
|
2009-01-19 18:09:03 +00:00
|
|
|
|
2009-01-19 17:47:00 +00:00
|
|
|
|
2009-09-02 21:00:45 +00:00
|
|
|
|
2009-01-19 17:47:00 +00:00
|
|
|
// The digital buttons
|
|
|
|
// -----------
|
2009-02-10 14:02:01 +00:00
|
|
|
if (PadState[_numPAD].buttons[InputCommon::CTL_A_BUTTON])
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-01-19 05:49:25 +00:00
|
|
|
_pPADStatus->button |= PAD_BUTTON_A;
|
2008-12-08 05:25:12 +00:00
|
|
|
_pPADStatus->analogA = 255; // Perhaps support pressure?
|
|
|
|
}
|
2009-02-10 14:02:01 +00:00
|
|
|
if (PadState[_numPAD].buttons[InputCommon::CTL_B_BUTTON])
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-01-19 05:49:25 +00:00
|
|
|
_pPADStatus->button |= PAD_BUTTON_B;
|
2008-12-08 05:25:12 +00:00
|
|
|
_pPADStatus->analogB = 255; // Perhaps support pressure?
|
|
|
|
}
|
2009-02-10 14:02:01 +00:00
|
|
|
if (PadState[_numPAD].buttons[InputCommon::CTL_X_BUTTON]) _pPADStatus->button|=PAD_BUTTON_X;
|
|
|
|
if (PadState[_numPAD].buttons[InputCommon::CTL_Y_BUTTON]) _pPADStatus->button|=PAD_BUTTON_Y;
|
|
|
|
if (PadState[_numPAD].buttons[InputCommon::CTL_Z_TRIGGER]) _pPADStatus->button|=PAD_TRIGGER_Z;
|
|
|
|
if (PadState[_numPAD].buttons[InputCommon::CTL_START]) _pPADStatus->button|=PAD_BUTTON_START;
|
2008-12-08 05:25:12 +00:00
|
|
|
|
2009-01-19 17:47:00 +00:00
|
|
|
|
2009-09-02 21:00:45 +00:00
|
|
|
|
2009-01-19 17:47:00 +00:00
|
|
|
// The D-pad
|
|
|
|
// -----------
|
2009-02-10 14:02:01 +00:00
|
|
|
if (PadMapping[_numPAD].controllertype == InputCommon::CTL_DPAD_HAT)
|
2008-12-08 05:25:12 +00:00
|
|
|
{
|
2009-01-24 22:13:53 +00:00
|
|
|
if (PadState[_numPAD].dpad == SDL_HAT_LEFTUP || PadState[_numPAD].dpad == SDL_HAT_UP || PadState[_numPAD].dpad == SDL_HAT_RIGHTUP ) _pPADStatus->button|=PAD_BUTTON_UP;
|
|
|
|
if (PadState[_numPAD].dpad == SDL_HAT_LEFTUP || PadState[_numPAD].dpad == SDL_HAT_LEFT || PadState[_numPAD].dpad == SDL_HAT_LEFTDOWN ) _pPADStatus->button|=PAD_BUTTON_LEFT;
|
|
|
|
if (PadState[_numPAD].dpad == SDL_HAT_LEFTDOWN || PadState[_numPAD].dpad == SDL_HAT_DOWN || PadState[_numPAD].dpad == SDL_HAT_RIGHTDOWN ) _pPADStatus->button|=PAD_BUTTON_DOWN;
|
|
|
|
if (PadState[_numPAD].dpad == SDL_HAT_RIGHTUP || PadState[_numPAD].dpad == SDL_HAT_RIGHT || PadState[_numPAD].dpad == SDL_HAT_RIGHTDOWN ) _pPADStatus->button|=PAD_BUTTON_RIGHT;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-10 14:02:01 +00:00
|
|
|
if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_UP])
|
2008-12-27 11:32:03 +00:00
|
|
|
_pPADStatus->button |= PAD_BUTTON_UP;
|
2009-02-10 14:02:01 +00:00
|
|
|
if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_DOWN])
|
2008-12-27 11:32:03 +00:00
|
|
|
_pPADStatus->button |= PAD_BUTTON_DOWN;
|
2009-02-10 14:02:01 +00:00
|
|
|
if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_LEFT])
|
2008-12-27 11:32:03 +00:00
|
|
|
_pPADStatus->button |= PAD_BUTTON_LEFT;
|
2009-02-10 14:02:01 +00:00
|
|
|
if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_RIGHT])
|
2008-12-27 11:32:03 +00:00
|
|
|
_pPADStatus->button |= PAD_BUTTON_RIGHT;
|
2008-12-08 05:25:12 +00:00
|
|
|
}
|
2009-01-15 06:48:15 +00:00
|
|
|
|
2009-01-19 18:09:03 +00:00
|
|
|
// Update error code
|
2008-12-08 05:25:12 +00:00
|
|
|
_pPADStatus->err = PAD_ERR_NONE;
|
|
|
|
}
|
|
|
|
|
2009-01-19 17:47:00 +00:00
|
|
|
|
|
|
|
///////////////////////////////////////////////// Spec functions
|
|
|
|
|
|
|
|
|
2009-02-01 16:29:35 +00:00
|
|
|
//******************************************************************************
|
|
|
|
// Supporting functions
|
|
|
|
//******************************************************************************
|
|
|
|
|
2009-02-18 23:26:16 +00:00
|
|
|
|
2009-09-02 21:00:45 +00:00
|
|
|
|
2009-02-18 23:26:16 +00:00
|
|
|
// Search for SDL devices
|
2009-09-08 16:07:13 +00:00
|
|
|
// ----------------
|
2009-11-14 17:08:32 +00:00
|
|
|
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
|
2009-02-18 23:26:16 +00:00
|
|
|
{
|
2009-12-14 02:23:14 +00:00
|
|
|
// Close opened devices first
|
|
|
|
Close_Devices();
|
|
|
|
|
2009-11-14 17:08:32 +00:00
|
|
|
bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
|
2009-11-12 18:57:35 +00:00
|
|
|
|
2009-11-14 17:08:32 +00:00
|
|
|
// Warn the user if no gamepads are detected
|
|
|
|
if (_NumGoodPads == 0 && g_EmulatorRunning)
|
2009-02-18 23:26:16 +00:00
|
|
|
{
|
2009-11-14 17:08:32 +00:00
|
|
|
PanicAlert("nJoy: No Gamepad Detected");
|
2009-02-18 23:26:16 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the PadState[].joy handle
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
{
|
2009-11-14 17:08:32 +00:00
|
|
|
if (joyinfo.size() > (u32)PadMapping[i].ID)
|
|
|
|
if(joyinfo.at(PadMapping[i].ID).Good)
|
|
|
|
PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID);
|
2009-11-12 18:57:35 +00:00
|
|
|
}
|
|
|
|
|
2009-11-14 17:08:32 +00:00
|
|
|
return Success;
|
2009-02-18 23:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-02-01 16:29:35 +00:00
|
|
|
// Check if Dolphin is in focus
|
2009-09-08 16:07:13 +00:00
|
|
|
// ----------------
|
2009-02-01 16:29:35 +00:00
|
|
|
bool IsFocus()
|
|
|
|
{
|
2009-02-11 10:30:02 +00:00
|
|
|
return true;
|
|
|
|
|
2009-02-01 16:29:35 +00:00
|
|
|
#ifdef _WIN32
|
2009-02-01 20:45:27 +00:00
|
|
|
HWND RenderingWindow = NULL; if (g_PADInitialize) RenderingWindow = g_PADInitialize->hWnd;
|
|
|
|
HWND Parent = GetParent(RenderingWindow);
|
2009-02-01 16:29:35 +00:00
|
|
|
HWND TopLevel = GetParent(Parent);
|
2009-07-03 03:01:58 +00:00
|
|
|
HWND Config = NULL; if (m_ConfigFrame) Config = (HWND)m_ConfigFrame->GetHWND();
|
2009-02-11 10:30:02 +00:00
|
|
|
// Support both rendering to main window and not, and the config and eventual console window
|
|
|
|
if (GetForegroundWindow() == TopLevel || GetForegroundWindow() == RenderingWindow || GetForegroundWindow() == Config || GetForegroundWindow() == m_hConsole)
|
2009-02-01 16:29:35 +00:00
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
#else
|
|
|
|
return true;
|
|
|
|
#endif
|
|
|
|
}
|