Fix a small misspell in OGL config, Fix the toggle fullscreen button when rendering to separate window + a weird issue related to rendering to main.

Code cleanup in nJoy i had around for a while, it also adds code to support SDL 1.3's force feedback API and is more stable (will not crash anymore on stop when rumble is enabled)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4459 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
sl1nk3.s 2009-10-24 00:18:21 +00:00
parent bf4ae6aaa0
commit 9154424841
21 changed files with 229 additions and 663 deletions

View file

@ -148,15 +148,6 @@ bool GetRealWiimote()
return g_bRealWiimote;
}
// This can occur when the emulator is not running and the nJoy configuration window is opened
void ReconnectPad()
{
CPluginManager &Plugins = CPluginManager::GetInstance();
Plugins.FreePad(0);
Plugins.GetPad(0)->Config(g_pWindowHandle);
INFO_LOG(CONSOLE, "ReconnectPad()\n");
}
// This doesn't work yet, I don't understand how the connection work yet
void ReconnectWiimote()
{

View file

@ -62,7 +62,6 @@ namespace Core
void* GetWindowHandle();
bool GetRealWiimote();
void ReconnectWiimote();
void ReconnectPad();
extern bool bReadTrace;
extern bool bWriteTrace;

View file

@ -141,18 +141,6 @@ int abc = 0;
{
switch (nMsg)
{
/*
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
break;
case WM_LBUTTONDBLCLK:
break;
*/
//case WM_KEYDOWN:
// break;
case WM_USER:
switch(wParam)
{
@ -170,11 +158,6 @@ int abc = 0;
main_frame->bRenderToMain = true;
return 0;
case NJOY_RELOAD:
// DirectInput in nJoy has failed
Core::ReconnectPad();
return 0;
case WIIMOTE_RECONNECT:
// The Wiimote plugin has been shut down, now reconnect the Wiimote
//INFO_LOG(CONSOLE, "WIIMOTE_RECONNECT\n");
@ -192,9 +175,6 @@ int abc = 0;
// -----------------------------
}
break;
//default:
// return wxPanel::MSWWindowProc(nMsg, wParam, lParam);
}
// By default let wxWidgets do what it normally does with this event
@ -261,7 +241,6 @@ EVT_MENU(IDM_BROWSE, CFrame::OnBrowse)
EVT_MENU(IDM_MEMCARD, CFrame::OnMemcard)
EVT_MENU(IDM_CHEATS, CFrame::OnShow_CheatsWindow)
EVT_MENU(IDM_INFO, CFrame::OnShow_InfoWindow)
EVT_MENU(IDM_RESTART, CFrame::OnRestart)
EVT_MENU(IDM_CHANGEDISC, CFrame::OnChangeDisc)
EVT_MENU(IDM_LOAD_WII_MENU, CFrame::OnLoadWiiMenu)
EVT_MENU(IDM_TOGGLE_FULLSCREEN, CFrame::OnToggleFullscreen)
@ -524,24 +503,6 @@ void CFrame::OnQuit(wxCommandEvent& WXUNUSED (event))
Close(true);
}
void CFrame::OnRestart(wxCommandEvent& WXUNUSED (event))
{
if (Core::GetState() != Core::CORE_UNINITIALIZED)
{
wxMessageBox(wxT("Please stop the current game before restarting."), wxT("Notice"), wxOK, this);
return;
}
// Get exe name and restart
#ifdef _WIN32
char Str[MAX_PATH + 1];
DWORD Size = sizeof(Str)/sizeof(char);
//DWORD n = GetModuleFileNameA(NULL, Str, Size);
ShellExecuteA(NULL, "open", PathToFilename(*new std::string(Str)).c_str(), g_pCodeWindow ? "" : "-d", NULL, SW_SHOW);
#endif
Close(true);
}
// --------
// Events
@ -705,10 +666,6 @@ void CFrame::OnGameListCtrl_ItemActivated(wxListEvent& WXUNUSED (event))
void CFrame::OnKeyDown(wxKeyEvent& event)
{
// In this case event.Skip() cause a double posting to this function
if (! (Core::GetState() == Core::CORE_RUN && bRenderToMain && event.GetEventObject() == this))
event.Skip();
// Toggle fullscreen
if (event.GetKeyCode() == WXK_ESCAPE || (event.GetKeyCode() == WXK_RETURN && event.GetModifiers() == wxMOD_ALT))
{
@ -721,14 +678,6 @@ void CFrame::OnKeyDown(wxKeyEvent& event)
}
#endif
#ifdef RERECORDING
// Turn on or off frame advance
if (event.GetKeyCode() == WXK_CONTROL) Core::FrameStepOnOff();
// Step forward
if (event.GetKeyCode() == WXK_SPACE) Core::FrameAdvance();
#endif
// Send the keyboard status to the Input plugin
if(Core::GetState() != Core::CORE_UNINITIALIZED)
CPluginManager::GetInstance().GetPad(0)->PAD_Input(event.GetKeyCode(), 1); // 1 = Down

View file

@ -309,7 +309,6 @@ class CFrame : public wxFrame
void OnShow_CheatsWindow(wxCommandEvent& event);
void OnShow_InfoWindow(wxCommandEvent& event);
void OnRestart(wxCommandEvent& event);
void OnLoadWiiMenu(wxCommandEvent& event);
void GameListChanged(wxCommandEvent& event);

View file

@ -120,7 +120,6 @@ void CFrame::CreateMenu()
fileMenu->AppendSeparator();
fileMenu->Append(IDM_BROWSE, _T("&Browse for ISOs..."));
fileMenu->AppendSeparator();
// fileMenu->Append(IDM_RESTART, g_pCodeWindow ? _T("Restart in regular &mode") : _T("&Restart in debugging &mode"));
fileMenu->Append(wxID_EXIT, _T("E&xit\tAlt+F4"));
m_MenuBar->Append(fileMenu, _T("&File"));
@ -781,7 +780,12 @@ void CFrame::OnLoadWiiMenu(wxCommandEvent& WXUNUSED (event))
// the entire screen (when we render to the main window).
void CFrame::OnToggleFullscreen(wxCommandEvent& WXUNUSED (event))
{
if (bRenderToMain || Core::GetState() != Core::CORE_RUN)
DoFullscreen(!IsFullScreen());
#ifdef _WIN32
else // Post the message to the separate rendering window which will then handle it.
PostMessage((HWND)Core::GetWindowHandle(), WM_USER, TOGGLE_FULLSCREEN, 0);
#endif
}
void CFrame::OnToggleDualCore(wxCommandEvent& WXUNUSED (event))

View file

@ -60,10 +60,12 @@ namespace InputCommon
// -----------------------
bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
{
/* SDL 1.3 use DirectInput instead of the old Microsoft Multimedia API, and with this we need
the SDL_INIT_VIDEO flag to */
if (!SDL_WasInit(0))
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
#if SDL_VERSION_ATLEAST(1, 3, 0)
if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC) < 0)
#else
if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
#endif
{
PanicAlert("Could not initialize SDL: %s", SDL_GetError());
return false;

View file

@ -40,8 +40,16 @@
#ifdef _WIN32
#include <SDL.h> // Externals
#include <SDL_version.h>
#if SDL_VERSION_ATLEAST(1, 3, 0)
#include <SDL_haptic.h>
#endif
#else
#include <SDL/SDL.h>
#include <SDL/SDL_version.h>
#if SDL_VERSION_ATLEAST(1, 3, 0)
#include <SDL/SDL_haptic.h>
#endif
#endif
#include "Common.h" // Common

View file

@ -27,9 +27,9 @@ enum PLUGIN_COMM
OPENGL_WM_USER_CREATE,
OPENGL_WM_USER_KEYDOWN,
OPENGL_VIDEO_STOP,
TOGGLE_FULLSCREEN,
VIDEO_DESTROY, // The video debugging window was destroyed
AUDIO_DESTROY, // The audio debugging window was destroyed
NJOY_RELOAD, // Reload nJoy if DirectInput has failed
WIIMOTE_RECONNECT, // Reconnect the Wiimote if it has disconnected
INPUT_FRAME_COUNTER // Wind back the frame counter for rerecording
};

View file

@ -141,6 +141,11 @@ LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
//PostQuitMessage( 0 );
break;
case WM_USER:
// if (wParam == TOGGLE_FULLSCREEN)
// TODO : Insert some toggle fullscreen code here, kthx :d
break;
case WM_SIZE:
// Reset the D3D Device here
// Also make damn sure that this is not called from inside rendering a frame :P

View file

@ -230,7 +230,7 @@ void GFXConfigDialogOGL::CreateGUIControls()
m_MSAAModeCB->Append(wxT("16xQ CSAA"));
m_MSAAModeCB->SetSelection(g_Config.iMultisampleMode);
m_OSDHotKey = new wxCheckBox(m_PageGeneral, ID_OSDHOTKEY, wxT("Enabke Hotkeys"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_OSDHotKey = new wxCheckBox(m_PageGeneral, ID_OSDHOTKEY, wxT("Enable Hotkeys"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
#ifndef _WIN32
// JPeterson set the hot key to be Win32-specific
m_OSDHotKey->Enable(false);
@ -328,7 +328,6 @@ void GFXConfigDialogOGL::CreateGUIControls()
sBasic->Add(m_WindowResolutionCB, wxGBPosition(2, 1), wxGBSpan(1, 1), wxALL, 5);
sBasic->Add(m_Fullscreen, wxGBPosition(1, 2), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5);
sBasic->Add(m_WindowFSResolutionCB, wxGBPosition(2, 2), wxGBSpan(1, 1), wxALL, 5);
sBasic->Add(m_Fullscreen, wxGBPosition(2, 3), wxGBSpan(1, 1), wxALL | wxALIGN_CENTER_VERTICAL, 5);
sBasic->Add(KeepARText, wxGBPosition(3, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5);
sBasic->Add(m_KeepAR, wxGBPosition(3, 1), wxGBSpan(1, 1), wxALL, 5);
@ -339,7 +338,7 @@ void GFXConfigDialogOGL::CreateGUIControls()
sBasic->Add(m_HideCursor, wxGBPosition(5, 0), wxGBSpan(1, 4), wxALL, 5);
#endif
sbBasic->Add(sBasic, 1, wxEXPAND);
sbBasic->Add(sBasic);
sGeneral->Add(sbBasic, 0, wxEXPAND|wxALL, 5);
sBasicAdvanced = new wxGridBagSizer(0, 0);
@ -357,7 +356,7 @@ void GFXConfigDialogOGL::CreateGUIControls()
sEnhancements = new wxGridBagSizer(0, 0);
sEnhancements->Add(AnisoText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sEnhancements->Add(m_MaxAnisotropyCB, wxGBPosition(0, 1), wxGBSpan(1, 1), wxALL|wxEXPAND, 5);
sEnhancements->Add(m_ForceFiltering, wxGBPosition(0, 2), wxGBSpan(1, 2), wxALL, 5);
sEnhancements->Add(m_ForceFiltering, wxGBPosition(0, 2), wxGBSpan(1, 2), wxALL|wxALIGN_CENTER_VERTICAL, 5);
sEnhancements->Add(MSAAText, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sEnhancements->Add(m_MSAAModeCB, wxGBPosition(1, 1), wxGBSpan(1, 1), wxALL|wxEXPAND, 5);
sEnhancements->Add(PostShaderText, wxGBPosition(2, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);

View file

@ -275,7 +275,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
switch (iMsg)
{
case WM_CREATE:
PostMessage(m_hParent, WM_USER, OPENGL_WM_USER_CREATE, (int)m_hParent);
PostMessage((HWND)g_VideoInitialize.pWindowHandle, WM_USER, OPENGL_WM_USER_CREATE, (int)m_hParent);
break;
case WM_PAINT:
@ -345,6 +345,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
}
if (wParam == OPENGL_WM_USER_KEYDOWN)
OnKeyDown(lParam);
if (wParam == TOGGLE_FULLSCREEN)
ToggleFullscreen(m_hWnd);
break;
// This is called when we close the window when we render to a separate window
@ -418,6 +420,11 @@ HWND OpenWindow(HWND parent, HINSTANCE hInstance, int width, int height, const T
// Create new separate window
else
{
// Don't forget to make it NULL, or a broken window will be created in case we
// render to main, stop, then render to separate window, as the GUI will still
// think we're rendering to main because m_hParent will still contain the old HWND...
m_hParent = NULL;
DWORD style = g_Config.bFullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW;
RECT rc = {0, 0, width, height};

View file

@ -328,8 +328,8 @@ void Initialize(void *init)
g_Config.Load(FULL_CONFIG_DIR "gfx_opengl.ini");
g_Config.GameIniLoad(globals->game_ini);
#if defined(HAVE_WX) && HAVE_WX
g_Config.UpdateProjectionHack();
#if defined(HAVE_WX) && HAVE_WX
//Enable support for PNG screenshots.
wxImage::AddHandler( new wxPNGHandler );
#endif

View file

@ -28,9 +28,6 @@
// http://code.google.com/p/dolphin-emu/
//
// Include
// ---------
#include "nJoy.h"
@ -67,7 +64,7 @@ void DEBUG_INIT()
#endif
pFile = fopen ("nJoy-debug.txt","wt");
fprintf(pFile, "nJoy v"INPUT_VERSION" Debug\n");
fprintf(pFile, "nJoy Debug\n");
#ifdef _WIN32
fprintf(pFile, "Date: %s\nTime: %s\n", dateStr, timeStr);
#endif
@ -181,10 +178,6 @@ void Config::Save(int Slot)
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);
// ======================================
// Debugging
//if(m_ConfigFrame) m_ConfigFrame->LogMsg("Saved: %s %i\n", SectionName.c_str(), PadMapping[i].triggertype);
}
INFO_LOG(CONSOLE, "%i: Save: %i\n", 0, PadMapping[0].halfpress);
@ -202,7 +195,7 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
// Load file
IniFile file;
file.Load(FULL_CONFIG_DIR "nJoy.ini");
bool Tmp; // Tmp storage
bool Tmp;
// ==================================================================
// Global settings
@ -211,10 +204,6 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
file.Get("General", "CheckForFocus", &g_Config.bCheckFocus, false);
file.Get("General", "NoTriggerFilter", &g_Config.bNoTriggerFilter, false);
file.Get("General", "RumbleStrength", &g_Config.RumbleStrength, 8);
#ifdef RERECORDING
file.Get("General", "Recording", &g_Config.bRecording, false);
file.Get("General", "Playback", &g_Config.bPlayback, false);
#endif
if(!ChangeSaveByID)
{
@ -239,8 +228,8 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
// 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 */
// 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
@ -280,10 +269,6 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
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;
// =============================
// Debugging
//if(m_ConfigFrame) m_ConfigFrame->LogMsg("%i: Enabled: %i\n", i, PadMapping[i].buttons[CTL_X_BUTTON]);
}
INFO_LOG(CONSOLE, "%i: Load: %i\n", 0, PadMapping[0].halfpress);

View file

@ -28,9 +28,6 @@
// http://code.google.com/p/dolphin-emu/
//
// Include
// ---------
#include "ConfigBox.h"
@ -39,17 +36,12 @@
extern bool g_EmulatorRunning;
/* If we don't use this hack m_MainSizer->GetMinSize().GetWidth() will not change
when we enable and disable bShowAdvanced */
bool StrangeHack = true;
// 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. */
// 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"));
@ -62,13 +54,6 @@ void PADConfigDialognJoy::PadGetStatus()
int PhysicalDevice = PadMapping[notebookpage].ID;
int TriggerType = PadMapping[notebookpage].triggertype;
// Analog stick
// -----------------
// Set Deadzones perhaps out of function
//int deadzone = (int)(((float)(128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
//int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
// Get original values
int main_x = PadState[notebookpage].axis[InputCommon::CTL_MAIN_X];
int main_y = PadState[notebookpage].axis[InputCommon::CTL_MAIN_Y];
@ -184,10 +169,6 @@ std::string ShowStatus(int VirtualController)
int Hats = joyinfo[PhysicalDevice].NumHats;
int Buttons = joyinfo[PhysicalDevice].NumButtons;
// Get version
//SDL_version Version;
//SDL_GetVersion(&Version);
// Update the internal values
SDL_JoystickUpdate();
@ -256,11 +237,6 @@ void PADConfigDialognJoy::Update()
"%s", ShowStatus(notebookpage).c_str()
));
#endif
//LogMsg("Abc%s\n", ShowStatus(notebookpage).c_str());
if(StrangeHack) PadGetStatus();
if(!g_Config.bShowAdvanced) StrangeHack = false; else StrangeHack = true;
}
@ -317,45 +293,6 @@ void PADConfigDialognJoy::CreateAdvancedControls(int i)
wxPoint(1, 1), wxDefaultSize);
m_bmpDotOutC[i] = new wxStaticBitmap(m_pOutStatusC[i], wxID_ANY, CreateBitmapDot(),
wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize);
// Rerecording
// ---------
#ifdef RERECORDING
// Create controls
m_SizeRecording[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Input Recording"));
m_CheckRecording[i] = new wxCheckBox(m_Controller[i], ID_RECORDING, wxT("Record input"));
m_CheckPlayback[i] = new wxCheckBox(m_Controller[i], ID_PLAYBACK, wxT("Play back input"));
m_BtnSaveRecording[i] = new wxButton(m_Controller[i], ID_SAVE_RECORDING, wxT("Save recording"), wxDefaultPosition, wxDefaultSize);
// Tool tips
m_CheckRecording[i]->SetToolTip(wxT("Your recording will be saved to pad-record.bin in the Dolphin dir when you stop the game"));
m_CheckPlayback[i]->SetToolTip(wxT("Play back the pad-record.bin file from the Dolphin dir"));
m_BtnSaveRecording[i]->SetToolTip(wxT(
"This will save the current recording to pad-record.bin. Your recording will\n"
"also be automatically saved every 60 * 10 frames. And when you shut down the\n"
"game."));
// Sizers
m_SizeRecording[i]->Add(m_CheckRecording[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_CheckPlayback[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_BtnSaveRecording[i], 0, wxEXPAND | wxALL, 1);
// Only enable these options for pad 0
m_CheckRecording[i]->Enable(false); m_CheckRecording[0]->Enable(true);
m_CheckPlayback[i]->Enable(false); m_CheckPlayback[0]->Enable(true);
m_BtnSaveRecording[i]->Enable(false); m_BtnSaveRecording[0]->Enable(true);
// Don't allow saving when we are not recording
m_BtnSaveRecording[i]->Enable(g_EmulatorRunning && g_Config.bRecording);
//sDevice[i]->Add(m_SizeRecording[i], 0, wxEXPAND | wxALL, 1);
// Set values
//m_CheckRecording[0]->SetValue(g_Config.bRecording);
//m_CheckPlayback[0]->SetValue(g_Config.bPlayback);
//Console::Print("m_CheckRecording: %i\n", g_Config.bRecording, g_Config.bPlayback);
#endif
}

View file

@ -83,11 +83,6 @@ BEGIN_EVENT_TABLE(PADConfigDialognJoy,wxDialog)
EVT_COMBOBOX(IDCB_CSTICK_DIAGONAL, PADConfigDialognJoy::ChangeSettings)
EVT_CHECKBOX(IDCB_CSTICK_S_TO_C, PADConfigDialognJoy::ChangeSettings)
EVT_CHECKBOX(IDCB_FILTER_SETTINGS, PADConfigDialognJoy::ChangeSettings)
#ifdef RERECORDING
EVT_CHECKBOX(ID_RECORDING, PADConfigDialognJoy::ChangeSettings)
EVT_CHECKBOX(ID_PLAYBACK, PADConfigDialognJoy::ChangeSettings)
EVT_BUTTON(ID_SAVE_RECORDING, PADConfigDialognJoy::GetButtons)
#endif
EVT_BUTTON(IDB_SHOULDER_L, PADConfigDialognJoy::GetButtons)
EVT_BUTTON(IDB_SHOULDER_R, PADConfigDialognJoy::GetButtons)
@ -155,9 +150,6 @@ PADConfigDialognJoy::~PADConfigDialognJoy()
void PADConfigDialognJoy::OnKeyDown(wxKeyEvent& event)
{
/*m_pStatusBar->SetLabel(wxString::Format(
"Key: %i", event.GetKeyCode()
));*/
g_Pressed = event.GetKeyCode();
}
@ -171,7 +163,7 @@ void PADConfigDialognJoy::OnClose(wxCloseEvent& event)
m_ConstantTimer->Stop();
// Close pads, unless we are running a game
if(!g_EmulatorRunning) Shutdown();
if (!g_EmulatorRunning) Shutdown();
}
// Call about dialog
@ -199,7 +191,7 @@ void PADConfigDialognJoy::OKClick(wxCommandEvent& event)
if (event.GetId() == ID_OK)
{
DoSave(); // Save settings
if(Debugging) PanicAlert("Done");
if (Debugging) PanicAlert("Done");
Close(); // Call OnClose()
}
}
@ -219,7 +211,7 @@ void PADConfigDialognJoy::CancelClick(wxCommandEvent& event)
void PADConfigDialognJoy::LogMsg(const char* format, ...)
{
#ifdef _WIN32
if(Debugging)
if (Debugging)
{
const int MaxMsgSize = 1024*2;
char buffer[MaxMsgSize];
@ -257,7 +249,7 @@ void PADConfigDialognJoy::DoSave(bool ChangePad, int Slot)
// Replace "" with "-1" before we are saving
ToBlank(false);
if(ChangePad)
if (ChangePad)
{
// Since we are selecting the pad to save to by the Id we can't update it when we change the pad
for(int i = 0; i < 4; i++) SaveButtonMapping(i, true);
@ -304,34 +296,18 @@ void PADConfigDialognJoy::DoChangeJoystick()
g_Config.Load(true);
UpdateGUI(notebookpage); // Update the GUI
}
void PADConfigDialognJoy::PadOpen(int Open) // Open for slot 1, 2, 3 or 4
{
// Check that we got a good pad
if (!joyinfo.at(PadMapping[Open].ID).Good)
{
PadState[Open].joy = NULL;
return;
}
PadState[Open].joy = SDL_JoystickOpen(PadMapping[Open].ID);
}
void PADConfigDialognJoy::PadClose(int Close) // Close for slot 1, 2, 3 or 4
{
if (SDL_JoystickOpened(PadMapping[Close].ID)) SDL_JoystickClose(PadState[Close].joy);
PadState[Close].joy = NULL;
}
// Notebook page changed
void PADConfigDialognJoy::NotebookPageChanged(wxNotebookEvent& event)
{
// Save current settings now, don't wait for OK
if(ControlsCreated && !g_Config.bSaveByID) DoSave(false, notebookpage);
if (ControlsCreated && !g_Config.bSaveByID) DoSave(false, notebookpage);
// Update the global variable
notebookpage = event.GetSelection();
// Update GUI
if(ControlsCreated) UpdateGUI(notebookpage);
if (ControlsCreated) UpdateGUI(notebookpage);
}
// Replace the harder to understand -1 with "" for the sake of user friendliness
@ -365,7 +341,7 @@ void PADConfigDialognJoy::SetButtonTextAll(int id, const char *text)
for (int i = 0; i < 4; i++)
{
// Safety check to avoid crash
if(joyinfo.size() > (u32)PadMapping[i].ID)
if (joyinfo.size() > (u32)PadMapping[i].ID)
if (joyinfo[PadMapping[i].ID].Name == joyinfo[PadMapping[notebookpage].ID].Name)
SetButtonText(id, text, i);
};
@ -376,7 +352,7 @@ void PADConfigDialognJoy::SaveButtonMappingAll(int Slot)
for (int i = 0; i < 4; i++)
{
// This can occur when no gamepad is detected
if(joyinfo.size() > (u32)PadMapping[i].ID)
if (joyinfo.size() > (u32)PadMapping[i].ID)
if (joyinfo[PadMapping[i].ID].Name == joyinfo[PadMapping[Slot].ID].Name)
SaveButtonMapping(i, false, Slot);
}
@ -384,7 +360,7 @@ void PADConfigDialognJoy::SaveButtonMappingAll(int Slot)
void PADConfigDialognJoy::UpdateGUIAll(int Slot)
{
if(Slot == -1)
if (Slot == -1)
{
for (int i = 0; i < 4; i++) UpdateGUI(i);
}
@ -393,7 +369,7 @@ void PADConfigDialognJoy::UpdateGUIAll(int Slot)
for (int i = 0; i < 4; i++)
{
// Safety check to avoid crash
if(joyinfo.size() > (u32)PadMapping[i].ID)
if (joyinfo.size() > (u32)PadMapping[i].ID)
if (joyinfo[PadMapping[i].ID].Name == joyinfo[PadMapping[Slot].ID].Name)
UpdateGUI(i);
}
@ -412,11 +388,14 @@ void PADConfigDialognJoy::ChangeSettings( wxCommandEvent& event )
g_Config.bShowAdvanced = m_CBShowAdvanced[notebookpage]->IsChecked();
for(int i = 0; i < 4; i++)
{
UpdateGUI(i);
m_CBShowAdvanced[i]->SetValue(g_Config.bShowAdvanced);
m_sMainRight[i]->Show(g_Config.bShowAdvanced);
}
SizeWindow();
// Resize the window without the need of any weird hack
SetSizerAndFit(m_MainSizer);
break;
// Advanced settings
case IDCB_CHECKFOCUS:
g_Config.bCheckFocus = m_CBCheckFocus[notebookpage]->IsChecked();
@ -432,24 +411,6 @@ void PADConfigDialognJoy::ChangeSettings( wxCommandEvent& event )
m_AdvancedMapFilter[i]->SetValue(g_Config.bNoTriggerFilter);
}
break;
#ifdef RERECORDING
case ID_RECORDING:
g_Config.bRecording = m_CheckRecording[notebookpage]->IsChecked();
if(g_Config.bRecording) g_Config.bPlayback = !g_Config.bRecording;
for(int i = 0; i < 4; i++) m_CheckRecording[i]->SetValue(g_Config.bRecording);
for(int i = 0; i < 4; i++) m_CheckPlayback[i]->SetValue(g_Config.bPlayback);
break;
case ID_PLAYBACK:
g_Config.bPlayback = m_CheckPlayback[notebookpage]->IsChecked();
if(g_Config.bPlayback) g_Config.bRecording = !g_Config.bPlayback;
for(int i = 0; i < 4; i++) m_CheckPlayback[i]->SetValue(g_Config.bPlayback);
for(int i = 0; i < 4; i++) m_CheckPlayback[i]->SetValue(g_Config.bRecording);
break;
case ID_SAVE_RECORDING:
// Double check again that we are still running a game
if (g_EmulatorRunning) Recording::Save();
break;
#endif
case IDC_CONTROLTYPE:
if(!g_Config.bSaveByID)
@ -529,10 +490,6 @@ void PADConfigDialognJoy::UpdateGUI(int _notebookpage)
m_CBCheckFocus[_notebookpage]->SetValue(g_Config.bCheckFocus);
m_AdvancedMapFilter[_notebookpage]->SetValue(g_Config.bNoTriggerFilter);
m_RStrength[_notebookpage]->SetSelection(g_Config.RumbleStrength);
#ifdef RERECORDING
m_CheckRecording[_notebookpage]->SetValue(g_Config.bRecording);
m_CheckPlayback[_notebookpage]->SetValue(g_Config.bPlayback);
#endif
// Replace the harder to understand -1 with "" for the sake of user friendliness
ToBlank();
@ -568,12 +525,12 @@ void PADConfigDialognJoy::OnPaint(wxPaintEvent &event)
// Populate the config window
void PADConfigDialognJoy::CreateGUIControls()
{
INFO_LOG(CONSOLE, "CreateGUIControls()\n");
INFO_LOG(PAD, "CreateGUIControls()\n");
#ifndef _DEBUG
SetTitle(wxT("Configure: nJoy v")wxT(INPUT_VERSION)wxT(" Input Plugin"));
SetTitle(wxT("Configure: nJoy Input Plugin"));
#else
SetTitle(wxT("Configure: nJoy v")wxT(INPUT_VERSION)wxT(" (Debug) Input Plugin"));
SetTitle(wxT("Configure: nJoy (Debug) Input Plugin"));
#endif
SetIcon(wxNullIcon);
@ -614,7 +571,7 @@ void PADConfigDialognJoy::CreateGUIControls()
// Search for devices and add them to the device list
wxArrayString arrayStringFor_Joyname; // The string array
if(NumGoodPads > 0)
if (NumGoodPads > 0)
{
for(int x = 0; (u32)x < joyinfo.size(); x++)
{
@ -829,6 +786,9 @@ void PADConfigDialognJoy::CreateGUIControls()
// Create objects for Rumble settings (general 4)
m_RStrength[i] = new wxComboBox(m_Controller[i], IDC_RUMBLESTRENGTH, wxAS_RumbleStrength[0], wxDefaultPosition, wxSize(85, 20), wxAS_RumbleStrength, wxCB_READONLY);
m_Rumble[i] = new wxCheckBox(m_Controller[i], IDC_ENABLERUMBLE, wxT("Enable Rumble"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
#if !SDL_VERSION_ATLEAST(1, 3, 0) && !defined(_WIN32)
m_Rumble[i]->Disable();
#endif
// Populate general settings 4
m_gRumble[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Rumble settings"));
@ -990,7 +950,7 @@ void PADConfigDialognJoy::CreateGUIControls()
m_sMain[i] = new wxBoxSizer(wxHORIZONTAL);
m_sMain[i]->Add(m_sMainLeft[i], 0, wxEXPAND | (wxALL), 0);
m_sMain[i]->Add(m_sMainRight[i], 0, wxEXPAND | (wxRIGHT | wxTOP), 5);
m_Controller[i]->SetSizer(m_sMain[i]); // Set the main sizer
m_Controller[i]->SetSizerAndFit(m_sMain[i]); // Set the main sizer
// Show or hide it. We have to do this after we add it to its sizer
m_sMainRight[i]->Show(g_Config.bShowAdvanced);
@ -999,7 +959,6 @@ void PADConfigDialognJoy::CreateGUIControls()
UpdateGUI(i);
} // end of loop
// Populate buttons sizer.
wxBoxSizer * m_sButtons = new wxBoxSizer(wxHORIZONTAL);
m_sButtons->Add(m_About, 0, (wxBOTTOM), 0);
@ -1012,23 +971,14 @@ void PADConfigDialognJoy::CreateGUIControls()
m_MainSizer = new wxBoxSizer(wxVERTICAL);
m_MainSizer->Add(m_Notebook, 0, wxEXPAND | wxALL, 5);
m_MainSizer->Add(m_sButtons, 1, wxEXPAND | ( wxLEFT | wxRIGHT | wxBOTTOM), 5);
this->SetSizer(m_MainSizer);
SetSizerAndFit(m_MainSizer);
// Debugging
#ifdef SHOW_PAD_STATUS
m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(135, 100), wxDefaultSize);
#endif
//m_pStatusBar2 = new wxStaticText(this, IDT_DEBUGGING2, wxT("Debugging2"), wxPoint(125, 200), wxDefaultSize);
//m_pStatusBar->SetLabel(wxString::Format("Debugging text"));
/*m_TCDebugging = new wxTextCtrl(this, IDT_DEBUGGING3, _T(""), wxDefaultPosition, wxSize(400, 400),
wxTE_RICH | wxTE_MULTILINE | wxTE_DONTWRAP | wxNO_BORDER);
wxBoxSizer * m_LogSizer = new wxBoxSizer(wxVERTICAL);
m_LogSizer->Add(m_TCDebugging, 0, wxEXPAND | (wxALL), 0);
m_MainSizer->Add(m_LogSizer, 0, wxEXPAND | ( wxLEFT | wxRIGHT | wxBOTTOM), 5);*/
// Set window size
SizeWindow();
Center();
// All done
@ -1037,8 +987,3 @@ void PADConfigDialognJoy::CreateGUIControls()
// Replace the harder to understand -1 with "" for the sake of user friendliness
ToBlank();
}
void PADConfigDialognJoy::SizeWindow()
{
SetClientSize(m_MainSizer->GetMinSize().GetWidth(), m_MainSizer->GetMinSize().GetHeight());
}

View file

@ -196,11 +196,6 @@ class PADConfigDialognJoy : public wxDialog
*m_bmpSquareC[4], *m_bmpDotC[4], *m_bmpSquareOutC[4], *m_bmpDotOutC[4], *m_bmpAreaOutC[4];
int notebookpage; bool ControlsCreated;
#ifdef RERECORDING
wxStaticBoxSizer *m_SizeRecording[4];
wxCheckBox *m_CheckRecording[4], *m_CheckPlayback[4];
wxButton *m_BtnSaveRecording[4];
#endif
private:
enum
@ -236,9 +231,6 @@ class PADConfigDialognJoy : public wxDialog
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,
#ifdef RERECORDING
ID_RECORDING, ID_PLAYBACK, ID_SAVE_RECORDING,
#endif
// Timers
IDTM_CONSTANT, IDTM_BUTTON,
@ -327,9 +319,6 @@ class PADConfigDialognJoy : public wxDialog
void DoChangeJoystick();
void PadOpen(int Open);
void PadClose(int Close);
void UpdateGUI(int _notebookpage);
void ChangeSettings(wxCommandEvent& event);
@ -338,7 +327,6 @@ class PADConfigDialognJoy : public wxDialog
void OnClose(wxCloseEvent& event);
void CreateGUIControls();
void CreateAdvancedControls(int i);
void SizeWindow();
wxBitmap CreateBitmap();
wxBitmap CreateBitmapDot();
wxBitmap CreateBitmapArea(int,int);

View file

@ -86,10 +86,6 @@ void PADConfigDialognJoy::UpdateGUIButtonMapping(int controller)
m_AdvancedMapFilter[controller]->SetValue(g_Config.bNoTriggerFilter);
// Update Rumble checkbox
m_Rumble[controller]->SetValue(PadMapping[controller].rumble);
#ifdef RERECORDING
m_CheckRecording[controller]->SetValue(g_Config.bRecording);
m_CheckPlayback[controller]->SetValue(g_Config.bPlayback);
#endif
// Update D-Pad
if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT)
@ -153,9 +149,6 @@ void PADConfigDialognJoy::SaveButtonMapping(int controller, bool DontChangeId, i
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();
//LogMsg("PadMapping[%i].triggertype = %i, m_TriggerType[%i]->GetSelection() = %i\n",
// controller, PadMapping[controller].triggertype, FromSlot, m_TriggerType[FromSlot]->GetSelection());
// The halfpress button
m_JoyButtonHalfpress[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].halfpress = value; tmp.clear();
@ -324,9 +317,6 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
bool Stop = false; // Stop the timer
// =======================
//INFO_LOG(CONSOLE, "Before (%i) Id:%i %i IsRunning:%i\n",
// GetButtonWaitingTimer, GetButtonWaitingID, GetId, m_ButtonMappingTimer->IsRunning());
// If the Id has changed or the timer is not running we should start one
if( GetButtonWaitingID != GetId || !m_ButtonMappingTimer->IsRunning() )
{
@ -430,12 +420,4 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
wxT(" select another key with a higher key code."), pressed)
, wxT("Notice"), wxICON_INFORMATION);
}
// ======================== Process results
// Debugging
/*
INFO_LOG(CONSOLE, "Change: %i %i %i %i '%s' '%s' '%s' '%s'\n",
PadMapping[0].halfpress, PadMapping[1].halfpress, PadMapping[2].halfpress, PadMapping[3].halfpress,
m_JoyButtonHalfpress[0]->GetValue().c_str(), m_JoyButtonHalfpress[1]->GetValue().c_str(), m_JoyButtonHalfpress[2]->GetValue().c_str(), m_JoyButtonHalfpress[3]->GetValue().c_str()
);*/
}

View file

@ -46,7 +46,8 @@ Rerecording options
#include "FileUtil.h"
#include "ChunkFile.h"
// TODO :
// This is pretty much useless now with the TAS features right ?
#ifdef RERECORDING

View file

@ -28,57 +28,37 @@
// http://code.google.com/p/dolphin-emu/
//
// Include
// ---------
#include "nJoy.h"
#ifdef RUMBLE_HACK
// Enable or disable rumble.
// ---------
// Rumble in windows
#ifdef _WIN32
struct RUMBLE // GC Pad rumble DIDevice
{
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; } }
#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);
LPDIRECTINPUT8 g_Rumble; // DInput Rumble object
RUMBLE pRumble[4]; // 4 GC Rumble Pads
extern InputCommon::CONTROLLER_MAPPING PadMapping[4];
#elif defined(__linux__)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int fd;
char device_file_name[64];
struct ff_effect effect;
bool CanRumble = false;
#endif
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)
{
#ifdef _WIN32
if (PadMapping[_numPAD].rumble)
{
if (!g_Rumble)
@ -93,101 +73,33 @@ void Pad_Use_Rumble(u8 _numPAD)
pRumble[_numPAD].g_pDevice->Acquire();
}
}
#elif defined(__linux__)
if (!fd)
{
sprintf(device_file_name, "/dev/input/event%d", PadMapping[_numPAD].eventnum); //TODO: Make dynamic //
/* Open device */
fd = open(device_file_name, O_RDWR);
if (fd == -1) {
perror("Open device file");
//Something wrong, probably permissions, just return now
return;
}
int n_effects = 0;
if (ioctl(fd, EVIOCGEFFECTS, &n_effects) == -1) {
perror("Ioctl number of effects");
}
if (n_effects > 0)
CanRumble = true;
else
return; // Return since we can't do any effects
/* a strong rumbling effect */
effect.type = FF_RUMBLE;
effect.id = -1;
effect.u.rumble.strong_magnitude = 0x8000;
effect.u.rumble.weak_magnitude = 0;
effect.replay.length = 5000; // Set to 5 seconds, if a Game needs more for a single rumble event, it is dumb and must be a demo
effect.replay.delay = 0;
if (ioctl(fd, EVIOCSFF, &effect) == -1) {
perror("Upload effect");
CanRumble = false; //We have effects but it doesn't support the rumble we are using. This is basic rumble, should work for most
}
}
#endif
}
////////////////////////////////////////////////////
// Set PAD rumble. Explanation: Stop = 0, Rumble = 1
// --------------
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
{
Pad_Use_Rumble(_numPAD);
// SDL can't rumble the gamepad so we need to use platform specific code
#ifdef _WIN32
int a = 0;
if (_uType == 1)
{
// it looks like _uStrength is equal to 3 everytime anyway...
a = _uStrength > 2 ? (1000*(g_Config.RumbleStrength + 1)) : 0;
a = a > 10000 ? 10000 : a;
}
// a = int ((float)a * 0.96f);
// What is this for ?
// else if ((_uType == 0) || (_uType == 2))
int Strenght = 0;
if (PadMapping[_numPAD].rumble) // rumble activated
{
// Start Effect
SetDeviceForcesXY(_numPAD, a);
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;
#elif defined(__linux__)
struct input_event event;
if (CanRumble)
{
if (_uType == 1)
{
event.type = EV_FF;
event.code = effect.id;
event.value = 1;
if (write(fd, (const void*) &event, sizeof(event)) == -1) {
perror("Play effect");
exit(1);
SetDeviceForcesXY(_numPAD, Strenght);
}
}
if ((_uType == 0) || (_uType == 2))
{
event.type = EV_FF;
event.code = effect.id;
event.value = 0;
if (write(fd, (const void*) &event, sizeof(event)) == -1) {
perror("Stop effect");
exit(1);
}
}
}
#endif
}
#ifdef _WIN32
// Rumble stuff :D!
// ----------------
//
@ -360,21 +272,106 @@ BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pCont
return DIENUM_CONTINUE;
}
VOID FreeDirectInput()
void PAD_RumbleClose()
{
// Unacquire the device one last time just in case
// the app tried to exit while the device is still acquired.
for (int i=0; i<4; i++) // Free all pads
// 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_pDevice->Unacquire();
SAFE_RELEASE(pRumble[i].g_pEffect);
SAFE_RELEASE(pRumble[i].g_pDevice);
if (pRumble[i].g_pDevice && pRumble[i].g_pEffect)
pRumble[i].g_pEffect->Stop();
}
SAFE_RELEASE(g_Rumble); // Rumble object
}
#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[_numPAD].g_pDevice) {
SDL_HapticClose( pRumble[_numPAD].g_pDevice );
pRumble[_numPAD].g_pDevice = NULL;
}
}
#endif
}
#endif // RUMBLE_HACK

