mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-03-10 11:48:14 -07:00
Falcon4ever prefers to keep a standalone code copy of nJoy in repository.
Nakee, please make a branch/tag after release so that the code of nJoy will be saved as a standalone plugin git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4998 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
581
Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj
Normal file
581
Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Source/Plugins/Plugin_nJoy_SDL/Res/controller.bmp
Normal file
BIN
Source/Plugins/Plugin_nJoy_SDL/Res/controller.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 375 KiB |
BIN
Source/Plugins/Plugin_nJoy_SDL/Res/njoy.bmp
Normal file
BIN
Source/Plugins/Plugin_nJoy_SDL/Res/njoy.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
275
Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp
Normal file
275
Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
|
||||
// Project description
|
||||
// -------------------
|
||||
// Name: nJoy
|
||||
// Description: A Dolphin Compatible Input Plugin
|
||||
//
|
||||
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
||||
// Site: www.multigesture.net
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
//
|
||||
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
|
||||
// Include
|
||||
// ---------
|
||||
#include "nJoy.h"
|
||||
#include "Common.h"
|
||||
|
||||
Config g_Config;
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
extern PADConfigDialognJoy* m_ConfigFrame;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Run when created
|
||||
// -----------------
|
||||
Config::Config()
|
||||
{
|
||||
// Clear the memory
|
||||
//memset(this, 0, sizeof(Config));
|
||||
}
|
||||
|
||||
|
||||
// Enable output log
|
||||
// -----------------
|
||||
void DEBUG_INIT()
|
||||
{
|
||||
if (pFile)
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
char dateStr [9];
|
||||
_strdate( dateStr);
|
||||
char timeStr [9];
|
||||
_strtime( timeStr );
|
||||
#endif
|
||||
|
||||
pFile = fopen ("nJoy-debug.txt","wt");
|
||||
fprintf(pFile, "nJoy Debug\n");
|
||||
#ifdef _WIN32
|
||||
fprintf(pFile, "Date: %s\nTime: %s\n", dateStr, timeStr);
|
||||
#endif
|
||||
fprintf(pFile, "---------------\n");
|
||||
}
|
||||
|
||||
// Disable output log
|
||||
// ------------------
|
||||
void DEBUG_QUIT()
|
||||
{
|
||||
if (!pFile)
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
char timeStr [9];
|
||||
_strtime(timeStr);
|
||||
|
||||
fprintf(pFile, "_______________\n");
|
||||
fprintf(pFile, "Time: %s", timeStr);
|
||||
#endif
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Save settings to file
|
||||
// ---------------------
|
||||
void Config::Save(int Slot)
|
||||
{
|
||||
// If there are no good pads don't save
|
||||
if (NumGoodPads == 0) return;
|
||||
|
||||
// Load ini file
|
||||
IniFile file;
|
||||
file.Load(FULL_CONFIG_DIR "nJoy.ini");
|
||||
|
||||
// ==================================================================
|
||||
// Global settings
|
||||
// -----------------
|
||||
file.Set("General", "ShowAdvanced", g_Config.bShowAdvanced);
|
||||
file.Set("General", "SaveByID", g_Config.bSaveByID);
|
||||
file.Set("General", "CheckForFocus", g_Config.bCheckFocus);
|
||||
file.Set("General", "NoTriggerFilter", g_Config.bNoTriggerFilter);
|
||||
file.Set("General", "RumbleStrength", g_Config.RumbleStrength);
|
||||
#ifdef RERECORDING
|
||||
file.Set("General", "Recording", g_Config.bRecording);
|
||||
file.Set("General", "Playback", g_Config.bPlayback);
|
||||
#endif
|
||||
// ========================
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
// Should we save this slot?
|
||||
if (Slot != -1 && Slot != i) continue;
|
||||
|
||||
// ==================================================================
|
||||
// Slot specific settings only
|
||||
// -----------------
|
||||
std::string SectionName = StringFromFormat("PAD%i", i+1);
|
||||
|
||||
// Save the physical device ID
|
||||
file.Set(SectionName.c_str(), "joy_id", PadMapping[i].ID);
|
||||
file.Set(SectionName.c_str(), "enable", PadMapping[i].enable);
|
||||
// ===================
|
||||
|
||||
// ==================================================================
|
||||
// Joypad or slot specific settings
|
||||
// -----------------
|
||||
// Current joypad device ID: PadMapping[i].ID
|
||||
// Current joypad name: joyinfo[PadMapping[i].ID].Name
|
||||
if(g_Config.bSaveByID)
|
||||
{
|
||||
/* Save joypad specific settings. Check for "PadMapping[i].ID < SDL_NumJoysticks()" to
|
||||
avoid reading a joyinfo that does't exist */
|
||||
if((u32)PadMapping[i].ID >= joyinfo.size()) continue;
|
||||
|
||||
// Create a new section name after the joypad name
|
||||
SectionName = joyinfo[PadMapping[i].ID].Name;
|
||||
}
|
||||
|
||||
file.Set(SectionName.c_str(), "l_shoulder", PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER]);
|
||||
file.Set(SectionName.c_str(), "r_shoulder", PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER]);
|
||||
file.Set(SectionName.c_str(), "a_button", PadMapping[i].buttons[InputCommon::CTL_A_BUTTON]);
|
||||
file.Set(SectionName.c_str(), "b_button", PadMapping[i].buttons[InputCommon::CTL_B_BUTTON]);
|
||||
file.Set(SectionName.c_str(), "x_button", PadMapping[i].buttons[InputCommon::CTL_X_BUTTON]);
|
||||
file.Set(SectionName.c_str(), "y_button", PadMapping[i].buttons[InputCommon::CTL_Y_BUTTON]);
|
||||
file.Set(SectionName.c_str(), "z_trigger", PadMapping[i].buttons[InputCommon::CTL_Z_TRIGGER]);
|
||||
file.Set(SectionName.c_str(), "start_button", PadMapping[i].buttons[InputCommon::CTL_START]);
|
||||
file.Set(SectionName.c_str(), "dpad", PadMapping[i].dpad);
|
||||
file.Set(SectionName.c_str(), "dpad_up", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_UP]);
|
||||
file.Set(SectionName.c_str(), "dpad_down", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_DOWN]);
|
||||
file.Set(SectionName.c_str(), "dpad_left", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_LEFT]);
|
||||
file.Set(SectionName.c_str(), "dpad_right", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_RIGHT]);
|
||||
file.Set(SectionName.c_str(), "main_x", PadMapping[i].axis[InputCommon::CTL_MAIN_X]);
|
||||
file.Set(SectionName.c_str(), "main_y", PadMapping[i].axis[InputCommon::CTL_MAIN_Y]);
|
||||
file.Set(SectionName.c_str(), "sub_x", PadMapping[i].axis[InputCommon::CTL_SUB_X]);
|
||||
file.Set(SectionName.c_str(), "sub_y", PadMapping[i].axis[InputCommon::CTL_SUB_Y]);
|
||||
|
||||
file.Set(SectionName.c_str(), "deadzone", PadMapping[i].deadzone);
|
||||
file.Set(SectionName.c_str(), "halfpress", PadMapping[i].halfpress);
|
||||
|
||||
file.Set(SectionName.c_str(), "controllertype", PadMapping[i].controllertype);
|
||||
file.Set(SectionName.c_str(), "TriggerType", PadMapping[i].triggertype);
|
||||
file.Set(SectionName.c_str(), "eventnum", PadMapping[i].eventnum);
|
||||
file.Set(SectionName.c_str(), "use_rumble", PadMapping[i].rumble);
|
||||
|
||||
file.Set(SectionName.c_str(), "Radius", PadMapping[i].SRadius);
|
||||
file.Set(SectionName.c_str(), "RadiusOnOff", PadMapping[i].bRadiusOnOff);
|
||||
file.Set(SectionName.c_str(), "Diagonal", PadMapping[i].SDiagonal);
|
||||
file.Set(SectionName.c_str(), "SquareToCircle", PadMapping[i].bSquareToCircle);
|
||||
file.Set(SectionName.c_str(), "RadiusC", PadMapping[i].SRadiusC);
|
||||
file.Set(SectionName.c_str(), "RadiusOnOffC", PadMapping[i].bRadiusOnOffC);
|
||||
file.Set(SectionName.c_str(), "DiagonalC", PadMapping[i].SDiagonalC);
|
||||
file.Set(SectionName.c_str(), "SquareToCircleC", PadMapping[i].bSquareToCircleC);
|
||||
}
|
||||
|
||||
INFO_LOG(CONSOLE, "%i: Save: %i\n", 0, PadMapping[0].halfpress);
|
||||
|
||||
file.Save(FULL_CONFIG_DIR "nJoy.ini");
|
||||
}
|
||||
|
||||
// Load settings from file
|
||||
// -----------------------
|
||||
void Config::Load(bool ChangePad, bool ChangeSaveByID)
|
||||
{
|
||||
// Load file
|
||||
IniFile file;
|
||||
file.Load(FULL_CONFIG_DIR "nJoy.ini");
|
||||
bool Tmp;
|
||||
|
||||
// ==================================================================
|
||||
// Global settings
|
||||
// -----------------
|
||||
file.Get("General", "ShowAdvanced", &g_Config.bShowAdvanced, false);
|
||||
file.Get("General", "CheckForFocus", &g_Config.bCheckFocus, false);
|
||||
file.Get("General", "NoTriggerFilter", &g_Config.bNoTriggerFilter, false);
|
||||
file.Get("General", "RumbleStrength", &g_Config.RumbleStrength, 8);
|
||||
|
||||
if(!ChangeSaveByID)
|
||||
{
|
||||
file.Get("General", "SaveByID", &Tmp, false); g_Config.bSaveByID = Tmp;
|
||||
}
|
||||
// =============
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
std::string SectionName = StringFromFormat("PAD%i", i+1);
|
||||
|
||||
// Don't update this when we are loading settings from the PADConfigDialognJoy
|
||||
if (!ChangePad)
|
||||
{
|
||||
file.Get(SectionName.c_str(), "joy_id", &PadMapping[i].ID, 0);
|
||||
file.Get(SectionName.c_str(), "enable", &PadMapping[i].enable, false);
|
||||
}
|
||||
|
||||
// ==================================================================
|
||||
// Joypad or slot specific settings
|
||||
// -----------------
|
||||
// Current joypad device ID: PadMapping[i].ID
|
||||
// Current joypad name: joyinfo[PadMapping[i].ID].Name
|
||||
if(g_Config.bSaveByID)
|
||||
{
|
||||
// Prevent a crash from illegal access to joyinfo that will only have values for
|
||||
// the current amount of connected pads
|
||||
if((u32)PadMapping[i].ID >= joyinfo.size()) continue;
|
||||
|
||||
// Create a section name
|
||||
SectionName = joyinfo[PadMapping[i].ID].Name;
|
||||
}
|
||||
|
||||
file.Get(SectionName.c_str(), "l_shoulder", &PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER], 4);
|
||||
file.Get(SectionName.c_str(), "r_shoulder", &PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER], 5);
|
||||
file.Get(SectionName.c_str(), "a_button", &PadMapping[i].buttons[InputCommon::CTL_A_BUTTON], 0);
|
||||
file.Get(SectionName.c_str(), "b_button", &PadMapping[i].buttons[InputCommon::CTL_B_BUTTON], 1);
|
||||
file.Get(SectionName.c_str(), "x_button", &PadMapping[i].buttons[InputCommon::CTL_X_BUTTON], 3);
|
||||
file.Get(SectionName.c_str(), "y_button", &PadMapping[i].buttons[InputCommon::CTL_Y_BUTTON], 2);
|
||||
file.Get(SectionName.c_str(), "z_trigger", &PadMapping[i].buttons[InputCommon::CTL_Z_TRIGGER], 7);
|
||||
file.Get(SectionName.c_str(), "start_button", &PadMapping[i].buttons[InputCommon::CTL_START], 9);
|
||||
file.Get(SectionName.c_str(), "dpad", &PadMapping[i].dpad, 0);
|
||||
file.Get(SectionName.c_str(), "dpad_up", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_UP], 0);
|
||||
file.Get(SectionName.c_str(), "dpad_down", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_DOWN], 0);
|
||||
file.Get(SectionName.c_str(), "dpad_left", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_LEFT], 0);
|
||||
file.Get(SectionName.c_str(), "dpad_right", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_RIGHT], 0);
|
||||
file.Get(SectionName.c_str(), "main_x", &PadMapping[i].axis[InputCommon::CTL_MAIN_X], 0);
|
||||
file.Get(SectionName.c_str(), "main_y", &PadMapping[i].axis[InputCommon::CTL_MAIN_Y], 1);
|
||||
file.Get(SectionName.c_str(), "sub_x", &PadMapping[i].axis[InputCommon::CTL_SUB_X], 2);
|
||||
file.Get(SectionName.c_str(), "sub_y", &PadMapping[i].axis[InputCommon::CTL_SUB_Y], 3);
|
||||
|
||||
file.Get(SectionName.c_str(), "deadzone", &PadMapping[i].deadzone, 9);
|
||||
file.Get(SectionName.c_str(), "halfpress", &PadMapping[i].halfpress, -1);
|
||||
file.Get(SectionName.c_str(), "controllertype", &PadMapping[i].controllertype, 0);
|
||||
file.Get(SectionName.c_str(), "TriggerType", &PadMapping[i].triggertype, 0);
|
||||
file.Get(SectionName.c_str(), "eventnum", &PadMapping[i].eventnum, 0);
|
||||
file.Get(SectionName.c_str(), "use_rumble", &PadMapping[i].rumble, false);
|
||||
|
||||
file.Get(SectionName.c_str(), "Radius", &PadMapping[i].SRadius, "100%");
|
||||
file.Get(SectionName.c_str(), "RadiusOnOff", &Tmp, false); PadMapping[i].bRadiusOnOff = Tmp;
|
||||
file.Get(SectionName.c_str(), "Diagonal", &PadMapping[i].SDiagonal, "100%");
|
||||
file.Get(SectionName.c_str(), "SquareToCircle", &Tmp, false); PadMapping[i].bSquareToCircle = Tmp;
|
||||
file.Get(SectionName.c_str(), "RadiusC", &PadMapping[i].SRadiusC, "100%");
|
||||
file.Get(SectionName.c_str(), "RadiusOnOffC", &Tmp, false); PadMapping[i].bRadiusOnOffC = Tmp;
|
||||
file.Get(SectionName.c_str(), "DiagonalC", &PadMapping[i].SDiagonalC, "100%");
|
||||
file.Get(SectionName.c_str(), "SquareToCircleC", &Tmp, false); PadMapping[i].bSquareToCircleC = Tmp;
|
||||
}
|
||||
|
||||
INFO_LOG(CONSOLE, "%i: Load: %i\n", 0, PadMapping[0].halfpress);
|
||||
}
|
||||
|
||||
42
Source/Plugins/Plugin_nJoy_SDL/Src/Config.h
Normal file
42
Source/Plugins/Plugin_nJoy_SDL/Src/Config.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
// 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/
|
||||
|
||||
#ifndef _PLUGIN_NJOY_SDL_CONFIG_H
|
||||
#define _PLUGIN_NJOY_SDL_CONFIG_H
|
||||
|
||||
struct Config
|
||||
{
|
||||
Config();
|
||||
void Load(bool ChangePad = false, bool ChangeSaveByID = false);
|
||||
void Save(int Slot = -1);
|
||||
int CheckForDuplicateJoypads(bool OK);
|
||||
|
||||
// General
|
||||
bool bShowAdvanced; // Only allow one of these
|
||||
bool bSaveByID;
|
||||
bool bCheckFocus;
|
||||
bool bNoTriggerFilter;
|
||||
int RumbleStrength;
|
||||
#ifdef RERECORDING
|
||||
bool bRecording;
|
||||
bool bPlayback;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern Config g_Config;
|
||||
|
||||
#endif // _PLUGIN_NJOY_SDL_CONFIG_H
|
||||
91
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/AboutBox.cpp
Normal file
91
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/AboutBox.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
|
||||
// Project description
|
||||
// -------------------
|
||||
// Name: nJoy
|
||||
// Description: A Dolphin Compatible Input Plugin
|
||||
//
|
||||
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
||||
// Site: www.multigesture.net
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
//
|
||||
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
|
||||
|
||||
#include "AboutBox.h"
|
||||
#include "../nJoy.h"
|
||||
#include "Images/njoy.xpm"
|
||||
|
||||
BEGIN_EVENT_TABLE(AboutBox,wxDialog)
|
||||
EVT_CLOSE(AboutBox::OnClose)
|
||||
EVT_BUTTON(ID_OK, AboutBox::OKClick)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
AboutBox::AboutBox(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style)
|
||||
: wxDialog(parent, id, title, position, size, style)
|
||||
{
|
||||
CreateGUIControls();
|
||||
}
|
||||
|
||||
AboutBox::~AboutBox()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
void AboutBox::CreateGUIControls()
|
||||
{
|
||||
SetTitle(wxT("About: nJoy Input Plugin"));
|
||||
SetIcon(wxNullIcon);
|
||||
//SetSize(8,8,200,399);
|
||||
SetClientSize(200,376);
|
||||
Center();
|
||||
|
||||
#ifndef _WIN32
|
||||
// Force a 8pt font so that it looks more or less "correct" regardless of the default font setting
|
||||
wxFont f(8,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL);
|
||||
SetFont(f);
|
||||
#endif
|
||||
|
||||
m_thankyoutext = new wxStaticText(this, ID_THANKYOU, THANKYOU, wxPoint(18,196), wxDefaultSize, 0, wxEmptyString);
|
||||
m_thankyoutext->Wrap(167);
|
||||
m_specialthanks = new wxStaticText(this, ID_SPECIALTHANKS, wxT("F|RES and ector."), wxPoint(18,153), wxDefaultSize, 0, wxEmptyString);
|
||||
m_pluginversion = new wxStaticText(this, ID_PLUGINVERSION, PLUGIN_VER_STR, wxPoint(18,80), wxDefaultSize, 0, wxEmptyString);
|
||||
m_OK = new wxButton(this, ID_OK, wxT("OK"), wxPoint(116,343), wxSize(75,25), 0, wxDefaultValidator, wxEmptyString);
|
||||
m_version = new wxStaticText(this, ID_STATUSV, wxT("PUBLIC RELEASE"), wxPoint(14,349), wxDefaultSize, 0, wxEmptyString);
|
||||
m_thankyougroup = new wxStaticBox(this, IDG_THANKYOU, wxT("Greetings to:"), wxPoint(10,180), wxSize(180,160));
|
||||
m_specialthanksgroup = new wxStaticBox(this, IDG_SPECIALTHANKS, wxT("Special thanks to:"), wxPoint(10,135), wxSize(180,39));
|
||||
m_pluginversiongroup = new wxStaticBox(this, IDG_PLUGINVERSION, wxT("Plugin info:"), wxPoint(10,61), wxSize(180,68));
|
||||
|
||||
wxBitmap WxStaticBitmap1_BITMAP(AboutBox_WxStaticBitmap1_XPM);
|
||||
m_njoylogo = new wxStaticBitmap(this, ID_AWESOMEPICTURE, WxStaticBitmap1_BITMAP, wxPoint(-1,-2), wxSize(200,60));
|
||||
}
|
||||
|
||||
void AboutBox::OnClose(wxCloseEvent& /*event*/)
|
||||
{
|
||||
EndModal(0);
|
||||
}
|
||||
|
||||
void AboutBox::OKClick(wxCommandEvent& event)
|
||||
{
|
||||
if (event.GetId() == ID_OK)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
91
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/AboutBox.h
Normal file
91
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/AboutBox.h
Normal file
@@ -0,0 +1,91 @@
|
||||
|
||||
// Project description
|
||||
// -------------------
|
||||
// Name: nJoy
|
||||
// Description: A Dolphin Compatible Input Plugin
|
||||
//
|
||||
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
||||
// Site: www.multigesture.net
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
//
|
||||
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
|
||||
|
||||
#ifndef __ABOUTBOX_h__
|
||||
#define __ABOUTBOX_h__
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
#include <wx/dialog.h>
|
||||
#else
|
||||
#include <wx/wxprec.h>
|
||||
#endif
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/statbmp.h>
|
||||
|
||||
|
||||
class AboutBox : public wxDialog
|
||||
{
|
||||
private:
|
||||
DECLARE_EVENT_TABLE();
|
||||
|
||||
public:
|
||||
AboutBox(wxWindow *parent, wxWindowID id = 1, const wxString &title = wxT("About: nJoy Input Plugin"),
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE);
|
||||
virtual ~AboutBox();
|
||||
void OKClick(wxCommandEvent& event);
|
||||
|
||||
private:
|
||||
wxStaticText *m_thankyoutext;
|
||||
wxStaticText *m_specialthanks;
|
||||
wxStaticText *m_pluginversion;
|
||||
wxButton *m_OK;
|
||||
wxStaticText *m_version;
|
||||
wxStaticBox *m_thankyougroup;
|
||||
wxStaticBox *m_specialthanksgroup;
|
||||
wxStaticBox *m_pluginversiongroup;
|
||||
wxStaticBitmap *m_njoylogo;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
ID_THANKYOU = 1009,
|
||||
ID_SPECIALTHANKS = 1008,
|
||||
ID_PLUGINVERSION = 1007,
|
||||
ID_OK = 1006,
|
||||
ID_STATUSV = 1005,
|
||||
IDG_THANKYOU = 1004,
|
||||
IDG_SPECIALTHANKS = 1003,
|
||||
IDG_PLUGINVERSION = 1002,
|
||||
ID_AWESOMEPICTURE = 1001,
|
||||
|
||||
ID_DUMMY_VALUE_ //don't remove this value unless you have other enum values
|
||||
};
|
||||
|
||||
private:
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void CreateGUIControls();
|
||||
};
|
||||
|
||||
#endif
|
||||
373
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp
Normal file
373
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp
Normal file
@@ -0,0 +1,373 @@
|
||||
|
||||
// Project description
|
||||
// -------------------
|
||||
// Name: nJoy
|
||||
// Description: A Dolphin Compatible Input Plugin
|
||||
//
|
||||
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
||||
// Site: www.multigesture.net
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
//
|
||||
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
|
||||
// Include
|
||||
// ---------
|
||||
#include "ConfigBox.h"
|
||||
#include "../nJoy.h"
|
||||
#include "Images/controller.xpm"
|
||||
|
||||
extern bool g_EmulatorRunning;
|
||||
|
||||
// Set PAD status
|
||||
// --------------
|
||||
void PADConfigDialognJoy::PadGetStatus()
|
||||
{
|
||||
// Return if it's not detected. The ID should never be less than zero here, it can only be that
|
||||
// because of a manual ini file change, but we make that check anway.
|
||||
if(PadMapping[notebookpage].ID < 0 || PadMapping[notebookpage].ID >= SDL_NumJoysticks())
|
||||
{
|
||||
m_TStatusIn[notebookpage]->SetLabel(wxT("Not connected")); m_TStatusOut[notebookpage]->SetLabel(wxT("Not connected"));
|
||||
m_TStatusInC[notebookpage]->SetLabel(wxT("Not connected")); m_TStatusOutC[notebookpage]->SetLabel(wxT("Not connected"));
|
||||
m_TStatusTriggers[notebookpage]->SetLabel(wxT("Not connected"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get physical device status
|
||||
int PhysicalDevice = PadMapping[notebookpage].ID;
|
||||
int TriggerType = PadMapping[notebookpage].triggertype;
|
||||
|
||||
// Get original values
|
||||
int main_x = PadState[notebookpage].axis[InputCommon::CTL_MAIN_X];
|
||||
int main_y = PadState[notebookpage].axis[InputCommon::CTL_MAIN_Y];
|
||||
int sub_x = PadState[notebookpage].axis[InputCommon::CTL_SUB_X];
|
||||
int sub_y = PadState[notebookpage].axis[InputCommon::CTL_SUB_Y];
|
||||
|
||||
// Get adjusted values
|
||||
int main_x_after = main_x, main_y_after = main_y;
|
||||
if(PadMapping[notebookpage].bSquareToCircle) InputCommon::Square2Circle(main_x_after, main_y_after, notebookpage, PadMapping[notebookpage].SDiagonal);
|
||||
// Adjust radius
|
||||
if(PadMapping[notebookpage].bRadiusOnOff) InputCommon::RadiusAdjustment(main_x_after, main_y_after, notebookpage, PadMapping[notebookpage].SRadius);
|
||||
// C-stick
|
||||
int sub_x_after = sub_x, sub_y_after = sub_y;
|
||||
if(PadMapping[notebookpage].bSquareToCircleC) InputCommon::Square2Circle(sub_x_after, sub_y_after, notebookpage, PadMapping[notebookpage].SDiagonalC);
|
||||
if(PadMapping[notebookpage].bRadiusOnOffC) InputCommon::RadiusAdjustment(sub_x_after, sub_y_after, notebookpage, PadMapping[notebookpage].SRadiusC);
|
||||
|
||||
// Convert values
|
||||
float f_x = main_x / 32767.0;
|
||||
float f_y = main_y / 32767.0;
|
||||
float f_x_aft = main_x_after / 32767.0;
|
||||
float f_y_aft = main_y_after / 32767.0;
|
||||
// C-stick
|
||||
float f_x_c = sub_x / 32767.0;
|
||||
float f_y_c = sub_y / 32767.0;
|
||||
float f_x_aft_c = sub_x_after / 32767.0;
|
||||
float f_y_aft_c = sub_y_after / 32767.0;
|
||||
// Print values
|
||||
m_TStatusIn[notebookpage]->SetLabel(wxString::Format(wxT("x:%1.2f y:%1.2f"), f_x, f_y));
|
||||
m_TStatusOut[notebookpage]->SetLabel(wxString::Format(wxT("x:%1.2f y:%1.2f"), f_x_aft, f_y_aft));
|
||||
m_TStatusInC[notebookpage]->SetLabel(wxString::Format(wxT("x:%1.2f y:%1.2f"), f_x_c, f_y_c));
|
||||
m_TStatusOutC[notebookpage]->SetLabel(wxString::Format(wxT("x:%1.2f y:%1.2f"), f_x_aft_c, f_y_aft_c));
|
||||
|
||||
// Adjust the values for the plot
|
||||
// Border adjustment
|
||||
int BoxW_ = BoxW - 2; int BoxH_ = BoxH - 2;
|
||||
main_x = (BoxW_ / 2) + (main_x * BoxW_ / (32767 * 2));
|
||||
main_y = (BoxH_ / 2) + (main_y * BoxH_ / (32767 * 2));
|
||||
int main_x_out = (BoxW_ / 2) + (main_x_after * BoxW_ / (32767 * 2));
|
||||
int main_y_out = (BoxH_ / 2) + (main_y_after * BoxH_ / (32767 * 2));
|
||||
// Adjust the dot
|
||||
m_bmpDot[notebookpage]->SetPosition(wxPoint(main_x, main_y));
|
||||
m_bmpDotOut[notebookpage]->SetPosition(wxPoint(main_x_out, main_y_out));
|
||||
// C-stick
|
||||
sub_x = (BoxW_ / 2) + (sub_x * BoxW_ / (32767 * 2));
|
||||
sub_y = (BoxH_ / 2) + (sub_y * BoxH_ / (32767 * 2));
|
||||
int sub_x_out = (BoxW_ / 2) + (sub_x_after * BoxW_ / (32767 * 2));
|
||||
int sub_y_out = (BoxH_ / 2) + (sub_y_after * BoxH_ / (32767 * 2));
|
||||
m_bmpDotC[notebookpage]->SetPosition(wxPoint(sub_x, sub_y));
|
||||
m_bmpDotOutC[notebookpage]->SetPosition(wxPoint(sub_x_out, sub_y_out));
|
||||
///////////////////// Analog stick
|
||||
|
||||
|
||||
|
||||
// Triggers
|
||||
// -----------------
|
||||
int TriggerValue = 255;
|
||||
if (PadState[notebookpage].halfpress) TriggerValue = 100;
|
||||
|
||||
// Get the selected keys
|
||||
long Left, Right;
|
||||
m_JoyShoulderL[notebookpage]->GetValue().ToLong(&Left);
|
||||
m_JoyShoulderR[notebookpage]->GetValue().ToLong(&Right);
|
||||
|
||||
// Get the trigger values
|
||||
int TriggerLeft = PadState[notebookpage].axis[InputCommon::CTL_L_SHOULDER];
|
||||
int TriggerRight = PadState[notebookpage].axis[InputCommon::CTL_R_SHOULDER];
|
||||
|
||||
// Convert the triggers values
|
||||
if (PadMapping[notebookpage].triggertype == InputCommon::CTL_TRIGGER_SDL)
|
||||
{
|
||||
TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
|
||||
TriggerRight = InputCommon::Pad_Convert(TriggerRight);
|
||||
}
|
||||
|
||||
// If we don't have any axis selected for the shoulder buttons
|
||||
if(Left < 1000) TriggerLeft = 0;
|
||||
if(Right < 1000) TriggerRight = 0;
|
||||
|
||||
// Get the digital values
|
||||
if(Left < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_L_SHOULDER]) TriggerLeft = TriggerValue;
|
||||
if(Right < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_R_SHOULDER]) TriggerRight = TriggerValue;
|
||||
|
||||
m_TStatusTriggers[notebookpage]->SetLabel(wxString::Format(
|
||||
wxT("Left:%03i Right:%03i"),
|
||||
TriggerLeft, TriggerRight
|
||||
));
|
||||
///////////////////// Triggers
|
||||
}
|
||||
|
||||
// Show the current pad status
|
||||
// -----------------
|
||||
std::string ShowStatus(int VirtualController)
|
||||
{
|
||||
// Save the physical device
|
||||
int PhysicalDevice = PadMapping[VirtualController].ID;
|
||||
|
||||
// Make local shortcut
|
||||
SDL_Joystick *joy = PadState[VirtualController].joy;
|
||||
|
||||
// Make shortcuts for all pads
|
||||
SDL_Joystick *joy0 = PadState[0].joy;
|
||||
SDL_Joystick *joy1 = PadState[1].joy;
|
||||
SDL_Joystick *joy2 = PadState[2].joy;
|
||||
SDL_Joystick *joy3 = PadState[3].joy;
|
||||
|
||||
// Temporary storage
|
||||
std::string StrAxes, StrHats, StrBut;
|
||||
int value;
|
||||
|
||||
// Get status
|
||||
int Axes = joyinfo[PhysicalDevice].NumAxes;
|
||||
int Balls = joyinfo[PhysicalDevice].NumBalls;
|
||||
int Hats = joyinfo[PhysicalDevice].NumHats;
|
||||
int Buttons = joyinfo[PhysicalDevice].NumButtons;
|
||||
|
||||
// Update the internal values
|
||||
SDL_JoystickUpdate();
|
||||
|
||||
// Go through all axes and read out their values
|
||||
for(int i = 0; i < Axes; i++)
|
||||
{
|
||||
value = SDL_JoystickGetAxis(joy, i);
|
||||
StrAxes += StringFromFormat(" %i:%06i", i, value);
|
||||
}
|
||||
for(int i = 0;i < Hats; i++)
|
||||
{
|
||||
value = SDL_JoystickGetHat(joy, i);
|
||||
StrHats += StringFromFormat(" %i:%i", i, value);
|
||||
}
|
||||
for(int i = 0;i < Buttons; i++)
|
||||
{
|
||||
value = SDL_JoystickGetButton(joy, i);
|
||||
StrBut += StringFromFormat(" %i:%i", i+1, value);
|
||||
}
|
||||
|
||||
return StringFromFormat(
|
||||
"All pads:\n"
|
||||
"ID: %i %i %i %i\n"
|
||||
"Controllertype: %i %i %i %i\n"
|
||||
"SquareToCircle: %i %i %i %i\n\n"
|
||||
#ifdef _WIN32
|
||||
"Handles: %i %i %i %i\n"
|
||||
"XInput: %i %i %i\n"
|
||||
#endif
|
||||
|
||||
"This pad:\n"
|
||||
"Axes: %s\n"
|
||||
"Hats: %s\n"
|
||||
"But: %s\n"
|
||||
"Device: Ax: %i Balls:%i Hats:%i But:%i",
|
||||
PadMapping[0].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID,
|
||||
PadMapping[0].controllertype, PadMapping[1].controllertype, PadMapping[2].controllertype, PadMapping[3].controllertype,
|
||||
PadMapping[0].bSquareToCircle, PadMapping[1].bSquareToCircle, PadMapping[2].bSquareToCircle, PadMapping[3].bSquareToCircle,
|
||||
#ifdef _WIN32
|
||||
joy0, joy1, joy2, joy3,
|
||||
//PadState[PadMapping[0].ID].joy, PadState[PadMapping[1].ID].joy, PadState[PadMapping[2].ID].joy, PadState[PadMapping[3].ID].joy,
|
||||
XInput::IsConnected(0), XInput::GetXI(0, InputCommon::XI_TRIGGER_L), XInput::GetXI(0, InputCommon::XI_TRIGGER_R),
|
||||
#endif
|
||||
StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(),
|
||||
Axes, Balls, Hats, Buttons
|
||||
);
|
||||
}
|
||||
|
||||
// Populate the advanced tab
|
||||
// -----------------
|
||||
void PADConfigDialognJoy::Update()
|
||||
{
|
||||
// Check that Dolphin is in focus, otherwise don't update the pad status
|
||||
/* If the emulator is running and unpaused GetJoyState() is run a little more often than needed,
|
||||
but I allow that since it can confuse the user if the input status in the configuration window
|
||||
is not update when the emulator is paused. */
|
||||
if (g_Config.bCheckFocus || IsFocus()) // && !g_EmulatorRunning)
|
||||
{
|
||||
for (int i = 0; (u32)i < joyinfo.size(); i++)
|
||||
InputCommon::GetJoyState(PadState[i], PadMapping[i], i, joyinfo[PadMapping[i].ID].NumButtons);
|
||||
}
|
||||
|
||||
// Show the current status in a window in the wxPanel
|
||||
#ifdef SHOW_PAD_STATUS
|
||||
m_pStatusBar->SetLabel(wxString::Format(
|
||||
"%s", ShowStatus(notebookpage).c_str()
|
||||
));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Populate the advanced tab
|
||||
// -----------------
|
||||
void PADConfigDialognJoy::CreateAdvancedControls(int i)
|
||||
{
|
||||
// Main-stick
|
||||
m_TStatusIn[i] = new wxStaticText(m_Controller[i], IDT_STATUS_IN, wxT("In"));
|
||||
m_TStatusOut[i] = new wxStaticText(m_Controller[i], IDT_STATUS_OUT, wxT("Out"));
|
||||
m_gStatusIn[i] = new wxStaticBoxSizer( wxHORIZONTAL, m_Controller[i], wxT("Main-stick (In) (Out)"));
|
||||
// C-stick
|
||||
m_TStatusInC[i] = new wxStaticText(m_Controller[i], IDT_STATUS_IN, wxT("In"));
|
||||
m_TStatusOutC[i] = new wxStaticText(m_Controller[i], IDT_STATUS_OUT, wxT("Out"));
|
||||
m_gStatusInC[i] = new wxStaticBoxSizer( wxHORIZONTAL, m_Controller[i], wxT("C-stick (In) (Out)"));
|
||||
|
||||
// Main-stick In-Out
|
||||
m_pInStatus[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize);
|
||||
m_bmpSquare[i] = new wxStaticBitmap(m_pInStatus[i], ID_STATUSBMP1 + i, CreateBitmap(),
|
||||
//wxPoint(4, 15), wxSize(70,70));
|
||||
//wxPoint(4, 20), wxDefaultSize);
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
m_bmpDot[i] = new wxStaticBitmap(m_pInStatus[i], ID_STATUSDOTBMP1 + i, CreateBitmapDot(),
|
||||
wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize);
|
||||
|
||||
m_pOutStatus[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize);
|
||||
m_bmpSquareOut[i] = new wxStaticBitmap(m_pOutStatus[i], ID_STATUSBMP1 + i, CreateBitmap(),
|
||||
//wxPoint(4, 15), wxSize(70,70));
|
||||
//wxPoint(4, 20), wxDefaultSize);
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
// Yes the diagonals for the original GC controller are this narrow (i.e. around 80% of the full radius),
|
||||
// it's not a perfect octagon. Some third party GC controllers has a diagonal at 90% however,
|
||||
// i.e. at around 63,63 rather than 55,55.
|
||||
m_bmpAreaOut[i] = new wxStaticBitmap(m_pOutStatus[i], wxID_ANY, CreateBitmapArea(100,55),
|
||||
wxPoint(1, 1), wxDefaultSize);
|
||||
m_bmpDotOut[i] = new wxStaticBitmap(m_pOutStatus[i], ID_STATUSDOTBMP1 + i, CreateBitmapDot(),
|
||||
wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize);
|
||||
|
||||
// C-stick In-Out
|
||||
m_pInStatusC[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize);
|
||||
m_bmpSquareC[i] = new wxStaticBitmap(m_pInStatusC[i], wxID_ANY, CreateBitmap(),
|
||||
//wxPoint(4, 15), wxSize(70,70));
|
||||
//wxPoint(4, 20), wxDefaultSize);
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
m_bmpDotC[i] = new wxStaticBitmap(m_pInStatusC[i], wxID_ANY, CreateBitmapDot(),
|
||||
wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize);
|
||||
|
||||
m_pOutStatusC[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize);
|
||||
m_bmpSquareOutC[i] = new wxStaticBitmap(m_pOutStatusC[i], wxID_ANY, CreateBitmap(),
|
||||
//wxPoint(4, 15), wxSize(70,70));
|
||||
//wxPoint(4, 20), wxDefaultSize);
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
m_bmpAreaOutC[i] = new wxStaticBitmap(m_pOutStatusC[i], wxID_ANY, CreateBitmapArea(85,46),
|
||||
wxPoint(1, 1), wxDefaultSize);
|
||||
m_bmpDotOutC[i] = new wxStaticBitmap(m_pOutStatusC[i], wxID_ANY, CreateBitmapDot(),
|
||||
wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize);
|
||||
}
|
||||
|
||||
|
||||
wxBitmap PADConfigDialognJoy::CreateBitmap() // Create box
|
||||
{
|
||||
BoxW = 70, BoxH = 70;
|
||||
wxBitmap bitmap(BoxW, BoxH);
|
||||
wxMemoryDC dc;
|
||||
dc.SelectObject(bitmap);
|
||||
|
||||
// Set outline and fill colors
|
||||
//wxBrush LightBlueBrush(_T("#0383f0"));
|
||||
//wxPen LightBluePen(_T("#80c5fd"));
|
||||
//wxPen LightGrayPen(_T("#909090"));
|
||||
wxPen LightBluePen(_T("#7f9db9")); // Windows XP color
|
||||
dc.SetPen(LightBluePen);
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
|
||||
dc.Clear();
|
||||
dc.DrawRectangle(0, 0, BoxW, BoxH);
|
||||
dc.SelectObject(wxNullBitmap);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
// Create dot
|
||||
wxBitmap PADConfigDialognJoy::CreateBitmapDot()
|
||||
{
|
||||
int w = 2, h = 2;
|
||||
wxBitmap bitmap(w, h);
|
||||
wxMemoryDC dc;
|
||||
dc.SelectObject(bitmap);
|
||||
|
||||
// Set outline and fill colors
|
||||
//wxBrush RedBrush(_T("#0383f0"));
|
||||
//wxPen RedPen(_T("#80c5fd"));
|
||||
//wxPen LightGrayPen(_T("#909090"));
|
||||
dc.SetPen(*wxRED_PEN);
|
||||
dc.SetBrush(*wxRED_BRUSH);
|
||||
|
||||
dc.Clear();
|
||||
dc.DrawRectangle(0, 0, w, h);
|
||||
dc.SelectObject(wxNullBitmap);
|
||||
return bitmap;
|
||||
}
|
||||
wxBitmap PADConfigDialognJoy::CreateBitmapArea(int Max, int Diagonal)
|
||||
{
|
||||
wxBitmap bitmap(BoxW - 2, BoxH - 2);
|
||||
wxMemoryDC dc;
|
||||
dc.SelectObject(bitmap);
|
||||
|
||||
// Set outline and fill colors
|
||||
// wxMEDIUM_GREY_PEN, wxLIGHT_GREY_BRUSH
|
||||
wxBrush LightGrayBrush(_T("#dddddd"));
|
||||
wxPen LightGrayPen(_T("#bfbfbf"));
|
||||
dc.SetBrush(LightGrayBrush);
|
||||
dc.SetPen(LightGrayPen);
|
||||
|
||||
// Clear bitmap
|
||||
dc.Clear();
|
||||
|
||||
// Create offset for polygon
|
||||
float Adj = (float)(BoxW-2) / 256.0;
|
||||
float iAdj = 127.0 * Adj;
|
||||
// The polygon corners
|
||||
wxPoint Points[8];
|
||||
Points[0].x = (int)(0.0 * Adj + iAdj); Points[0].y = (int)(Max * Adj + iAdj);
|
||||
Points[1].x = (int)(Diagonal * Adj + iAdj); Points[1].y = (int)(Diagonal * Adj + iAdj);
|
||||
Points[2].x = (int)(Max * Adj + iAdj); Points[2].y = (int)(0.0 * Adj + iAdj);
|
||||
Points[3].x = (int)(Diagonal * Adj + iAdj); Points[3].y = (int)(-Diagonal * Adj + iAdj);
|
||||
Points[4].x = (int)(0.0 * Adj + iAdj); Points[4].y = (int)(-Max * Adj + iAdj);
|
||||
Points[5].x = (int)(-Diagonal * Adj + iAdj); Points[5].y = (int)(-Diagonal * Adj + iAdj);
|
||||
Points[6].x = (int)(-Max * Adj + iAdj); Points[6].y = (int)(0.0 * Adj + iAdj);
|
||||
Points[7].x = (int)(-Diagonal * Adj + iAdj); Points[7].y = (int)(Diagonal * Adj + iAdj);
|
||||
// Draw polygon
|
||||
dc.DrawPolygon(8, Points);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
1013
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp
Normal file
1013
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp
Normal file
File diff suppressed because it is too large
Load Diff
358
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h
Normal file
358
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h
Normal file
@@ -0,0 +1,358 @@
|
||||
|
||||
// Project description
|
||||
// -------------------
|
||||
// Name: nJoy
|
||||
// Description: A Dolphin Compatible Input Plugin
|
||||
//
|
||||
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
||||
// Site: www.multigesture.net
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
//
|
||||
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
|
||||
|
||||
|
||||
#ifndef __CONFIGBOX_h__
|
||||
#define __CONFIGBOX_h__
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
#include <wx/dialog.h>
|
||||
#else
|
||||
#include <wx/wxprec.h>
|
||||
#endif
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/statbmp.h>
|
||||
#include <wx/gbsizer.h>
|
||||
|
||||
#include "../nJoy.h"
|
||||
|
||||
class PADConfigDialognJoy : public wxDialog
|
||||
{
|
||||
private:
|
||||
DECLARE_EVENT_TABLE();
|
||||
|
||||
public:
|
||||
PADConfigDialognJoy(wxWindow *parent, wxWindowID id = 1,
|
||||
const wxString &title = wxT("Configure: nJoy Input Plugin"),
|
||||
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
|
||||
long style = wxDEFAULT_DIALOG_STYLE);
|
||||
virtual ~PADConfigDialognJoy();
|
||||
|
||||
#if wxUSE_TIMER
|
||||
void OnTimer(wxTimerEvent& WXUNUSED(event)) { Update(); }
|
||||
void OnButtonTimer(wxTimerEvent& WXUNUSED(event)) { DoGetButtons(GetButtonWaitingID); }
|
||||
wxTimer *m_ConstantTimer, *m_ButtonMappingTimer;
|
||||
#endif
|
||||
|
||||
// Debugging
|
||||
wxStaticText* m_pStatusBar, * m_pStatusBar2;
|
||||
wxTextCtrl* m_TCDebugging;
|
||||
bool Debugging;
|
||||
void LogMsg(const char* format, ...);
|
||||
|
||||
// Status window
|
||||
int BoxW, BoxH;
|
||||
|
||||
// Configure buttons
|
||||
int GetButtonWaitingID, GetButtonWaitingTimer;
|
||||
|
||||
private:
|
||||
wxButton *m_About;
|
||||
wxButton *m_OK;
|
||||
wxButton *m_Cancel;
|
||||
|
||||
wxPanel *m_Controller[4]; // Main containers
|
||||
wxNotebook *m_Notebook;
|
||||
wxBoxSizer * m_MainSizer;
|
||||
|
||||
wxPanel *m_pKeys[4], *m_pInStatus[4], *m_pOutStatus[4], *m_pInStatusC[4], *m_pOutStatusC[4];
|
||||
wxBitmap WxStaticBitmap1_BITMAP;
|
||||
wxStaticBoxSizer * m_sKeys[4];
|
||||
wxBoxSizer *m_sMain[4], *m_sMainLeft[4], *m_sMainRight[4];
|
||||
|
||||
|
||||
// Settings
|
||||
// ---------
|
||||
|
||||
wxComboBox *m_Joyname[4];
|
||||
wxCheckBox *m_Enable[4];
|
||||
wxComboBox *m_ControlType[4], *m_TriggerType[4];
|
||||
wxComboBox *m_Deadzone[4];
|
||||
|
||||
wxStaticBoxSizer *m_gJoyname[4];
|
||||
|
||||
wxStaticBoxSizer *m_gExtrasettings[4]; // Extra settings
|
||||
wxGridBagSizer * m_gGBExtrasettings[4];
|
||||
|
||||
wxBoxSizer* m_sSettings[4]; // General settings 2
|
||||
wxStaticBoxSizer *m_gGenSettings[4];
|
||||
|
||||
wxStaticBoxSizer *m_gGenSettingsID[4];
|
||||
wxGridBagSizer *m_gGBGenSettings[4];
|
||||
wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4];
|
||||
wxStaticText *m_TSControltype[4], *m_TSTriggerType[4];
|
||||
|
||||
wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4], *m_gStatusInC[4], *m_gStatusInSettingsC[4], *m_gStatusAdvancedSettings[4]; // Advanced settings
|
||||
wxBoxSizer *m_gStatusInSettingsH[4], *m_gStatusInSettingsRadiusH[4], *m_gStatusInSettingsHC[4], *m_gStatusInSettingsRadiusHC[4];
|
||||
wxGridBagSizer *m_GBAdvancedMainStick[4], *m_GBAdvancedCStick[4];
|
||||
wxStaticText *m_TStatusIn[4], *m_TStatusOut[4], *m_TStatusInC[4], *m_TStatusOutC[4];
|
||||
wxComboBox *m_CoBRadius[4], *m_CoBRadiusC[4]; wxCheckBox *m_CBRadius[4], *m_CBRadiusC[4];
|
||||
wxComboBox *m_CoBDiagonal[4], *m_CoBDiagonalC[4]; wxCheckBox *m_CBS_to_C[4], *m_CBS_to_CC[4];
|
||||
wxCheckBox *m_CBCheckFocus[4], *m_AdvancedMapFilter[4];
|
||||
|
||||
wxCheckBox *m_Rumble[4]; // Rumble settings
|
||||
wxComboBox *m_RStrength[4];
|
||||
wxStaticBoxSizer *m_gRumble[4];
|
||||
wxGridBagSizer *m_gGBRumble[4];
|
||||
|
||||
wxStaticBoxSizer *m_gStatusTriggers[4]; // Triggers
|
||||
wxStaticText *m_TStatusTriggers[4];
|
||||
|
||||
|
||||
// Keys
|
||||
// ---------
|
||||
int g_Pressed; // Keyboard input
|
||||
|
||||
wxTextCtrl *m_JoyShoulderL[4];
|
||||
wxTextCtrl *m_JoyShoulderR[4];
|
||||
|
||||
wxButton *m_bJoyShoulderL[4];
|
||||
wxButton *m_bJoyShoulderR[4];
|
||||
|
||||
wxTextCtrl *m_JoyButtonA[4];
|
||||
wxTextCtrl *m_JoyButtonB[4];
|
||||
wxTextCtrl *m_JoyButtonX[4];
|
||||
wxTextCtrl *m_JoyButtonY[4];
|
||||
wxTextCtrl *m_JoyButtonZ[4];
|
||||
wxTextCtrl *m_JoyButtonStart[4];
|
||||
wxTextCtrl *m_JoyButtonHalfpress[4];
|
||||
|
||||
wxButton *m_bJoyButtonA[4];
|
||||
wxButton *m_bJoyButtonB[4];
|
||||
wxButton *m_bJoyButtonX[4];
|
||||
wxButton *m_bJoyButtonY[4];
|
||||
wxButton *m_bJoyButtonZ[4];
|
||||
wxButton *m_bJoyButtonStart[4];
|
||||
wxButton *m_bJoyButtonHalfpress[4];
|
||||
|
||||
wxTextCtrl *m_JoyAnalogMainX[4];
|
||||
wxTextCtrl *m_JoyAnalogMainY[4];
|
||||
wxTextCtrl *m_JoyAnalogSubX[4];
|
||||
wxTextCtrl *m_JoyAnalogSubY[4];
|
||||
|
||||
wxButton *m_bJoyAnalogMainX[4];
|
||||
wxButton *m_bJoyAnalogMainY[4];
|
||||
wxButton *m_bJoyAnalogSubX[4];
|
||||
wxButton *m_bJoyAnalogSubY[4];
|
||||
|
||||
wxTextCtrl *m_JoyDpadUp[4];
|
||||
wxTextCtrl *m_JoyDpadDown[4];
|
||||
wxTextCtrl *m_JoyDpadLeft[4];
|
||||
wxTextCtrl *m_JoyDpadRight[4];
|
||||
|
||||
wxButton *m_bJoyDpadUp[4];
|
||||
wxButton *m_bJoyDpadDown[4];
|
||||
wxButton *m_bJoyDpadLeft[4];
|
||||
wxButton *m_bJoyDpadRight[4];
|
||||
|
||||
wxStaticText *m_textMainX[4];
|
||||
wxStaticText *m_textMainY[4];
|
||||
wxStaticText *m_textDpadUp[4];
|
||||
wxStaticText *m_textDpadDown[4];
|
||||
wxStaticText *m_textDpadLeft[4];
|
||||
wxStaticText *m_textDpadRight[4];
|
||||
wxStaticText *m_textDeadzone[4];
|
||||
wxStaticText *m_textHalfpress[4];
|
||||
wxStaticText *m_textSubX[4];
|
||||
wxStaticText *m_textSubY[4];
|
||||
wxStaticText *m_textWebsite[4];
|
||||
|
||||
wxTextCtrl *m_PlaceholderBMP[4];
|
||||
wxStaticBitmap *m_controllerimage[4],
|
||||
*m_bmpSquare[4], *m_bmpDot[4], *m_bmpSquareOut[4], *m_bmpDotOut[4], *m_bmpAreaOut[4],
|
||||
*m_bmpSquareC[4], *m_bmpDotC[4], *m_bmpSquareOutC[4], *m_bmpDotOutC[4], *m_bmpAreaOutC[4];
|
||||
|
||||
int notebookpage; bool ControlsCreated;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
ID_ABOUT = 1000,
|
||||
ID_OK,
|
||||
ID_CANCEL,
|
||||
ID_NOTEBOOK,
|
||||
ID_CONTROLLERPAGE1,
|
||||
ID_CONTROLLERPAGE2,
|
||||
ID_CONTROLLERPAGE3,
|
||||
ID_CONTROLLERPAGE4,
|
||||
ID_CONTROLLERPICTURE, // Background picture
|
||||
|
||||
ID_KEYSPANEL1, ID_KEYSPANEL2, ID_KEYSPANEL3, ID_KEYSPANEL4,
|
||||
|
||||
IDG_JOYSTICK, IDC_JOYNAME, IDC_ENABLE,
|
||||
|
||||
IDG_EXTRASETTINGS, IDC_DEADZONE, // Extra settings
|
||||
|
||||
IDG_CONTROLLERTYPE, IDC_CONTROLTYPE, IDC_TRIGGERTYPE, // Controller type
|
||||
|
||||
IDC_SAVEBYID, IDC_SHOWADVANCED, // Settings
|
||||
|
||||
IDC_ENABLERUMBLE, IDC_RUMBLESTRENGTH, IDT_RUMBLESTRENGTH, // Rumble
|
||||
|
||||
ID_INSTATUS1, ID_INSTATUS2, ID_INSTATUS3, ID_INSTATUS4, // Advanced status
|
||||
ID_STATUSBMP1, ID_STATUSBMP2, ID_STATUSBMP3, ID_STATUSBMP4,
|
||||
ID_STATUSDOTBMP1, ID_STATUSDOTBMP2, ID_STATUSDOTBMP3, ID_STATUSDOTBMP4,
|
||||
IDT_STATUS_IN, IDT_STATUS_OUT,
|
||||
|
||||
// Advaced settings
|
||||
IDCB_MAINSTICK_RADIUS, IDCB_MAINSTICK_CB_RADIUS, IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL,
|
||||
IDCB_CSTICK_RADIUS, IDCB_CSTICK_CB_RADIUS, IDCB_CSTICK_DIAGONAL, IDCB_CSTICK_S_TO_C, IDT_CSTICK_DIAGONAL,
|
||||
IDT_TRIGGERS, IDCB_CHECKFOCUS, IDCB_FILTER_SETTINGS,
|
||||
|
||||
// Timers
|
||||
IDTM_CONSTANT, IDTM_BUTTON,
|
||||
|
||||
|
||||
// ==============================================
|
||||
// Keys objects
|
||||
// -----------------------------
|
||||
|
||||
// -------------------------------------
|
||||
// Text controls that hold the mapped key value
|
||||
// ----------
|
||||
ID_ANALOG_MAIN_X = 2000,
|
||||
ID_ANALOG_MAIN_Y,
|
||||
ID_ANALOG_SUB_X,
|
||||
ID_ANALOG_SUB_Y,
|
||||
ID_SHOULDER_L,
|
||||
ID_SHOULDER_R,
|
||||
|
||||
ID_DPAD_UP,
|
||||
ID_DPAD_DOWN,
|
||||
ID_DPAD_LEFT,
|
||||
ID_DPAD_RIGHT,
|
||||
|
||||
ID_BUTTON_A,
|
||||
ID_BUTTON_B,
|
||||
ID_BUTTON_X,
|
||||
ID_BUTTON_Y,
|
||||
ID_BUTTON_Z,
|
||||
ID_BUTTONSTART,
|
||||
|
||||
ID_BUTTONHALFPRESS,
|
||||
// ------------------ Keep this order
|
||||
|
||||
// -------------------------------------
|
||||
// Buttons controls (it's important that they are kept in this order)
|
||||
// --------
|
||||
IDB_ANALOG_MAIN_X = 3000,
|
||||
IDB_ANALOG_MAIN_Y,
|
||||
IDB_ANALOG_SUB_X,
|
||||
IDB_ANALOG_SUB_Y,
|
||||
IDB_SHOULDER_L,
|
||||
IDB_SHOULDER_R,
|
||||
|
||||
IDB_DPAD_UP,
|
||||
IDB_DPAD_DOWN,
|
||||
IDB_DPAD_LEFT,
|
||||
IDB_DPAD_RIGHT,
|
||||
|
||||
IDB_BUTTON_A,
|
||||
IDB_BUTTON_B,
|
||||
IDB_BUTTON_X,
|
||||
IDB_BUTTON_Y,
|
||||
IDB_BUTTON_Z,
|
||||
IDB_BUTTONSTART,
|
||||
|
||||
IDB_BUTTONHALFPRESS,
|
||||
// ------------------ Keep this order
|
||||
|
||||
// Statis text controls that hold the button label
|
||||
IDT_ANALOG_MAIN_X = 4000,
|
||||
IDT_ANALOG_MAIN_Y,
|
||||
IDT_ANALOG_SUB_X,
|
||||
IDT_ANALOG_SUB_Y,
|
||||
|
||||
IDT_DPAD_UP,
|
||||
IDT_DPAD_DOWN,
|
||||
IDT_DPAD_LEFT,
|
||||
IDT_DPAD_RIGHT,
|
||||
IDT_DEADZONE,
|
||||
IDT_BUTTONHALFPRESS,
|
||||
|
||||
IDT_DPADTYPE, IDT_TRIGGERTYPE,
|
||||
IDT_WEBSITE,
|
||||
IDT_DEBUGGING, IDT_DEBUGGING2, IDT_DEBUGGING3,
|
||||
// ============
|
||||
|
||||
ID_DUMMY_VALUE_ //don't remove this value unless you have other enum values
|
||||
};
|
||||
|
||||
private:
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void AboutClick(wxCommandEvent& event);
|
||||
void OKClick(wxCommandEvent& event);
|
||||
void CancelClick(wxCommandEvent& event);
|
||||
void DoSave(bool ChangePad = false, int Slot = -1);
|
||||
|
||||
void DoChangeJoystick();
|
||||
|
||||
void UpdateGUI(int _notebookpage);
|
||||
|
||||
void ChangeSettings(wxCommandEvent& event);
|
||||
void ComboChange(wxCommandEvent& event);
|
||||
|
||||
void CreateGUIControls();
|
||||
void CreateAdvancedControls(int i);
|
||||
wxBitmap CreateBitmap();
|
||||
wxBitmap CreateBitmapDot();
|
||||
wxBitmap CreateBitmapArea(int,int);
|
||||
void PadGetStatus();
|
||||
void Update();
|
||||
|
||||
void UpdateGUIButtonMapping(int controller);
|
||||
void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1);
|
||||
void SaveButtonMappingAll(int Slot);
|
||||
void UpdateGUIAll(int Slot);
|
||||
void ToBlank(bool ToBlank = true);
|
||||
void OnSaveById();
|
||||
|
||||
void NotebookPageChanged(wxNotebookEvent& event);
|
||||
|
||||
void GetButtons(wxCommandEvent& event); void DoGetButtons(int);
|
||||
void GetHats(int ID);
|
||||
void GetAxis(wxCommandEvent& event);
|
||||
|
||||
void OnPaint(wxPaintEvent &event);
|
||||
|
||||
void SetButtonText(int id, const char *text, int Page = -1);
|
||||
void SetButtonTextAll(int id, const char *text);
|
||||
wxString GetButtonText(int id, int Page = -1);
|
||||
void OnKeyDown(wxKeyEvent& event);
|
||||
};
|
||||
|
||||
#endif
|
||||
425
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp
Normal file
425
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp
Normal file
@@ -0,0 +1,425 @@
|
||||
|
||||
// Project description
|
||||
// -------------------
|
||||
// Name: nJoy
|
||||
// Description: A Dolphin Compatible Input Plugin
|
||||
//
|
||||
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
||||
// Site: www.multigesture.net
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
//
|
||||
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
// Include
|
||||
// ---------
|
||||
#include "math.h" // System
|
||||
|
||||
#include "ConfigBox.h" // Local
|
||||
#include "../nJoy.h"
|
||||
#include "Images/controller.xpm"
|
||||
|
||||
extern bool g_EmulatorRunning;
|
||||
|
||||
|
||||
|
||||
// Set dialog items from saved values
|
||||
// ----------------
|
||||
void PADConfigDialognJoy::UpdateGUIButtonMapping(int controller)
|
||||
{
|
||||
// http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString
|
||||
wxString tmp;
|
||||
|
||||
// Update selected gamepad
|
||||
m_Joyname[controller]->SetSelection(PadMapping[controller].ID);
|
||||
m_Enable[controller]->SetValue(PadMapping[controller].enable);
|
||||
|
||||
tmp << PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER]; m_JoyShoulderL[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER]; m_JoyShoulderR[controller]->SetValue(tmp); tmp.clear();
|
||||
|
||||
tmp << PadMapping[controller].buttons[InputCommon::CTL_A_BUTTON]; m_JoyButtonA[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON]; m_JoyButtonB[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON]; m_JoyButtonX[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON]; m_JoyButtonY[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].buttons[InputCommon::CTL_Z_TRIGGER]; m_JoyButtonZ[controller]->SetValue(tmp); tmp.clear();
|
||||
|
||||
tmp << PadMapping[controller].buttons[InputCommon::CTL_START]; m_JoyButtonStart[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].halfpress; m_JoyButtonHalfpress[controller]->SetValue(tmp); tmp.clear();
|
||||
|
||||
tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_X]; m_JoyAnalogMainX[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_Y]; m_JoyAnalogMainY[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_X]; m_JoyAnalogSubX[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_Y]; m_JoyAnalogSubY[controller]->SetValue(tmp); tmp.clear();
|
||||
|
||||
// Update the deadzone and controller type controls
|
||||
m_ControlType[controller]->SetSelection(PadMapping[controller].controllertype);
|
||||
m_TriggerType[controller]->SetSelection(PadMapping[controller].triggertype);
|
||||
m_Deadzone[controller]->SetSelection(PadMapping[controller].deadzone);
|
||||
m_CoBRadius[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SRadius.c_str()));
|
||||
m_CBRadius[controller]->SetValue(PadMapping[controller].bRadiusOnOff);
|
||||
m_CoBDiagonal[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonal.c_str()));
|
||||
m_CBS_to_C[controller]->SetValue(PadMapping[controller].bSquareToCircle);
|
||||
// C-stick
|
||||
m_CoBRadiusC[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SRadiusC.c_str()));
|
||||
m_CBRadiusC[controller]->SetValue(PadMapping[controller].bRadiusOnOffC);
|
||||
m_CoBDiagonalC[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonalC.c_str()));
|
||||
m_CBS_to_CC[controller]->SetValue(PadMapping[controller].bSquareToCircleC);
|
||||
m_AdvancedMapFilter[controller]->SetValue(g_Config.bNoTriggerFilter);
|
||||
// Update Rumble checkbox
|
||||
m_Rumble[controller]->SetValue(PadMapping[controller].rumble);
|
||||
|
||||
// Update D-Pad
|
||||
if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT)
|
||||
{
|
||||
tmp << PadMapping[controller].dpad; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP]; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_DOWN]; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT]; m_JoyDpadLeft[controller]->SetValue(tmp); tmp.clear();
|
||||
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT]; m_JoyDpadRight[controller]->SetValue(tmp); tmp.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Populate the PadMapping array with the dialog items settings (for example
|
||||
selected joystick and so on) */
|
||||
void PADConfigDialognJoy::SaveButtonMapping(int controller, bool DontChangeId, int FromSlot)
|
||||
{
|
||||
// Temporary storage
|
||||
wxString tmp;
|
||||
long value;
|
||||
|
||||
// Save from or to the same or different slots
|
||||
if (FromSlot == -1) FromSlot = controller;
|
||||
|
||||
// Replace "" with "-1" in the GUI controls
|
||||
ToBlank(false);
|
||||
|
||||
// Set other settings
|
||||
if(!DontChangeId) PadMapping[controller].ID = m_Joyname[FromSlot]->GetSelection();
|
||||
PadMapping[controller].enable = m_Enable[FromSlot]->IsChecked();
|
||||
PadMapping[controller].controllertype = m_ControlType[FromSlot]->GetSelection();
|
||||
PadMapping[controller].triggertype = m_TriggerType[FromSlot]->GetSelection();
|
||||
PadMapping[controller].deadzone = m_Deadzone[FromSlot]->GetSelection();
|
||||
PadMapping[controller].SRadius = m_CoBRadius[FromSlot]->GetLabel().mb_str();
|
||||
PadMapping[controller].bRadiusOnOff = m_CBRadius[FromSlot]->IsChecked();
|
||||
PadMapping[controller].SDiagonal = m_CoBDiagonal[FromSlot]->GetLabel().mb_str();
|
||||
PadMapping[controller].bSquareToCircle = m_CBS_to_C[FromSlot]->IsChecked();
|
||||
// C-stick
|
||||
PadMapping[controller].SRadiusC = m_CoBRadiusC[FromSlot]->GetLabel().mb_str();
|
||||
PadMapping[controller].bRadiusOnOffC = m_CBRadiusC[FromSlot]->IsChecked();
|
||||
PadMapping[controller].SDiagonalC = m_CoBDiagonalC[FromSlot]->GetLabel().mb_str();
|
||||
PadMapping[controller].bSquareToCircleC = m_CBS_to_CC[FromSlot]->IsChecked();
|
||||
|
||||
// The analog buttons
|
||||
m_JoyAnalogMainX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_X] = value; tmp.clear();
|
||||
m_JoyAnalogMainY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_Y] = value; tmp.clear();
|
||||
m_JoyAnalogSubX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_SUB_X] = value; tmp.clear();
|
||||
m_JoyAnalogSubY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_SUB_Y] = value; tmp.clear();
|
||||
|
||||
// The shoulder buttons
|
||||
m_JoyShoulderL[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER] = value;
|
||||
m_JoyShoulderR[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER] = value;
|
||||
|
||||
// The digital buttons
|
||||
m_JoyButtonA[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_A_BUTTON] = value; tmp.clear();
|
||||
m_JoyButtonB[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON] = value; tmp.clear();
|
||||
m_JoyButtonX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON] = value; tmp.clear();
|
||||
m_JoyButtonY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON] = value; tmp.clear();
|
||||
m_JoyButtonZ[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_Z_TRIGGER] = value; tmp.clear();
|
||||
m_JoyButtonStart[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_START] = value; tmp.clear();
|
||||
|
||||
// The halfpress button
|
||||
m_JoyButtonHalfpress[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].halfpress = value; tmp.clear();
|
||||
|
||||
// The digital pad
|
||||
if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT)
|
||||
{
|
||||
m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad = value; tmp.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP] = value; tmp.clear();
|
||||
m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_DOWN] = value; tmp.clear();
|
||||
m_JoyDpadLeft[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT] = value; tmp.clear();
|
||||
m_JoyDpadRight[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT] = value; tmp.clear();
|
||||
}
|
||||
|
||||
// Replace "-1" with ""
|
||||
ToBlank();
|
||||
}
|
||||
|
||||
// Update the textbox for the buttons
|
||||
// ----------------
|
||||
void PADConfigDialognJoy::SetButtonText(int id, const char *text, int Page)
|
||||
{
|
||||
// Set controller value
|
||||
int controller;
|
||||
if (Page == -1) controller = notebookpage; else controller = Page;
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case IDB_DPAD_RIGHT: m_JoyDpadRight[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_DPAD_UP: m_JoyDpadUp[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_DPAD_DOWN: m_JoyDpadDown[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_DPAD_LEFT: m_JoyDpadLeft[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
|
||||
case IDB_ANALOG_MAIN_X: m_JoyAnalogMainX[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_ANALOG_MAIN_Y: m_JoyAnalogMainY[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_ANALOG_SUB_X: m_JoyAnalogSubX[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_ANALOG_SUB_Y: m_JoyAnalogSubY[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
|
||||
case IDB_SHOULDER_L: m_JoyShoulderL[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_SHOULDER_R: m_JoyShoulderR[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
|
||||
case IDB_BUTTON_A: m_JoyButtonA[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_BUTTON_B: m_JoyButtonB[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_BUTTON_X: m_JoyButtonX[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_BUTTON_Y: m_JoyButtonY[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_BUTTON_Z: m_JoyButtonZ[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
case IDB_BUTTONSTART: m_JoyButtonStart[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
|
||||
case IDB_BUTTONHALFPRESS: m_JoyButtonHalfpress[controller]->SetValue(wxString::FromAscii(text)); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the text in the textbox for the buttons
|
||||
// ----------------
|
||||
wxString PADConfigDialognJoy::GetButtonText(int id, int Page)
|
||||
{
|
||||
// Set controller value
|
||||
int controller;
|
||||
if (Page == -1) controller = notebookpage; else controller = Page;
|
||||
|
||||
switch(id)
|
||||
{
|
||||
// D-Pad
|
||||
case IDB_DPAD_RIGHT: return m_JoyDpadRight[controller]->GetValue();
|
||||
case IDB_DPAD_UP: return m_JoyDpadUp[controller]->GetValue();
|
||||
case IDB_DPAD_DOWN: return m_JoyDpadDown[controller]->GetValue();
|
||||
case IDB_DPAD_LEFT: return m_JoyDpadLeft[controller]->GetValue();
|
||||
|
||||
// Analog Stick
|
||||
case IDB_ANALOG_MAIN_X: return m_JoyAnalogMainX[controller]->GetValue();
|
||||
case IDB_ANALOG_MAIN_Y: return m_JoyAnalogMainY[controller]->GetValue();
|
||||
case IDB_ANALOG_SUB_X: return m_JoyAnalogSubX[controller]->GetValue();
|
||||
case IDB_ANALOG_SUB_Y: return m_JoyAnalogSubY[controller]->GetValue();
|
||||
|
||||
// Shoulder Buttons
|
||||
case IDB_SHOULDER_L: return m_JoyShoulderL[controller]->GetValue();
|
||||
case IDB_SHOULDER_R: return m_JoyShoulderR[controller]->GetValue();
|
||||
|
||||
// Buttons
|
||||
case IDB_BUTTON_A: return m_JoyButtonA[controller]->GetValue();
|
||||
case IDB_BUTTON_B: return m_JoyButtonB[controller]->GetValue();
|
||||
case IDB_BUTTON_X: return m_JoyButtonX[controller]->GetValue();
|
||||
case IDB_BUTTON_Y: return m_JoyButtonY[controller]->GetValue();
|
||||
case IDB_BUTTON_Z: return m_JoyButtonZ[controller]->GetValue();
|
||||
case IDB_BUTTONSTART: return m_JoyButtonStart[controller]->GetValue();
|
||||
|
||||
case IDB_BUTTONHALFPRESS: return m_JoyButtonHalfpress[controller]->GetValue();
|
||||
default: return wxString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Configure button mapping
|
||||
// ----------
|
||||
|
||||
|
||||
// Wait for button press
|
||||
// ---------------------
|
||||
/* Loop or timer: There are basically two ways to do this. With a while() or for() loop, or with a
|
||||
timer. The downside with the while() or for() loop is that there is no way to stop it if the user
|
||||
should select to configure another button while we are still in an old loop. What will happen then
|
||||
is that we start another parallel loop (at least in Windows) that blocks the old loop. And our only
|
||||
option to wait for the old loop to finish is with a new loop, and that will block the old loop for as
|
||||
long as it's going on. Therefore a timer is easier to control. */
|
||||
void PADConfigDialognJoy::GetButtons(wxCommandEvent& event)
|
||||
{
|
||||
DoGetButtons(event.GetId());
|
||||
}
|
||||
|
||||
void PADConfigDialognJoy::DoGetButtons(int GetId)
|
||||
{
|
||||
// =============================================
|
||||
// Collect the starting values
|
||||
// ----------------
|
||||
|
||||
// Get the current controller
|
||||
int Controller = notebookpage;
|
||||
int PadID = PadMapping[Controller].ID;
|
||||
|
||||
// Create a shortcut for the pad handle
|
||||
SDL_Joystick *joy = PadState[Controller].joy;
|
||||
|
||||
// Get the number of axes, hats and buttons
|
||||
int Buttons = SDL_JoystickNumButtons(joy);
|
||||
int Axes = SDL_JoystickNumAxes(joy);
|
||||
int Hats = SDL_JoystickNumHats(joy);
|
||||
|
||||
INFO_LOG(CONSOLE, "PadID: %i Axes: %i\n", PadID, joyinfo[PadID].NumAxes, joyinfo[PadID].joy);
|
||||
|
||||
// Get the controller and trigger type
|
||||
int ControllerType = PadMapping[Controller].controllertype;
|
||||
int TriggerType = PadMapping[Controller].triggertype;
|
||||
|
||||
// Collect the accepted buttons for this slot
|
||||
bool LeftRight = (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R);
|
||||
|
||||
bool Axis = (GetId >= IDB_ANALOG_MAIN_X && GetId <= IDB_SHOULDER_R)
|
||||
// Don't allow SDL input for the triggers when XInput is selected
|
||||
&& !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) );
|
||||
|
||||
bool XInput = (TriggerType == InputCommon::CTL_TRIGGER_XINPUT);
|
||||
|
||||
bool Button = (GetId >= IDB_BUTTON_A && GetId <= IDB_BUTTONHALFPRESS) // All digital buttons
|
||||
|| (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) // both shoulder buttons
|
||||
|| (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT && ControllerType == InputCommon::CTL_DPAD_CUSTOM); // Or the custom hat mode
|
||||
|
||||
bool Hat = (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT) // All DPads
|
||||
&& (PadMapping[Controller].controllertype == InputCommon::CTL_DPAD_HAT); // Not with the hat option defined
|
||||
|
||||
bool NoTriggerFilter = g_Config.bNoTriggerFilter;
|
||||
|
||||
// Values used in this function
|
||||
char format[128];
|
||||
int Seconds = 4; // Seconds to wait for
|
||||
int TimesPerSecond = 40; // How often to run the check
|
||||
|
||||
// Values returned from InputCommon::GetButton()
|
||||
int value; // Axis value
|
||||
int type; // Button type
|
||||
int pressed = 0;
|
||||
bool Succeed = false;
|
||||
bool Stop = false; // Stop the timer
|
||||
// =======================
|
||||
|
||||
// If the Id has changed or the timer is not running we should start one
|
||||
if( GetButtonWaitingID != GetId || !m_ButtonMappingTimer->IsRunning() )
|
||||
{
|
||||
if(m_ButtonMappingTimer->IsRunning())
|
||||
{
|
||||
m_ButtonMappingTimer->Stop();
|
||||
GetButtonWaitingTimer = 0;
|
||||
|
||||
// Update the old textbox
|
||||
SetButtonText(GetButtonWaitingID, "");
|
||||
}
|
||||
|
||||
// Save the button Id
|
||||
GetButtonWaitingID = GetId;
|
||||
|
||||
// Reset the key in case we happen to have an old one
|
||||
g_Pressed = 0;
|
||||
|
||||
// Update the text box
|
||||
sprintf(format, "[ %d ]", Seconds);
|
||||
SetButtonText(GetId, format);
|
||||
|
||||
// Start the timer
|
||||
#if wxUSE_TIMER
|
||||
m_ButtonMappingTimer->Start(1000 / TimesPerSecond);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// Check for buttons
|
||||
// ----------------
|
||||
|
||||
// If there is a timer but we should not create a new one
|
||||
else
|
||||
{
|
||||
InputCommon::GetButton(
|
||||
joy, PadID, Buttons, Axes, Hats,
|
||||
g_Pressed, value, type, pressed, Succeed, Stop,
|
||||
LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter);
|
||||
}
|
||||
// ========================= Check for keys
|
||||
|
||||
|
||||
// ===============================================
|
||||
// Process results
|
||||
// ----------------
|
||||
|
||||
// Count each time
|
||||
GetButtonWaitingTimer++;
|
||||
|
||||
// This is run every second
|
||||
if(GetButtonWaitingTimer % TimesPerSecond == 0)
|
||||
{
|
||||
// Current time
|
||||
int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond);
|
||||
|
||||
// Update text
|
||||
sprintf(format, "[ %d ]", TmpTime);
|
||||
SetButtonText(GetId, format);
|
||||
}
|
||||
|
||||
// Time's up
|
||||
if( (GetButtonWaitingTimer / TimesPerSecond) >= Seconds )
|
||||
{
|
||||
Stop = true;
|
||||
// Leave a blank mapping
|
||||
if(g_Config.bSaveByID) SetButtonTextAll(GetId, "-1"); else SetButtonText(GetId, "-1");
|
||||
}
|
||||
|
||||
// If we got a button
|
||||
if(Succeed)
|
||||
{
|
||||
Stop = true;
|
||||
// Write the number of the pressed button to the text box
|
||||
sprintf(format, "%d", pressed);
|
||||
if(g_Config.bSaveByID) SetButtonTextAll(GetId, format); else SetButtonText(GetId, format);
|
||||
}
|
||||
|
||||
// Stop the timer
|
||||
if(Stop)
|
||||
{
|
||||
m_ButtonMappingTimer->Stop();
|
||||
GetButtonWaitingTimer = 0;
|
||||
|
||||
/* Update the button mapping for all slots that use this device. (It doesn't make sense to have several slots
|
||||
controlled by the same device, but several DirectInput instances of different but identical devices may possible
|
||||
have the same id, I don't know. So we have to do this. The user may also have selected the same device for
|
||||
several disabled slots. */
|
||||
if(g_Config.bSaveByID) SaveButtonMappingAll(Controller); else SaveButtonMapping(Controller);
|
||||
}
|
||||
|
||||
// If we got a bad button
|
||||
if(g_Pressed == -1)
|
||||
{
|
||||
// Update text
|
||||
if(g_Config.bSaveByID) SetButtonTextAll(GetId, "-1"); else SetButtonText(GetId, "-1");
|
||||
|
||||
// Notify the user
|
||||
wxMessageBox(wxString::Format(
|
||||
wxT("You selected a key with a to low key code (%i), please")
|
||||
wxT(" select another key with a higher key code."), pressed)
|
||||
, wxT("Notice"), wxICON_INFORMATION);
|
||||
}
|
||||
}
|
||||
566
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/Images/controller.xpm
Normal file
566
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/Images/controller.xpm
Normal file
File diff suppressed because it is too large
Load Diff
4028
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/Images/njoy.xpm
Normal file
4028
Source/Plugins/Plugin_nJoy_SDL/Src/GUI/Images/njoy.xpm
Normal file
File diff suppressed because it is too large
Load Diff
196
Source/Plugins/Plugin_nJoy_SDL/Src/ReRecording.cpp
Normal file
196
Source/Plugins/Plugin_nJoy_SDL/Src/ReRecording.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
|
||||
// Project description
|
||||
// -------------------
|
||||
// Name: nJoy
|
||||
// Description: A Dolphin Compatible Input Plugin
|
||||
//
|
||||
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
||||
// Site: www.multigesture.net
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
//
|
||||
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
// File description
|
||||
/* ---------
|
||||
|
||||
Rerecording options
|
||||
|
||||
////////////////////////*/
|
||||
|
||||
|
||||
|
||||
// Include
|
||||
// ---------
|
||||
#include "nJoy.h"
|
||||
#include "FileUtil.h"
|
||||
#include "ChunkFile.h"
|
||||
|
||||
// TODO :
|
||||
// This is pretty much useless now with the TAS features right ?
|
||||
|
||||
#ifdef RERECORDING
|
||||
|
||||
|
||||
namespace Recording
|
||||
{
|
||||
|
||||
|
||||
|
||||
// Definitions
|
||||
// -------------
|
||||
// Pre defined maxium storage limit
|
||||
#define RECORD_SIZE (1024 * 128)
|
||||
SPADStatus RecordBuffer[RECORD_SIZE];
|
||||
int count = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Recording functions
|
||||
// -------------
|
||||
void RecordInput(const SPADStatus& _rPADStatus)
|
||||
{
|
||||
if (count >= RECORD_SIZE) return;
|
||||
RecordBuffer[count++] = _rPADStatus;
|
||||
|
||||
// Logging
|
||||
//u8 TmpData[sizeof(SPADStatus)];
|
||||
//memcpy(TmpData, &RecordBuffer[count - 1], sizeof(SPADStatus));
|
||||
//Console::Print("RecordInput(%i): %s\n", count, ArrayToString(TmpData, sizeof(SPADStatus), 0, 30).c_str());
|
||||
|
||||
// Auto save every ten seconds
|
||||
if (count % (60 * 10) == 0) Save();
|
||||
}
|
||||
|
||||
const SPADStatus& Play()
|
||||
{
|
||||
// Logging
|
||||
//Console::Print("PlayRecord(%i)\n", count);
|
||||
if (count >= RECORD_SIZE)
|
||||
{
|
||||
// Todo: Make the recording size unlimited?
|
||||
//PanicAlert("The recording reached its end");
|
||||
return(RecordBuffer[0]);
|
||||
}
|
||||
return(RecordBuffer[count++]);
|
||||
}
|
||||
|
||||
void Load()
|
||||
{
|
||||
FILE* pStream = fopen("pad-record.bin", "rb");
|
||||
|
||||
if (pStream != NULL)
|
||||
{
|
||||
fread(RecordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream);
|
||||
fclose(pStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("SimplePad: Could not open pad-record.bin");
|
||||
}
|
||||
|
||||
//Console::Print("LoadRecord()");
|
||||
}
|
||||
|
||||
void Save()
|
||||
{
|
||||
// Open the file in a way that clears all old data
|
||||
FILE* pStream = fopen("pad-record.bin", "wb");
|
||||
|
||||
if (pStream != NULL)
|
||||
{
|
||||
fwrite(RecordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream);
|
||||
fclose(pStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("NJoy: Could not save pad-record.bin");
|
||||
}
|
||||
//PanicAlert("SaveRecord()");
|
||||
//Console::Print("SaveRecord()");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
// -------------------------------------------
|
||||
// Rerecording
|
||||
// ----------------------
|
||||
#ifdef RERECORDING
|
||||
/* Check if we are starting the pad to record the input, and an old file exists. In that case ask
|
||||
if we really want to start the recording and eventually overwrite the file */
|
||||
if (g_Config.bRecording && File::Exists("pad-record.bin"))
|
||||
{
|
||||
if (!AskYesNo("An old version of '%s' aleady exists in your Dolphin directory. You can"
|
||||
" now make a copy of it before you start a new recording and overwrite the file."
|
||||
" Select Yes to continue and overwrite the file. Select No to turn off the input"
|
||||
" recording and continue without recording anything.",
|
||||
"pad-record.bin"))
|
||||
{
|
||||
// Turn off recording and continue
|
||||
g_Config.bRecording = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Load recorded input if we are to play it back, otherwise begin with a blank recording
|
||||
if (g_Config.bPlayback) Recording::Load();
|
||||
#endif
|
||||
// ----------------------
|
||||
}
|
||||
|
||||
|
||||
void ShutDown()
|
||||
{
|
||||
// Save recording
|
||||
if (g_Config.bRecording) Recording::Save();
|
||||
// Reset the counter
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void DoState(unsigned char **ptr, int mode)
|
||||
{
|
||||
// Load or save the counter
|
||||
PointerWrap p(ptr, mode);
|
||||
p.Do(count);
|
||||
|
||||
//Console::Print("count: %i\n", count);
|
||||
|
||||
// Update the frame counter for the sake of the status bar
|
||||
if (mode == PointerWrap::MODE_READ)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// This only works when rendering to the main window, I think
|
||||
PostMessage(GetParent(g_PADInitialize->hWnd), WM_USER, INPUT_FRAME_COUNTER, count);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // Recording
|
||||
|
||||
|
||||
#endif // RERECORDING
|
||||
380
Source/Plugins/Plugin_nJoy_SDL/Src/Rumble.cpp
Normal file
380
Source/Plugins/Plugin_nJoy_SDL/Src/Rumble.cpp
Normal file
@@ -0,0 +1,380 @@
|
||||
|
||||
// Project description
|
||||
// -------------------
|
||||
// Name: nJoy
|
||||
// Description: A Dolphin Compatible Input Plugin
|
||||
//
|
||||
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
||||
// Site: www.multigesture.net
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
//
|
||||
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
|
||||
// Include
|
||||
// ---------
|
||||
#include "nJoy.h"
|
||||
|
||||
|
||||
#ifdef RUMBLE_HACK
|
||||
|
||||
struct RUMBLE // GC Pad rumble DIDevice
|
||||
{
|
||||
LPDIRECTINPUTDEVICE8 g_pDevice; // 4 pads objects
|
||||
LPDIRECTINPUTEFFECT g_pEffect;
|
||||
DWORD g_dwNumForceFeedbackAxis;
|
||||
DIEFFECT eff;
|
||||
};
|
||||
|
||||
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContext);
|
||||
BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext);
|
||||
void SetDeviceForcesXY(int pad, int nXYForce);
|
||||
HRESULT InitRumble(HWND hWnd);
|
||||
|
||||
LPDIRECTINPUT8 g_Rumble; // DInput Rumble object
|
||||
RUMBLE pRumble[4]; // 4 GC Rumble Pads
|
||||
|
||||
//////////////////////
|
||||
// Use PAD rumble
|
||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||
|
||||
void Pad_Use_Rumble(u8 _numPAD)
|
||||
{
|
||||
if (PadMapping[_numPAD].rumble)
|
||||
{
|
||||
if (!g_Rumble)
|
||||
{
|
||||
// GetForegroundWindow() always sends the good HWND
|
||||
if (FAILED(InitRumble(GetForegroundWindow())))
|
||||
PanicAlert("Could not initialize Rumble!");
|
||||
} else
|
||||
{
|
||||
// Acquire gamepad
|
||||
if (pRumble[_numPAD].g_pDevice != NULL)
|
||||
pRumble[_numPAD].g_pDevice->Acquire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Set PAD rumble. Explanation: Stop = 0, Rumble = 1
|
||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||
|
||||
void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
|
||||
{
|
||||
if (!PadMapping[_numPAD].enable)
|
||||
return;
|
||||
|
||||
Pad_Use_Rumble(_numPAD);
|
||||
|
||||
int Strenght = 0;
|
||||
|
||||
if (PadMapping[_numPAD].rumble) // rumble activated
|
||||
{
|
||||
if (_uType == 1 && _uStrength > 2)
|
||||
{
|
||||
// it looks like _uStrength is equal to 3 everytime anyway...
|
||||
Strenght = 1000 * (g_Config.RumbleStrength + 1);
|
||||
Strenght = Strenght > 10000 ? 10000 : Strenght;
|
||||
}
|
||||
else
|
||||
Strenght = 0;
|
||||
|
||||
SetDeviceForcesXY(_numPAD, Strenght);
|
||||
}
|
||||
}
|
||||
|
||||
// Rumble stuff :D!
|
||||
// ----------------
|
||||
//
|
||||
|
||||
HRESULT InitRumble(HWND hWnd)
|
||||
{
|
||||
DIPROPDWORD dipdw;
|
||||
HRESULT hr;
|
||||
|
||||
// Register with the DirectInput subsystem and get a pointer to a IDirectInput interface we can use.
|
||||
if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&g_Rumble, NULL)))
|
||||
return hr;
|
||||
|
||||
// Look for a device we can use
|
||||
if (FAILED(hr = g_Rumble->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumFFDevicesCallback, NULL, DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK)))
|
||||
return hr;
|
||||
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
if (NULL == pRumble[i].g_pDevice)
|
||||
PadMapping[i].rumble = false; // Disable Rumble for this pad only.
|
||||
else
|
||||
{
|
||||
pRumble[i].g_pDevice->SetDataFormat(&c_dfDIJoystick);
|
||||
pRumble[i].g_pDevice->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND);
|
||||
// Request exclusive acces for both background and foreground.
|
||||
|
||||
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
|
||||
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
dipdw.diph.dwObj = 0;
|
||||
dipdw.diph.dwHow = DIPH_DEVICE;
|
||||
dipdw.dwData = FALSE;
|
||||
|
||||
// if Force Feedback doesn't seem to work...
|
||||
if (FAILED(pRumble[i].g_pDevice->EnumObjects(EnumAxesCallback,
|
||||
(void*)&pRumble[i].g_dwNumForceFeedbackAxis, DIDFT_AXIS))
|
||||
|| FAILED(pRumble[i].g_pDevice->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph)))
|
||||
{
|
||||
PanicAlert("Device %d doesn't seem to work ! \nRumble for device %d is now Disabled !", i+1);
|
||||
|
||||
PadMapping[i].rumble = false; // Disable Rumble for this pad
|
||||
|
||||
continue; // Next pad
|
||||
}
|
||||
|
||||
if (pRumble[i].g_dwNumForceFeedbackAxis > 2)
|
||||
pRumble[i].g_dwNumForceFeedbackAxis = 2;
|
||||
|
||||
DWORD _rgdwAxes[2] = {DIJOFS_X, DIJOFS_Y};
|
||||
long rglDirection[2] = {0, 0};
|
||||
DICONSTANTFORCE cf = {0};
|
||||
|
||||
ZeroMemory(&pRumble[i].eff, sizeof(pRumble[i].eff));
|
||||
pRumble[i].eff.dwSize = sizeof(DIEFFECT);
|
||||
pRumble[i].eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
|
||||
pRumble[i].eff.dwDuration = INFINITE; // fixed time may be safer (X * DI_SECONDS)
|
||||
pRumble[i].eff.dwSamplePeriod = 0;
|
||||
pRumble[i].eff.dwGain = DI_FFNOMINALMAX;
|
||||
pRumble[i].eff.dwTriggerButton = DIEB_NOTRIGGER;
|
||||
pRumble[i].eff.dwTriggerRepeatInterval = 0;
|
||||
pRumble[i].eff.cAxes = pRumble[i].g_dwNumForceFeedbackAxis;
|
||||
pRumble[i].eff.rgdwAxes = _rgdwAxes;
|
||||
pRumble[i].eff.rglDirection = rglDirection;
|
||||
pRumble[i].eff.lpEnvelope = 0;
|
||||
pRumble[i].eff.cbTypeSpecificParams = sizeof( DICONSTANTFORCE );
|
||||
pRumble[i].eff.lpvTypeSpecificParams = &cf;
|
||||
pRumble[i].eff.dwStartDelay = 0;
|
||||
|
||||
// Create the prepared effect
|
||||
if (FAILED(hr = pRumble[i].g_pDevice->CreateEffect(GUID_ConstantForce, &pRumble[i].eff, &pRumble[i].g_pEffect, NULL)))
|
||||
continue;
|
||||
|
||||
if (pRumble[i].g_pEffect == NULL)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void SetDeviceForcesXY(int npad, int nXYForce)
|
||||
{
|
||||
// Security check
|
||||
if (pRumble[npad].g_pDevice == NULL)
|
||||
return;
|
||||
|
||||
// If nXYForce is null, there's no point to create the effect
|
||||
// Just stop the force feedback
|
||||
if (nXYForce == 0) {
|
||||
pRumble[npad].g_pEffect->Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
long rglDirection[2] = {0};
|
||||
DICONSTANTFORCE cf;
|
||||
|
||||
// If only one force feedback axis, then apply only one direction and keep the direction at zero
|
||||
if (pRumble[npad].g_dwNumForceFeedbackAxis == 1)
|
||||
{
|
||||
rglDirection[0] = 0;
|
||||
cf.lMagnitude = nXYForce; // max should be 10000
|
||||
}
|
||||
// If two force feedback axis, then apply magnitude from both directions
|
||||
else
|
||||
{
|
||||
rglDirection[0] = nXYForce;
|
||||
rglDirection[1] = nXYForce;
|
||||
cf.lMagnitude = 1.4142f*nXYForce;
|
||||
}
|
||||
|
||||
ZeroMemory(&pRumble[npad].eff, sizeof(pRumble[npad].eff));
|
||||
pRumble[npad].eff.dwSize = sizeof(DIEFFECT);
|
||||
pRumble[npad].eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
|
||||
pRumble[npad].eff.cAxes = pRumble[npad].g_dwNumForceFeedbackAxis;
|
||||
pRumble[npad].eff.rglDirection = rglDirection;
|
||||
pRumble[npad].eff.lpEnvelope = 0;
|
||||
pRumble[npad].eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
|
||||
pRumble[npad].eff.lpvTypeSpecificParams = &cf;
|
||||
pRumble[npad].eff.dwStartDelay = 0;
|
||||
|
||||
// Now set the new parameters..
|
||||
pRumble[npad].g_pEffect->SetParameters(&pRumble[npad].eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START);
|
||||
// ..And start the effect immediately.
|
||||
if (pRumble[npad].g_pEffect != NULL)
|
||||
pRumble[npad].g_pEffect->Start(1, 0);
|
||||
}
|
||||
|
||||
BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContext)
|
||||
{
|
||||
LPDIRECTINPUTDEVICE8 pDevice;
|
||||
DIPROPDWORD dipdw;
|
||||
HRESULT hr;
|
||||
|
||||
int JoystickID;
|
||||
|
||||
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
|
||||
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
dipdw.diph.dwObj = 0;
|
||||
dipdw.diph.dwHow = DIPH_DEVICE;
|
||||
|
||||
g_Rumble->CreateDevice(pInst->guidInstance, &pDevice, NULL); // Create a DInput pad device
|
||||
|
||||
if (SUCCEEDED(hr = pDevice->GetProperty(DIPROP_JOYSTICKID, &dipdw.diph))) // Get DInput Device ID
|
||||
JoystickID = dipdw.dwData;
|
||||
else
|
||||
return DIENUM_CONTINUE;
|
||||
|
||||
//PanicAlert("DInput ID : %d \nSDL ID (1-4) : %d / %d / %d / %d\n", JoystickID, PadMapping[0].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID);
|
||||
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
if (PadMapping[i].ID == JoystickID) // if SDL ID = DInput ID -> we're dealing with the same device
|
||||
{
|
||||
// a DInput device is created even if rumble is disabled on startup
|
||||
// this way, you can toggle the rumble setting while in game
|
||||
//if (PadMapping[i].enabled) // && PadMapping[i].rumble
|
||||
pRumble[i].g_pDevice = pDevice; // everything looks good, save the DInput device
|
||||
}
|
||||
}
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext)
|
||||
{
|
||||
DWORD* pdwNumForceFeedbackAxis = (DWORD*)pContext; // Enum Rumble Axis
|
||||
if ((pdidoi->dwFlags & DIDOI_FFACTUATOR) != 0)
|
||||
(*pdwNumForceFeedbackAxis)++;
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
void PAD_RumbleClose()
|
||||
{
|
||||
// It may look weird, but we don't free anything here, it was the cause of crashes
|
||||
// on stop, and the DLL isn't unloaded anyway, so the pointers stay
|
||||
// We just stop the rumble in case it's still playing an effect.
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
if (pRumble[i].g_pDevice && pRumble[i].g_pEffect)
|
||||
pRumble[i].g_pEffect->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
#else // Multiplatform SDL Rumble code
|
||||
|
||||
#ifdef SDL_RUMBLE
|
||||
|
||||
struct RUMBLE // GC Pad rumble DIDevice
|
||||
{
|
||||
SDL_Haptic* g_pDevice;
|
||||
SDL_HapticEffect g_pEffect;
|
||||
int effect_id;
|
||||
};
|
||||
|
||||
RUMBLE pRumble[4] = {0}; // 4 GC Rumble Pads
|
||||
#endif
|
||||
|
||||
|
||||
// Use PAD rumble
|
||||
// --------------
|
||||
bool PAD_Init_Rumble(u8 _numPAD, SDL_Joystick *SDL_Device)
|
||||
{
|
||||
#ifdef SDL_RUMBLE
|
||||
if (SDL_Device == NULL)
|
||||
return false;
|
||||
|
||||
pRumble[_numPAD].g_pDevice = SDL_HapticOpenFromJoystick(SDL_Device);
|
||||
|
||||
if (pRumble[_numPAD].g_pDevice == NULL)
|
||||
return false; // Most likely joystick isn't haptic
|
||||
|
||||
if (!(SDL_HapticQuery(pRumble[_numPAD].g_pDevice) & SDL_HAPTIC_CONSTANT))
|
||||
{
|
||||
SDL_HapticClose(pRumble[_numPAD].g_pDevice); // No effect
|
||||
pRumble[_numPAD].g_pDevice = 0;
|
||||
PadMapping[_numPAD].rumble = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the strength of the rumble effect
|
||||
int Strenght = 3276 * (g_Config.RumbleStrength + 1);
|
||||
Strenght = Strenght > 32767 ? 32767 : Strenght;
|
||||
|
||||
// Create the effect
|
||||
memset(&pRumble[_numPAD].g_pEffect, 0, sizeof(SDL_HapticEffect)); // 0 is safe default
|
||||
pRumble[_numPAD].g_pEffect.type = SDL_HAPTIC_CONSTANT;
|
||||
pRumble[_numPAD].g_pEffect.constant.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
|
||||
pRumble[_numPAD].g_pEffect.constant.direction.dir[0] = 18000; // Force comes from south
|
||||
pRumble[_numPAD].g_pEffect.constant.level = Strenght;
|
||||
pRumble[_numPAD].g_pEffect.constant.length = 10000; // 10s long (should be INFINITE, but 10s is safer)
|
||||
pRumble[_numPAD].g_pEffect.constant.attack_length = 0; // disable Fade in...
|
||||
pRumble[_numPAD].g_pEffect.constant.fade_length = 0; // ...and out
|
||||
|
||||
// Upload the effect
|
||||
pRumble[_numPAD].effect_id = SDL_HapticNewEffect( pRumble[_numPAD].g_pDevice, &pRumble[_numPAD].g_pEffect );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Set PAD rumble. Explanation: Stop = 0, Rumble = 1
|
||||
// --------------
|
||||
void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
|
||||
{
|
||||
int Strenght = 0;
|
||||
|
||||
#ifdef SDL_RUMBLE
|
||||
if (PadMapping[_numPAD].rumble) // rumble activated
|
||||
{
|
||||
if (!pRumble[_numPAD].g_pDevice)
|
||||
return;
|
||||
|
||||
if (_uType == 1 && _uStrength > 2)
|
||||
SDL_HapticRunEffect( pRumble[_numPAD].g_pDevice, pRumble[_numPAD].effect_id, 1 );
|
||||
else
|
||||
SDL_HapticStopAll(pRumble[_numPAD].g_pDevice);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PAD_RumbleClose()
|
||||
{
|
||||
#ifdef SDL_RUMBLE
|
||||
for (int i=0; i<4; i++) // Free all pads
|
||||
{
|
||||
if (pRumble[i].g_pDevice) {
|
||||
SDL_HapticClose( pRumble[i].g_pDevice );
|
||||
pRumble[i].g_pDevice = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // RUMBLE_HACK
|
||||
31
Source/Plugins/Plugin_nJoy_SDL/Src/SConscript
Normal file
31
Source/Plugins/Plugin_nJoy_SDL/Src/SConscript
Normal file
@@ -0,0 +1,31 @@
|
||||
# -*- python -*-
|
||||
|
||||
Import('env')
|
||||
import sys
|
||||
|
||||
name = "Plugin_nJoy_SDL"
|
||||
padenv = env.Clone()
|
||||
|
||||
if not env['HAVE_SDL']:
|
||||
print name + " must have SDL to be build"
|
||||
Return()
|
||||
|
||||
files = [
|
||||
'Config.cpp',
|
||||
'nJoy.cpp',
|
||||
'Rumble.cpp',
|
||||
]
|
||||
if padenv['HAVE_WX']:
|
||||
files += [
|
||||
'GUI/AboutBox.cpp',
|
||||
'GUI/ConfigAdvanced.cpp',
|
||||
'GUI/ConfigJoypad.cpp',
|
||||
'GUI/ConfigBox.cpp',
|
||||
]
|
||||
|
||||
padenv.Append(
|
||||
CXXFLAGS = [ '-fPIC' ],
|
||||
LIBS = [ 'common', 'inputcommon' ],
|
||||
)
|
||||
|
||||
padenv.SharedLibrary(env['plugin_dir']+name, files)
|
||||
516
Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp
Normal file
516
Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp
Normal file
File diff suppressed because it is too large
Load Diff
111
Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h
Normal file
111
Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h
Normal file
@@ -0,0 +1,111 @@
|
||||
|
||||
// Project description
|
||||
// -------------------
|
||||
// Name: nJoy
|
||||
// Description: A Dolphin Compatible Input Plugin
|
||||
//
|
||||
// Author: Falcon4ever (nJoy@falcon4ever.com)
|
||||
// Site: www.multigesture.net
|
||||
// Copyright (C) 2003 Dolphin Project.
|
||||
//
|
||||
|
||||
//
|
||||
// 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/
|
||||
//
|
||||
|
||||
|
||||
|
||||
#ifndef __NJOY_h__
|
||||
#define __NJOY_h__
|
||||
|
||||
|
||||
// Includes
|
||||
// ----------
|
||||
#include <vector> // System
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
|
||||
#include "../../../Core/InputCommon/Src/SDL.h" // Core
|
||||
#include "../../../Core/InputCommon/Src/XInput.h"
|
||||
|
||||
#include "Common.h" // Common
|
||||
#include "Setup.h"
|
||||
#include "pluginspecs_pad.h"
|
||||
#include "IniFile.h"
|
||||
|
||||
#include "Config.h" // Local
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#include "GUI/AboutBox.h"
|
||||
#include "GUI/ConfigBox.h"
|
||||
#endif
|
||||
|
||||
// Define
|
||||
// ----------
|
||||
|
||||
// SDL Haptic fails on windows, it just doesn't work (even the sample doesn't work)
|
||||
// So until i can make it work, this is all disabled >:(
|
||||
#if SDL_VERSION_ATLEAST(1, 3, 0) && !defined(_WIN32)
|
||||
#define SDL_RUMBLE
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#define RUMBLE_HACK
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#pragma comment(lib, "dxguid.lib")
|
||||
#pragma comment(lib, "dinput8.lib")
|
||||
#pragma comment(lib, "winmm.lib")
|
||||
#include <dinput.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define INPUT_STATE wxT("PUBLIC RELEASE")
|
||||
#define RELDAY wxT("21")
|
||||
#define RELMONTH wxT("07")
|
||||
#define RELYEAR wxT("2008")
|
||||
#define THANKYOU wxT("`plot`, Absolute0, Aprentice, Bositman, Brice, ChaosCode, CKemu, CoDeX, Dave2001, dn, drk||Raziel, Florin, Gent, Gigaherz, Hacktarux, JegHegy, Linker, Linuzappz, Martin64, Muad, Knuckles, Raziel, Refraction, Rudy_x, Shadowprince, Snake785, Saqib, vEX, yaz0r, Zilmar, Zenogais and ZeZu.")
|
||||
#define PLUGIN_VER_STR wxT("Based on nJoy 0.3 by Falcon4ever\nRelease: ") RELDAY wxT("/") RELMONTH wxT("/") RELYEAR wxT("\nwww.multigesture.net")
|
||||
|
||||
|
||||
// Variables
|
||||
// ---------
|
||||
#ifndef _EXCLUDE_MAIN_
|
||||
extern SPADInitialize *g_PADInitialize;
|
||||
extern FILE *pFile;
|
||||
extern std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
|
||||
extern InputCommon::CONTROLLER_STATE PadState[4];
|
||||
extern InputCommon::CONTROLLER_MAPPING PadMapping[4];
|
||||
#ifdef _WIN32
|
||||
extern HWND m_hWnd, m_hConsole; // Handle to window
|
||||
#endif
|
||||
extern int NumPads, NumGoodPads, LastPad; // Number of goods pads
|
||||
#endif
|
||||
|
||||
|
||||
// Custom Functions
|
||||
// ----------------
|
||||
void Close_Devices();
|
||||
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads);
|
||||
void DEBUG_INIT();
|
||||
void DEBUG_QUIT();
|
||||
bool IsFocus();
|
||||
bool ReloadDLL();
|
||||
void PAD_RumbleClose();
|
||||
#endif // __NJOY_h__
|
||||
115
Source/Plugins/Plugin_nJoy_SDL/readme.txt
Normal file
115
Source/Plugins/Plugin_nJoy_SDL/readme.txt
Normal file
@@ -0,0 +1,115 @@
|
||||
nJoy v0.3 by Falcon4ever 2008
|
||||
A Dolphin Compatible Input Plugin
|
||||
Copyright (C) 2003 Dolphin Project.
|
||||
|
||||
Changelog
|
||||
==========================================================================
|
||||
|
||||
0.3: 3nd version of nJoy
|
||||
- Release: July 2008
|
||||
- Support for four players
|
||||
- Misc. improvements
|
||||
|
||||
0.2: 2nd version of nJoy
|
||||
- Release: 14th July 2005
|
||||
- Now using SDL instead of DirectInput9
|
||||
- Config/INI support
|
||||
- Adjustable deadzone
|
||||
- First public release
|
||||
|
||||
0.1: First version of nJoy
|
||||
- Private Release: january 2005
|
||||
- Using DirectInput9
|
||||
- Specially made for the Logitech Rumblepad 2, but other joypads work too
|
||||
- Advanced debug window, activated during gameplay
|
||||
- No deadzone configurable
|
||||
- No config/Ini
|
||||
|
||||
The Author
|
||||
==========================================================================
|
||||
* Falcon4ever (nJoy@falcon4ever.com)
|
||||
|
||||
System and Software Requirements
|
||||
==========================================================================
|
||||
Dolphin
|
||||
The latest Dolphin release, avaible at www.dolphin-emu.com
|
||||
|
||||
SDL.dll (SDL-1.2.13)
|
||||
(included with this release)
|
||||
latest version avaible at www.libsdl.org
|
||||
|
||||
A Joystick
|
||||
A Windows 9x compatible input device
|
||||
|
||||
|
||||
Plugin Information
|
||||
==========================================================================
|
||||
nJoy was written in C++, compiled with Microsoft Visual Studio 2005 Professional Edition.
|
||||
nJoy uses SDL for joysticks, mouse and keyboard.
|
||||
For the graphical interface plain Win32 code was used.
|
||||
|
||||
How to install
|
||||
==========================================================================
|
||||
Just unzip the content of the zipfile to your dolphin plugin dir and place
|
||||
sdl.dll in the root dir.
|
||||
|
||||
example config:
|
||||
[C:]
|
||||
|
|
||||
+-Dolphin Dir
|
||||
+-DolphinWx.exe File
|
||||
+-SDL.dll File
|
||||
|
|
||||
+-Plugins Dir
|
||||
+-nJoy.dll File
|
||||
|
||||
|
||||
FAQ
|
||||
==========================================================================
|
||||
|
||||
What's SDL???
|
||||
SDL is the Simple DirectMedia Layer written by Sam Lantinga.
|
||||
It provides an API for audio, video, input ...
|
||||
For more information go to http://www.libsdl.org/
|
||||
|
||||
Where can I download the latest releases???
|
||||
nJoy will be released @ www.multigesture.net
|
||||
|
||||
Can I mirror this file???
|
||||
Sure, just don't forget to add a link to:
|
||||
www.multigesture.net OR www.dolphin-emu.com
|
||||
-------------------- -------------------
|
||||
Why should I use nJoy instead of the default input plugin???
|
||||
At this moment the default plugin only supports keyboard input.
|
||||
nJoy supports Joysticks. And besides that, if you have an GC-adapter
|
||||
you can use your original GC controllers with dolphin !
|
||||
|
||||
Could you add [insert feature here] please???
|
||||
no.
|
||||
|
||||
But perhaps...
|
||||
NO!
|
||||
|
||||
Hmm... There is coming smoke out of my pc, wtf?
|
||||
err, this plugin comes without any warranty,
|
||||
use it at own risk :)
|
||||
|
||||
What should I do if my question isn't listed here???
|
||||
Just panic, call 911 or leave a message on:
|
||||
(1) Emutalk http://www.emutalk.net/forumdisplay.php?f=100
|
||||
(2) NGemu http://forums.ngemu.com/dolphin-discussion/
|
||||
|
||||
Thanks / Greetings
|
||||
==========================================================================
|
||||
|
||||
Special Thanks too:
|
||||
F|RES & ector
|
||||
|
||||
Greetings too:
|
||||
`plot`, Absolute0, Aprentice, Bositman, Brice, ChaosCode, CKemu,
|
||||
CoDeX, Dave2001, dn, drk||Raziel, Florin, Gent, Gigaherz, Hacktarux,
|
||||
icepir8, JegHegy, Linker, Linuzappz, Martin64, Muad, Knuckles, Raziel,
|
||||
Refraction, Rudy_x, Shadowprince, Snake785, Saqib, vEX, yaz0r,
|
||||
Zilmar, Zenogais and ZeZu.
|
||||
|
||||
AAaannd everyone else I forgot ;)...
|
||||
Reference in New Issue
Block a user