View file

@ -28,44 +28,6 @@
// http://code.google.com/p/dolphin-emu/
//
// Issues
/* ---------
The StrangeHack in ConfigAdvanced.cpp doesn't work in Linux, it still wont resize the
window correctly. So currently in Linux you have to have advanced controls enabled when
you open the window to see them.
// TODO : we should not need a Hack in the first place :/
////////////////////////*/
// Variables guide
/* ---------
Joyinfo[1, 2, 3, 4, ..., number of attached devices]: Gamepad info that is populate by Search_Devices()
PadMapping[1, 2, 3 and 4]: The button mapping
Joystate[1, 2, 3 and 4]: The current button states
The arrays PadMapping[] and PadState[] are numbered 0 to 3 for the four different virtual
controllers. Joysticks[].ID will have the number of the physical input device mapped to that
controller (this value range between 0 and the total number of connected physical devices). The
mapping of a certain physical device to PadState[].joy is initially done by Initialize(), but
for the configuration we can remap that, like in PADConfigDialognJoy::ChangeJoystick().
The joyinfo[] array holds the physical gamepad info for a certain physical device. It's therefore
used as joyinfo[PadMapping[controller].ID] if we want to get the joyinfo for a certain joystick.
////////////////////////*/
// Include
// ---------
#include "nJoy.h"
@ -78,10 +40,8 @@
// Variables
// ---------
#define _EXCLUDE_MAIN_ // Avoid certain declarations in nJoy.h
FILE *pFile;
std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
@ -95,10 +55,6 @@ int NumPads = 0, NumGoodPads = 0, LastPad = 0;
SPADInitialize *g_PADInitialize = NULL;
PLUGIN_GLOBALS* globals = NULL;
// Rumble
#if defined(__linux__)
extern int fd;
#endif
// Standard crap to make wxWidgets happy
#ifdef _WIN32
@ -177,12 +133,12 @@ void GetDllInfo(PLUGIN_INFO* _PluginInfo)
_PluginInfo->Type = PLUGIN_TYPE_PAD;
#ifdef DEBUGFAST
sprintf(_PluginInfo->Name, "nJoy v"INPUT_VERSION" (DebugFast) by Falcon4ever");
sprintf(_PluginInfo->Name, "nJoy (DebugFast) by Falcon4ever");
#else
#ifndef _DEBUG
sprintf(_PluginInfo->Name, "nJoy v"INPUT_VERSION " by Falcon4ever");
sprintf(_PluginInfo->Name, "nJoy by Falcon4ever");
#else
sprintf(_PluginInfo->Name, "nJoy v"INPUT_VERSION" (Debug) by Falcon4ever");
sprintf(_PluginInfo->Name, "nJoy (Debug) by Falcon4ever");
#endif
#endif
}
@ -198,26 +154,9 @@ void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
// ------------------
void DllConfig(HWND _hParent)
{
#ifdef _WIN32
// Start the pads so we can use them in the configuration and advanced controls
if (!g_EmulatorRunning)
{
Search_Devices(joyinfo, NumPads, NumGoodPads); // Populate joyinfo for all attached devices
// Check if a DirectInput error occured
if (ReloadDLL())
{
PostMessage(_hParent, WM_USER, NJOY_RELOAD, 0);
return;
}
}
#else
if (SDL_Init(SDL_INIT_JOYSTICK ) < 0)
{
printf("Could not initialize SDL! (%s)\n", SDL_GetError());
return;
}
#endif
// Init Joystick + Haptic (force feedback) subsystem on SDL 1.3
// Populate joyinfo for all attached devices
Search_Devices(joyinfo, NumPads, NumGoodPads);
g_Config.Load(); // load settings
@ -240,19 +179,9 @@ void DllDebugger(HWND _hParent, bool Show) {}
// Init PAD (start emulation)
// --------------------------
/* Information: This function can not be run twice without a Shutdown in between. If
it's run twice the SDL_Init() will cause a crash. One solution to this is to keep a
global function that remembers the SDL_Init() and SDL_Quit() (g_EmulatorRunning does
not do that since we can open and close this without any game running). But I would
suggest that avoiding to run this twice from the Core is better. */
void Initialize(void *init)
{
// Debugging
// #ifdef SHOW_PAD_STATUS
// Console::Open(110);
// m_hConsole = Console::GetHwnd();
// #endif
INFO_LOG(CONSOLE, "Initialize: %i\n", SDL_WasInit(0));
INFO_LOG(PAD, "Initialize: %i\n", SDL_WasInit(0));
g_PADInitialize = (SPADInitialize*)init;
g_EmulatorRunning = true;
@ -264,18 +193,8 @@ void Initialize(void *init)
DEBUG_INIT();
#endif
// Populate joyinfo for all attached devices if the configuration window is not already open
#if defined(HAVE_WX) && HAVE_WX
if(!m_ConfigFrame)
{
// Populate joyinfo for all attached devices
Search_Devices(joyinfo, NumPads, NumGoodPads);
// Check if a DirectInput error occured
if(ReloadDLL()) g_PADInitialize->padNumber = -1;
}
#endif
#ifdef RERECORDING
Recording::Initialize();
#endif
}
// Shutdown PAD (stop emulation)
@ -285,15 +204,7 @@ void Initialize(void *init)
Called from: The Dolphin Core, PADConfigDialognJoy::OnClose() */
void Shutdown()
{
INFO_LOG(CONSOLE, "Shutdown: %i\n", SDL_WasInit(0));
// -------------------------------------------
// Play back input instead of accepting any user input
// ----------------------
#ifdef RERECORDING
Recording::ShutDown();
#endif
// ----------------------
INFO_LOG(PAD, "Shutdown: %i\n", SDL_WasInit(0));
// Always change this variable
g_EmulatorRunning = false;
@ -303,18 +214,7 @@ void Shutdown()
DEBUG_QUIT();
#endif
#ifdef _WIN32
// Free DInput before closing SDL, or get a crash !
FreeDirectInput();
#elif defined(__linux__)
close(fd);
#endif
// Don't shutdown the gamepad if the configuration window is still showing
// Todo: Coordinate with the Wiimote plugin, SDL_Quit() will remove the pad for it to
#if defined(HAVE_WX) && HAVE_WX
if (m_ConfigFrame) return;
#endif
PAD_RumbleClose();
/* Close all devices carefully. We must check that we are not accessing any undefined
vector elements or any bad devices */
@ -335,7 +235,7 @@ void Shutdown()
NumGoodPads = 0;
// Finally close SDL
if (SDL_WasInit(0)) SDL_Quit();
SDL_Quit();
// Remove the pointer to the initialize data
g_PADInitialize = NULL;
@ -364,9 +264,6 @@ void PAD_Input(u16 _Key, u8 _UpDown)
{ PadState[i].dpad2[j] = _UpDown; break; }
}
}
// Debugging
//INFO_LOG(CONSOLE, "%i", _Key);
}
@ -386,25 +283,10 @@ void DoState(unsigned char **ptr, int mode)
// Function: Gives the current pad status to the Core
void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
{
//INFO_LOG(CONSOLE, "PAD_GetStatus(): %i %i %i\n", _numPAD, PadMapping[_numPAD].enabled, PadState[_numPAD].joy);
/* Check if the pad is avaliable, currently we don't disable pads just because they are
disconnected */
// Check if the pad is avaliable, currently we don't disable pads just because they are
// disconnected
if (!PadState[_numPAD].joy) return;
// -------------------------------------------
// Play back input instead of accepting any user input
// ----------------------
#ifdef RERECORDING
if (g_Config.bPlayback)
{
*_pPADStatus = Recording::Play();
return;
}
#endif
// ----------------------
// Clear pad status
memset(_pPADStatus, 0, sizeof(SPADStatus));
@ -543,45 +425,6 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// Update error code
_pPADStatus->err = PAD_ERR_NONE;
// -------------------------------------------
// Rerecording
// ----------------------
#ifdef RERECORDING
// Record input
if (g_Config.bRecording) Recording::RecordInput(*_pPADStatus);
#endif
// ----------------------
// Debugging
/*
// Show the status of all connected pads
ConsoleListener* Console = LogManager::GetInstance()->getConsoleListener();
if ((LastPad == 0 && _numPAD == 0) || _numPAD < LastPad) Console->ClearScreen();
LastPad = _numPAD;
// Console->ClearScreen();
int X = _pPADStatus->stickX - 128, Y = _pPADStatus->stickY - 128;
int Xc = _pPADStatus->substickX - 128, Yc = _pPADStatus->substickY - 128;
NOTICE_LOG(CONSOLE,
"Pad | Number:%i Enabled:%i Handle:%i\n"
"Stick | X:%03i Y:%03i R:%3.0f\n"
"C-Stick | X:%03i Y:%03i R:%3.0f\n"
"Trigger | StatusL:%04x StatusR:%04x TriggerL:%04x TriggerR:%04x TriggerValue:%i\n"
"Buttons | Overall:%i A:%i X:%i\n"
"======================================================\n",
_numPAD, PadMapping[_numPAD].enabled, PadState[_numPAD].joy,
X, Y, sqrt((float)(X*X + Y*Y)),
Xc, Yc, sqrt((float)(Xc*Xc + Yc*Yc)),
_pPADStatus->triggerLeft, _pPADStatus->triggerRight, TriggerLeft, TriggerRight, TriggerValue,
_pPADStatus->button,
PadState[_numPAD].buttons[InputCommon::CTL_A_BUTTON],
PadState[_numPAD].buttons[InputCommon::CTL_X_BUTTON]
);
*/
}
@ -622,37 +465,6 @@ bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_N
}
/* Check if any of the pads failed to open. In Windows there is a strange "IDirectInputDevice2::
SetDataFormat() DirectX error -2147024809" after exactly four SDL_Init() and SDL_Quit() */
// ----------------
bool ReloadDLL()
{
if ( (PadState[0].joy == NULL)
|| (PadState[1].joy == NULL)
|| (PadState[2].joy == NULL)
|| (PadState[3].joy == NULL))
{
// Check if it was an error and not just no pads connected
std::string StrError = SDL_GetError();
if (StrError.find("IDirectInputDevice2") != std::string::npos)
{
// Clear the physical device info
joyinfo.clear();
NumPads = 0;
NumGoodPads = 0;
// Close SDL
if (SDL_WasInit(0)) SDL_Quit();
// Log message
INFO_LOG(CONSOLE, "Error: %s\n", StrError.c_str());
return true;
}
}
return false;
}
// Check if Dolphin is in focus
// ----------------
bool IsFocus()

View file

@ -54,11 +54,18 @@
#if defined(HAVE_WX) && HAVE_WX
#include "GUI/AboutBox.h"
#include "GUI/ConfigBox.h"
//extern ConfigBox* m_frame;
#endif
#ifdef _WIN32
#include <tchar.h>
// 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
@ -66,40 +73,15 @@
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "winmm.lib")
#include <dinput.h>
void FreeDirectInput(); // Needed in both nJoy.cpp and Rumble.cpp
#else
#include <unistd.h>
#include <sys/ioctl.h>
#endif
#endif
#ifdef __linux__
#include <linux/input.h>
#endif
// Define
// ----------
#define INPUT_VERSION "0.3"
#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("nJoy v")wxT(INPUT_VERSION)wxT(" by Falcon4ever\nRelease: ") RELDAY wxT("/") RELMONTH wxT("/") RELYEAR wxT("\nwww.multigesture.net")
// Input vector. Todo: Save the configured keys here instead of in joystick
// ---------
/*
#ifndef _CONTROLLER_STATE_H
extern std::vector<u8> Keys;
#endif
*/
#define PLUGIN_VER_STR wxT("Based on nJoy 0.3 by Falcon4ever\nRelease: ") RELDAY wxT("/") RELMONTH wxT("/") RELYEAR wxT("\nwww.multigesture.net")
// Variables
@ -117,8 +99,6 @@ extern std::vector<u8> Keys;
#endif
// Custom Functions
// ----------------
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads);
@ -126,29 +106,5 @@ void DEBUG_INIT();
void DEBUG_QUIT();
bool IsFocus();
bool ReloadDLL();
#ifdef _WIN32
HRESULT InitRumble(HWND hWnd);
#endif
// ReRecording
// ----------------
#ifdef RERECORDING
namespace Recording
{
void Initialize();
void DoState(unsigned char **ptr, int mode);
void ShutDown();
void Save();
void Load();
const SPADStatus& Play();
void RecordInput(const SPADStatus& _rPADStatus);
}
#endif
void PAD_RumbleClose();
#endif // __NJOY_h__