diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.cpp index 0b7326871a..bf88c4103a 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.cpp @@ -213,12 +213,12 @@ SetTitle(wxT("Sound Debugging")); // Basic settings SetIcon(wxNullIcon); - SetSize(8, 8, 200, 100); // these will become the minimin sizes allowed by resizing + SetSize(8, 8, 200, 100); // These will become the minimin sizes allowed by resizing Center(); // Declarations - wxBoxSizer * sMAIN, * sMain, *_sMail, * sBlock; + wxBoxSizer * m_MainSizer, * sMain, *_sMail, * sBlock; wxButton* m_Upd; wxButton* m_SelC; @@ -511,16 +511,16 @@ SetTitle(wxT("Sound Debugging")); // -------------------------------------------------------------------- // Main containers // ----------------------------- - sMAIN = new wxBoxSizer(wxVERTICAL); - sMAIN->Add(m_Notebook, 1, wxEXPAND | wxALL, 5); - //sMAIN->SetSizeHints(this); + m_MainSizer = new wxBoxSizer(wxVERTICAL); + m_MainSizer->Add(m_Notebook, 1, wxEXPAND | wxALL, 5); + //m_MainSizer->SetSizeHints(this); m_PageMain->SetSizer(sMain); m_PageMail->SetSizer(_sMail); m_PageBlock->SetSizer(sBlock); //sMain->Layout(); - this->SetSizer(sMAIN); + this->SetSizer(m_MainSizer); //this->Layout(); NotifyUpdate(); diff --git a/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj b/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj index db213f4e7b..9659dd6bf5 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj +++ b/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj @@ -501,6 +501,10 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + @@ -509,6 +513,10 @@ RelativePath=".\Src\nJoy.h" > + + + + diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp new file mode 100644 index 0000000000..521f5dcbec --- /dev/null +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp @@ -0,0 +1,156 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// Project description +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003-2008 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" + + + +// 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 v"INPUT_VERSION" 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 SaveConfig() +{ + IniFile file; + file.Load("nJoy.ini"); + + for (int i = 0; i < 4; i++) + { + char SectionName[32]; + sprintf(SectionName, "PAD%i", i+1); + + file.Set(SectionName, "l_shoulder", joysticks[i].buttons[CTL_L_SHOULDER]); + file.Set(SectionName, "r_shoulder", joysticks[i].buttons[CTL_R_SHOULDER]); + file.Set(SectionName, "a_button", joysticks[i].buttons[CTL_A_BUTTON]); + file.Set(SectionName, "b_button", joysticks[i].buttons[CTL_B_BUTTON]); + file.Set(SectionName, "x_button", joysticks[i].buttons[CTL_X_BUTTON]); + file.Set(SectionName, "y_button", joysticks[i].buttons[CTL_Y_BUTTON]); + file.Set(SectionName, "z_trigger", joysticks[i].buttons[CTL_Z_TRIGGER]); + file.Set(SectionName, "start_button", joysticks[i].buttons[CTL_START]); + file.Set(SectionName, "dpad", joysticks[i].dpad); + file.Set(SectionName, "dpad_up", joysticks[i].dpad2[CTL_D_PAD_UP]); + file.Set(SectionName, "dpad_down", joysticks[i].dpad2[CTL_D_PAD_DOWN]); + file.Set(SectionName, "dpad_left", joysticks[i].dpad2[CTL_D_PAD_LEFT]); + file.Set(SectionName, "dpad_right", joysticks[i].dpad2[CTL_D_PAD_RIGHT]); + file.Set(SectionName, "main_x", joysticks[i].axis[CTL_MAIN_X]); + file.Set(SectionName, "main_y", joysticks[i].axis[CTL_MAIN_Y]); + file.Set(SectionName, "sub_x", joysticks[i].axis[CTL_SUB_X]); + file.Set(SectionName, "sub_y", joysticks[i].axis[CTL_SUB_Y]); + file.Set(SectionName, "enabled", joysticks[i].enabled); + file.Set(SectionName, "deadzone", joysticks[i].deadzone); + file.Set(SectionName, "halfpress", joysticks[i].halfpress); + file.Set(SectionName, "joy_id", joysticks[i].ID); + file.Set(SectionName, "controllertype", joysticks[i].controllertype); + file.Set(SectionName, "eventnum", joysticks[i].eventnum); + } + + file.Save("nJoy.ini"); +} + +// Load settings from file +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void LoadConfig() +{ + IniFile file; + file.Load("nJoy.ini"); + + for (int i = 0; i < 4; i++) + { + char SectionName[32]; + sprintf(SectionName, "PAD%i", i+1); + + file.Get(SectionName, "l_shoulder", &joysticks[i].buttons[CTL_L_SHOULDER], 4); + file.Get(SectionName, "r_shoulder", &joysticks[i].buttons[CTL_R_SHOULDER], 5); + file.Get(SectionName, "a_button", &joysticks[i].buttons[CTL_A_BUTTON], 0); + file.Get(SectionName, "b_button", &joysticks[i].buttons[CTL_B_BUTTON], 1); + file.Get(SectionName, "x_button", &joysticks[i].buttons[CTL_X_BUTTON], 3); + file.Get(SectionName, "y_button", &joysticks[i].buttons[CTL_Y_BUTTON], 2); + file.Get(SectionName, "z_trigger", &joysticks[i].buttons[CTL_Z_TRIGGER], 7); + file.Get(SectionName, "start_button", &joysticks[i].buttons[CTL_START], 9); + file.Get(SectionName, "dpad", &joysticks[i].dpad, 0); + file.Get(SectionName, "dpad_up", &joysticks[i].dpad2[CTL_D_PAD_UP], 0); + file.Get(SectionName, "dpad_down", &joysticks[i].dpad2[CTL_D_PAD_DOWN], 0); + file.Get(SectionName, "dpad_left", &joysticks[i].dpad2[CTL_D_PAD_LEFT], 0); + file.Get(SectionName, "dpad_right", &joysticks[i].dpad2[CTL_D_PAD_RIGHT], 0); + file.Get(SectionName, "main_x", &joysticks[i].axis[CTL_MAIN_X], 0); + file.Get(SectionName, "main_y", &joysticks[i].axis[CTL_MAIN_Y], 1); + file.Get(SectionName, "sub_x", &joysticks[i].axis[CTL_SUB_X], 2); + file.Get(SectionName, "sub_y", &joysticks[i].axis[CTL_SUB_Y], 3); + file.Get(SectionName, "enabled", &joysticks[i].enabled, 1); + file.Get(SectionName, "deadzone", &joysticks[i].deadzone, 9); + file.Get(SectionName, "halfpress", &joysticks[i].halfpress, 6); + file.Get(SectionName, "joy_id", &joysticks[i].ID, 0); + file.Get(SectionName, "controllertype", &joysticks[i].controllertype, 0); + file.Get(SectionName, "eventnum", &joysticks[i].eventnum, 0); + } +} + diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp new file mode 100644 index 0000000000..c4dc2acafd --- /dev/null +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp @@ -0,0 +1,133 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// Include +// ŻŻŻŻŻŻŻŻŻ +#include "ConfigBox.h" +#include "../nJoy.h" +#include "Images/controller.xpm" + +extern CONTROLLER_INFO *joyinfo; +extern bool emulator_running; +//////////////////////// + +int main_stick_x = 0; + +// Set PAD status +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void ConfigBox::PadGetStatus() +{ + // + int _numPAD = 0; + + if (!joysticks[_numPAD].enabled) + return; + + // Clear pad status + //memset(_pPADStatus, 0, sizeof(SPADStatus)); + + + // Get pad status + GetJoyState(_numPAD); + + // Reset! + /* + int base = 0x80; + _pPADStatus->stickY = base; + _pPADStatus->stickX = base; + _pPADStatus->substickX = base; + _pPADStatus->substickY = base; + _pPADStatus->button |= PAD_USE_ORIGIN; + */ + + // Set analog controllers + // Set Deadzones perhaps out of function + //int deadzone = (int)(((float)(128.00/100.00)) * (float)(joysticks[_numPAD].deadzone+1)); + //int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(joysticks[_numPAD].deadzone+1)); + + // Adjust range + // The value returned by SDL_JoystickGetAxis is a signed integer (-32768 to 32768) + // The value used for the gamecube controller is an unsigned char (0 to 255) + int main_stick_x = (joystate[_numPAD].axis[CTL_MAIN_X] >> 8); + int main_stick_y = -(joystate[_numPAD].axis[CTL_MAIN_Y] >> 8); + //int sub_stick_x = (joystate[_numPAD].axis[CTL_SUB_X] >> 8); + //int sub_stick_y = -(joystate[_numPAD].axis[CTL_SUB_Y] >> 8); + + + if (joystate[_numPAD].buttons[CTL_A_BUTTON]) + { + PanicAlert(""); + //_pPADStatus->button |= PAD_BUTTON_A; + //_pPADStatus->analogA = 255; // Perhaps support pressure? + for(int i=0; i<4 ;i++) + { + m_bmpDot[i]->SetPosition(wxPoint(main_stick_x += 3, main_stick_y)); + } + } + + for(int i=0; i<4 ;i++) + { + //m_bmpDot[i]->SetPosition(wxPoint(main_stick_x / 4, main_stick_y / 4)); + } +} + +// Populate the advanced tab +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void ConfigBox::Update() +{ + //PadGetStatus(); +} + + +// Populate the advanced tab +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void ConfigBox::CreateAdvancedControls(int i) +{ + m_pInStatus[i] = new wxPanel(m_Notebook, 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(40, 40), wxDefaultSize); +} + + +wxBitmap ConfigBox::CreateBitmap() // Create box +{ + int w = 70, h = 70; + wxBitmap bitmap(w, h); + wxMemoryDC dc; + dc.SelectObject(bitmap); + + // Set outline and fill colors + wxBrush LightBlueBrush(_T("#0383f0")); + wxPen LightBluePen(_T("#80c5fd")); + wxPen LightGrayPen(_T("#909090")); + dc.SetPen(LightGrayPen); + dc.SetBrush(*wxWHITE_BRUSH); + + dc.Clear(); + dc.DrawRectangle(0, 0, w, h); + dc.SelectObject(wxNullBitmap); + return bitmap; +} + +wxBitmap ConfigBox::CreateBitmapDot() // Create dot +{ + int w = 2, h = 2; + wxBitmap bitmap(w, h); + wxMemoryDC dc; + dc.SelectObject(bitmap); + + // Set outline and fill colors + wxBrush LightBlueBrush(_T("#0383f0")); + wxPen LightBluePen(_T("#80c5fd")); + wxPen LightGrayPen(_T("#909090")); + dc.SetPen(LightGrayPen); + dc.SetBrush(*wxWHITE_BRUSH); + + dc.Clear(); + dc.DrawRectangle(0, 0, w, h); + dc.SelectObject(wxNullBitmap); + return bitmap; +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp index 47c3d28517..87b41d5b1f 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp @@ -29,12 +29,16 @@ // ////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////// +// Include +// ŻŻŻŻŻŻŻŻŻ #include "ConfigBox.h" #include "../nJoy.h" #include "Images/controller.xpm" extern CONTROLLER_INFO *joyinfo; -extern CONTROLLER_MAPPING joysticks[4]; +//extern CONTROLLER_MAPPING joysticks[4]; extern bool emulator_running; static const char* ControllerType[] = @@ -44,7 +48,12 @@ static const char* ControllerType[] = // "Joytstick (xbox360)", // Shoulder buttons -> axis // "Keyboard" // Not supported yet, sorry F|RES ;( ... }; +//////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////// +// The wxWidgets class +// ŻŻŻŻŻŻŻ BEGIN_EVENT_TABLE(ConfigBox,wxDialog) EVT_CLOSE(ConfigBox::OnClose) EVT_BUTTON(ID_ABOUT, ConfigBox::AboutClick) @@ -72,21 +81,50 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog) EVT_BUTTON(IDB_ANALOG_MAIN_Y, ConfigBox::GetAxis) EVT_BUTTON(IDB_ANALOG_SUB_X, ConfigBox::GetAxis) EVT_BUTTON(IDB_ANALOG_SUB_Y, ConfigBox::GetAxis) + + #if wxUSE_TIMER + EVT_TIMER(wxID_ANY, ConfigBox::OnTimer) + #endif END_EVENT_TABLE() -ConfigBox::ConfigBox(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style) -: wxDialog(parent, id, title, position, size, style) +ConfigBox::ConfigBox(wxWindow *parent, wxWindowID id, const wxString &title, + const wxPoint &position, const wxSize& size, long style) + : wxDialog(parent, id, title, position, size, style) + #if wxUSE_TIMER + , m_timer(this) + #endif { notebookpage = 0; CreateGUIControls(); + + #if wxUSE_TIMER + m_timer.Start(1000); + #endif } ConfigBox::~ConfigBox() { // empty } +////////////////////////////////// -// Warning: horrible code below proceed at own risk! + +// Populate the config window +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void ConfigBox::OnPaint( wxPaintEvent &event ) +{ + event.Skip(); + + for(int i=0; i<4 ;i++) + { + wxPaintDC dcWin(m_pKeys[i]); + PrepareDC( dcWin ); + dcWin.DrawBitmap( WxStaticBitmap1_BITMAP, 94, 0, true ); + } +} + +// Populate the config window +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void ConfigBox::CreateGUIControls() { #ifndef _DEBUG @@ -95,9 +133,13 @@ void ConfigBox::CreateGUIControls() SetTitle(wxT("Configure: nJoy v"INPUT_VERSION" (Debug) Input Plugin")); #endif - SetIcon(wxNullIcon); - SetClientSize(637, 527); - Center(); + SetIcon(wxNullIcon); + + //WxStaticBitmap1_BITMAP(ConfigBox_WxStaticBitmap1_XPM); + + + + //WxStaticBitmap1_BITMAP = new WxStaticBitmap1_BITMAP(ConfigBox_WxStaticBitmap1_XPM); #ifndef _WIN32 // Force a 8pt font so that it looks more or less "correct" regardless of the default font setting @@ -106,28 +148,28 @@ void ConfigBox::CreateGUIControls() #endif // Buttons - m_About = new wxButton(this, ID_ABOUT, wxT("About"), wxPoint(5, 497), wxSize(75, 25), 0, wxDefaultValidator, wxT("About")); - m_OK = new wxButton(this, ID_OK, wxT("OK"), wxPoint(475, 497), wxSize(75, 25), 0, wxDefaultValidator, wxT("OK")); - m_Cancel = new wxButton(this, ID_CANCEL, wxT("Cancel"), wxPoint(556, 497), wxSize(75, 25), 0, wxDefaultValidator, wxT("Cancel")); + m_About = new wxButton(this, ID_ABOUT, wxT("About"), wxDefaultPosition, wxSize(75, 25), 0, wxDefaultValidator, wxT("About")); + m_OK = new wxButton(this, ID_OK, wxT("OK"), wxDefaultPosition, wxSize(75, 25), 0, wxDefaultValidator, wxT("OK")); + m_Cancel = new wxButton(this, ID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(75, 25), 0, wxDefaultValidator, wxT("Cancel")); // Notebook - m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxPoint(6, 7),wxSize(625, 484)); + m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); // Controller pages - m_Controller[0] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE1, wxPoint(0, 0), wxSize(600, 400)); + m_Controller[0] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE1, wxDefaultPosition, wxDefaultSize); m_Notebook->AddPage(m_Controller[0], wxT("Controller 1")); - m_Controller[1] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE2, wxPoint(0, 0), wxSize(600, 400)); + m_Controller[1] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE2, wxDefaultPosition, wxDefaultSize); m_Notebook->AddPage(m_Controller[1], wxT("Controller 2")); - m_Controller[2] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE3, wxPoint(0, 0), wxSize(600, 400)); + m_Controller[2] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE3, wxDefaultPosition, wxDefaultSize); m_Notebook->AddPage(m_Controller[2], wxT("Controller 3")); - m_Controller[3] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE4, wxPoint(0, 0), wxSize(600, 400)); + m_Controller[3] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE4, wxDefaultPosition, wxDefaultSize); m_Notebook->AddPage(m_Controller[3], wxT("Controller 4")); // Add controls wxArrayString arrayStringFor_Joyname; wxArrayString arrayStringFor_Controltype; wxArrayString arrayStringFor_Deadzone; - + // Search for devices and add the to the device list if(Search_Devices()) { @@ -152,118 +194,204 @@ void ConfigBox::CreateGUIControls() sprintf (buffer, "%d %%", x); arrayStringFor_Deadzone.Add(wxString::FromAscii(buffer)); } + + // Define bitmap for EVT_PAINT + WxStaticBitmap1_BITMAP = wxBitmap(ConfigBox_WxStaticBitmap1_XPM); + - wxBitmap WxStaticBitmap1_BITMAP(ConfigBox_WxStaticBitmap1_XPM); - + // Populate all four pages for(int i=0; i<4 ;i++) { + // -------------------------------------------------------------------- + // Populate keys sizer + // ----------------------------- + // Set relative values for the keys + int t = -75; // Top + int l = -4; // Left + m_sKeys[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Keys")); + m_pKeys[i] = new wxPanel(m_Controller[i], ID_KEYSPANEL1 + i, wxDefaultPosition, wxSize(600, 400)); + //m_sKeys[i] = new wxStaticBox (m_Controller[i], IDG_JOYSTICK, wxT("Keys"), wxDefaultPosition, wxSize(608, 500)); + m_sKeys[i]->Add(m_pKeys[i], 0, (wxALL), 0); // margin = 0 - // Groups - m_gJoyname[i] = new wxStaticBox(m_Controller[i], IDG_JOYSTICK, wxT("Controller:"), wxPoint(5, 11), wxSize(608, 46)); - - #ifdef _WIN32 - m_Joyattach[i] = new wxCheckBox(m_Controller[i], IDC_JOYATTACH, wxT("Controller attached"), wxPoint(495, 26), wxSize(109, 25), 0, wxDefaultValidator, wxT("Controller attached")); - m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, wxEmptyString, wxPoint(12, 29), wxSize(476, 21), arrayStringFor_Joyname, 0, wxDefaultValidator, wxT("m_Joyname")); - m_gExtrasettings[i] = new wxStaticBox(m_Controller[i], IDG_EXTRASETTINGS, wxT("Extra settings:"), wxPoint(104, 385), wxSize(155, 69)); - m_Deadzone[i] = new wxComboBox(m_Controller[i], IDC_DEADZONE, wxEmptyString, wxPoint(167, 400), wxSize(59, 21), arrayStringFor_Deadzone, 0, wxDefaultValidator, wxT("m_Deadzone")); - m_gControllertype[i] = new wxStaticBox(m_Controller[i], IDG_CONTROLLERTYPE, wxT("Controller type:"), wxPoint(359, 383), wxSize(143, 44)); - m_Controltype[i] = new wxComboBox(m_Controller[i], IDC_CONTROLTYPE, wxEmptyString, wxPoint(366, 401), wxSize(131, 21), arrayStringFor_Controltype, 0, wxDefaultValidator, wxT("m_Controltype")); - #else - m_Joyattach[i] = new wxCheckBox(m_Controller[i], IDC_JOYATTACH, wxT("Controller attached"), wxPoint(470, 26), wxSize(140, 25), 0, wxDefaultValidator, wxT("Controller attached")); - m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, wxEmptyString, wxPoint(10, 25), wxSize(450, 25), arrayStringFor_Joyname, 0, wxDefaultValidator, wxT("m_Joyname")); - m_gExtrasettings[i] = new wxStaticBox(m_Controller[i], IDG_EXTRASETTINGS, wxT("Extra settings:"), wxPoint(100, 385), wxSize(155, 65)); - m_Deadzone[i] = new wxComboBox(m_Controller[i], IDC_DEADZONE, wxEmptyString, wxPoint(167, 398), wxSize(80, 25), arrayStringFor_Deadzone, 0, wxDefaultValidator, wxT("m_Deadzone")); - m_gControllertype[i] = new wxStaticBox(m_Controller[i], IDG_CONTROLLERTYPE, wxT("Controller type:"), wxPoint(359, 383), wxSize(160, 44)); - m_Controltype[i] = new wxComboBox(m_Controller[i], IDC_CONTROLTYPE, wxEmptyString, wxPoint(364, 396), wxSize(150, 25), arrayStringFor_Controltype, 0, wxDefaultValidator, wxT("m_Controltype")); - #endif - - // GUI left side buttons - m_JoyShoulderL[i] = new wxTextCtrl(m_Controller[i], ID_SHOULDER_L, wxT("0"), wxPoint(6, 80), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyShoulderL[i]->Enable(false); - m_JoyAnalogMainX[i] = new wxTextCtrl(m_Controller[i], ID_ANALOG_MAIN_X, wxT("0"), wxPoint(6, 218), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyAnalogMainX[i]->Enable(false); - m_JoyAnalogMainY[i] = new wxTextCtrl(m_Controller[i], ID_ANALOG_MAIN_Y, wxT("0"), wxPoint(6, 255), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyAnalogMainY[i]->Enable(false); - m_JoyDpadUp[i] = new wxTextCtrl(m_Controller[i], ID_DPAD_UP, wxT("0"), wxPoint(6, 296), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyDpadUp[i]->Enable(false); - m_JoyDpadDown[i] = new wxTextCtrl(m_Controller[i], ID_DPAD_DOWN, wxT("0"), wxPoint(6, 333), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyDpadDown[i]->Enable(false); - m_JoyDpadLeft[i] = new wxTextCtrl(m_Controller[i], ID_DPAD_LEFT, wxT("0"), wxPoint(6, 369), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyDpadLeft[i]->Enable(false); - m_JoyDpadRight[i] = new wxTextCtrl(m_Controller[i], ID_DPAD_RIGHT, wxT("0"), wxPoint(6, 406), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyDpadRight[i]->Enable(false); - m_bJoyShoulderL[i] = new wxButton(m_Controller[i], IDB_SHOULDER_L, wxEmptyString, wxPoint(70, 82), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyAnalogMainX[i] = new wxButton(m_Controller[i], IDB_ANALOG_MAIN_X, wxEmptyString, wxPoint(70, 220), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyAnalogMainY[i] = new wxButton(m_Controller[i], IDB_ANALOG_MAIN_Y, wxEmptyString, wxPoint(70, 257), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyDpadUp[i] = new wxButton(m_Controller[i], IDB_DPAD_UP, wxEmptyString, wxPoint(70, 298), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyDpadDown[i] = new wxButton(m_Controller[i], IDB_DPAD_DOWN, wxEmptyString, wxPoint(70, 335), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyDpadLeft[i] = new wxButton(m_Controller[i], IDB_DPAD_LEFT, wxEmptyString, wxPoint(70, 371), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyDpadRight[i] = new wxButton(m_Controller[i], IDB_DPAD_RIGHT, wxEmptyString, wxPoint(70, 408), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - - m_textMainX[i] = new wxStaticText(m_Controller[i], IDT_ANALOG_MAIN_X, wxT("X-axis"), wxPoint(6, 204), wxDefaultSize, 0, wxT("X-axis")); - m_textMainY[i] = new wxStaticText(m_Controller[i], IDT_ANALOG_MAIN_Y, wxT("Y-axis"), wxPoint(6, 241), wxDefaultSize, 0, wxT("Y-axis")); - m_textDpadUp[i] = new wxStaticText(m_Controller[i], IDT_DPAD_UP, wxT("Up"), wxPoint(6, 282), wxDefaultSize, 0, wxT("Up")); - m_textDpadDown[i] = new wxStaticText(m_Controller[i], IDT_DPAD_DOWN, wxT("Down"), wxPoint(6, 319), wxDefaultSize, 0, wxT("Down")); - m_textDpadLeft[i] = new wxStaticText(m_Controller[i], IDT_DPAD_LEFT, wxT("Left"), wxPoint(6, 354), wxDefaultSize, 0, wxT("Left")); - m_textDpadRight[i] = new wxStaticText(m_Controller[i], IDT_DPAD_RIGHT, wxT("Right"), wxPoint(6, 391), wxDefaultSize, 0, wxT("Right")); - - // GUI right side buttons - m_JoyShoulderR[i] = new wxTextCtrl(m_Controller[i], ID_SHOULDER_R, wxT("0"), wxPoint(552, 106), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyShoulderR[i]->Enable(false); - m_JoyButtonA[i] = new wxTextCtrl(m_Controller[i], ID_BUTTON_A, wxT("0"), wxPoint(552, 280), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyButtonA[i]->Enable(false); - m_JoyButtonB[i] = new wxTextCtrl(m_Controller[i], ID_BUTTON_B, wxT("0"), wxPoint(552, 80), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyButtonB[i]->Enable(false); - m_JoyButtonX[i] = new wxTextCtrl(m_Controller[i], ID_BUTTON_X, wxT("0"), wxPoint(552, 242), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyButtonX[i]->Enable(false); - m_JoyButtonY[i] = new wxTextCtrl(m_Controller[i], ID_BUTTON_Y, wxT("0"), wxPoint(552, 171), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyButtonY[i]->Enable(false); - m_JoyButtonZ[i] = new wxTextCtrl(m_Controller[i], ID_BUTTON_Z, wxT("0"), wxPoint(552, 145), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyButtonZ[i]->Enable(false); - m_JoyAnalogSubX[i] = new wxTextCtrl(m_Controller[i], ID_ANALOG_SUB_X, wxT("0"), wxPoint(552, 351), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyAnalogSubX[i]->Enable(false); - m_JoyAnalogSubY[i] = new wxTextCtrl(m_Controller[i], ID_ANALOG_SUB_Y, wxT("0"), wxPoint(552, 388), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyAnalogSubY[i]->Enable(false); - m_bJoyShoulderR[i] = new wxButton(m_Controller[i], IDB_SHOULDER_R, wxEmptyString, wxPoint(526, 108), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyButtonA[i] = new wxButton(m_Controller[i], IDB_BUTTON_A, wxEmptyString, wxPoint(526, 282), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyButtonB[i] = new wxButton(m_Controller[i], IDB_BUTTON_B, wxEmptyString, wxPoint(526, 82), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyButtonX[i] = new wxButton(m_Controller[i], IDB_BUTTON_X, wxEmptyString, wxPoint(526, 244), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyButtonY[i] = new wxButton(m_Controller[i], IDB_BUTTON_Y, wxEmptyString, wxPoint(526, 173), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyButtonZ[i] = new wxButton(m_Controller[i], IDB_BUTTON_Z, wxEmptyString, wxPoint(526, 147), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyAnalogSubX[i] = new wxButton(m_Controller[i], IDB_ANALOG_SUB_X, wxEmptyString, wxPoint(526, 353), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyAnalogSubY[i] = new wxButton(m_Controller[i], IDB_ANALOG_SUB_Y, wxEmptyString, wxPoint(526, 390), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - - m_textSubX[i] = new wxStaticText(m_Controller[i], IDT_ANALOG_SUB_X, wxT("X-axis"), wxPoint(552, 336), wxDefaultSize, 0, wxT("X-axis")); - m_textSubY[i] = new wxStaticText(m_Controller[i], IDT_ANALOG_SUB_Y, wxT("Y-axis"), wxPoint(552, 373), wxDefaultSize, 0, wxT("Y-axis")); - - // GUI center button - m_JoyButtonStart[i] = new wxTextCtrl(m_Controller[i], ID_BUTTONSTART, wxT("0"), wxPoint(278, 403), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyButtonStart[i]->Enable(false); - m_JoyButtonHalfpress[i] = new wxTextCtrl(m_Controller[i], ID_BUTTONHALFPRESS, wxT("0"), wxPoint(167, 424), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); - m_JoyButtonHalfpress[i]->Enable(false); - m_bJoyButtonStart[i] = new wxButton(m_Controller[i], IDB_BUTTONSTART, wxEmptyString, wxPoint(297, 385), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - m_bJoyButtonHalfpress[i] = new wxButton(m_Controller[i], IDB_BUTTONHALFPRESS, wxEmptyString, wxPoint(231, 426), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); - - #ifdef _WIN32 - m_textDeadzone[i] = new wxStaticText(m_Controller[i], IDT_DEADZONE, wxT("Deadzone"), wxPoint(116, 404), wxDefaultSize, 0, wxT("Deadzone")); - m_textHalfpress[i] = new wxStaticText(m_Controller[i], IDT_BUTTONHALFPRESS, wxT("Half press"), wxPoint(116, 428), wxDefaultSize, 0, wxT("Half press")); - m_textWebsite[i] = new wxStaticText(m_Controller[i], IDT_WEBSITE, wxT("www.multigesture.net"), wxPoint(500, 438), wxDefaultSize, 0, wxT("www.multigesture.net")); - #else - m_textDeadzone[i] = new wxStaticText(m_Controller[i], IDT_DEADZONE, wxT("Deadzone"), wxPoint(105, 404), wxDefaultSize, 0, wxT("Deadzone")); - m_textHalfpress[i] = new wxStaticText(m_Controller[i], IDT_BUTTONHALFPRESS, wxT("Half press"), wxPoint(105, 428), wxDefaultSize, 0, wxT("Half press")); - m_textWebsite[i] = new wxStaticText(m_Controller[i], IDT_WEBSITE, wxT("www.multigesture.net"), wxPoint(480, 438), wxDefaultSize, 0, wxT("www.multigesture.net")); - #endif - + // -------------------------------------------------------------------- + // GameCube controller picture + // ----------------------------- // TODO: Controller image // Placeholder instead of bitmap // m_PlaceholderBMP[i] = new wxTextCtrl(m_Controller[i], ID_CONTROLLERPICTURE, wxT("BITMAP HERE PLZ KTHX!"), wxPoint(98, 75), wxSize(423, 306), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("BITMAP HERE PLZ KTHX!")); // m_PlaceholderBMP[i]->Enable(false); - // You can enable the bitmap here: - // But it loads überslow on init... (only in windows, linux seems to load it fast!) - // AAaaand the XPM file (256 colours) looks crappier than the real bitmap... so maybe we can find a way to use a bitmap? - m_controllerimage[i] = new wxStaticBitmap(m_Controller[i], ID_CONTROLLERPICTURE, WxStaticBitmap1_BITMAP, wxPoint(98, 75), wxSize(421,304)); + /* You can enable the bitmap here. But it loads überslow on init... (only in windows, linux + seems to load it fast!) AAaaand the XPM file (256 colours) looks crappier than the real bitmap... + so maybe we can find a way to use a bitmap? */ + //m_controllerimage[i] = new wxStaticBitmap(m_pKeys[i], ID_CONTROLLERPICTURE, WxStaticBitmap1_BITMAP, wxPoint(l + 98, t + 75), wxSize(421,304)); + //m_controllerimage[i] = new wxBitmap( WxStaticBitmap1_BITMAP ); + + // Paint background. This allows objects to be visible on top of the picture + m_pKeys[i]->Connect(wxID_ANY, wxEVT_PAINT, + wxPaintEventHandler(ConfigBox::OnPaint), + (wxObject*)0, this); + + + // -------------------------------------------------------------------- + // Keys objects + // ----------------------------- + // Left shoulder + m_JoyShoulderL[i] = new wxTextCtrl(m_pKeys[i], ID_SHOULDER_L, wxT("0"), wxPoint(l + 6, t + 80), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyShoulderL[i]->Enable(false); + m_bJoyShoulderL[i] = new wxButton(m_pKeys[i], IDB_SHOULDER_L, wxEmptyString, wxPoint(l + 70, t + 82), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + + // Left analog + int ALt = 170; int ALw = ALt + 14; int ALb = ALw + 2; // Set offset + m_JoyAnalogMainX[i] = new wxTextCtrl(m_pKeys[i], ID_ANALOG_MAIN_X, wxT("0"), wxPoint(l + 6, t + ALw), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyAnalogMainX[i]->Enable(false); + m_JoyAnalogMainY[i] = new wxTextCtrl(m_pKeys[i], ID_ANALOG_MAIN_Y, wxT("0"), wxPoint(l + 6, t + ALw + 36), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyAnalogMainY[i]->Enable(false); + m_bJoyAnalogMainX[i] = new wxButton(m_pKeys[i], IDB_ANALOG_MAIN_X, wxEmptyString, wxPoint(l + 70, t + ALb), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyAnalogMainY[i] = new wxButton(m_pKeys[i], IDB_ANALOG_MAIN_Y, wxEmptyString, wxPoint(l + 70, t + ALb + 36), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_textMainX[i] = new wxStaticText(m_pKeys[i], IDT_ANALOG_MAIN_X, wxT("X-axis"), wxPoint(l + 6, t + ALt), wxDefaultSize, 0, wxT("X-axis")); + m_textMainY[i] = new wxStaticText(m_pKeys[i], IDT_ANALOG_MAIN_Y, wxT("Y-axis"), wxPoint(l + 6, t + ALt + 36), wxDefaultSize, 0, wxT("Y-axis")); + // D-Pad + int DPt = 255; int DPw = DPt + 14; int DPb = DPw + 2; // Set offset + m_JoyDpadUp[i] = new wxTextCtrl(m_pKeys[i], ID_DPAD_UP, wxT("0"), wxPoint(l + 6, t + DPw), wxSize(59, t + 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyDpadUp[i]->Enable(false); + m_JoyDpadDown[i] = new wxTextCtrl(m_pKeys[i], ID_DPAD_DOWN, wxT("0"), wxPoint(l + 6, t + DPw + 36*1), wxSize(59, t + 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyDpadDown[i]->Enable(false); + m_JoyDpadLeft[i] = new wxTextCtrl(m_pKeys[i], ID_DPAD_LEFT, wxT("0"), wxPoint(l + 6, t + DPw + 36*2), wxSize(59, t + 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyDpadLeft[i]->Enable(false); + m_JoyDpadRight[i] = new wxTextCtrl(m_pKeys[i], ID_DPAD_RIGHT, wxT("0"), wxPoint(l + 6, t + DPw + 36*3), wxSize(59, t + 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyDpadRight[i]->Enable(false); + m_bJoyDpadUp[i] = new wxButton(m_pKeys[i], IDB_DPAD_UP, wxEmptyString, wxPoint(l + 70, t + DPb + 36*0), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyDpadDown[i] = new wxButton(m_pKeys[i], IDB_DPAD_DOWN, wxEmptyString, wxPoint(l + 70, t + DPb + 36*1), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyDpadLeft[i] = new wxButton(m_pKeys[i], IDB_DPAD_LEFT, wxEmptyString, wxPoint(l + 70, t + DPb + 36*2), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyDpadRight[i] = new wxButton(m_pKeys[i], IDB_DPAD_RIGHT, wxEmptyString, wxPoint(l + 70, t + DPb + 36*3), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_textDpadUp[i] = new wxStaticText(m_pKeys[i], IDT_DPAD_UP, wxT("Up"), wxPoint(l + 6, t + DPt + 36*0), wxDefaultSize, 0, wxT("Up")); + m_textDpadDown[i] = new wxStaticText(m_pKeys[i], IDT_DPAD_DOWN, wxT("Down"), wxPoint(l + 6, t + DPt + 36*1), wxDefaultSize, 0, wxT("Down")); + m_textDpadLeft[i] = new wxStaticText(m_pKeys[i], IDT_DPAD_LEFT, wxT("Left"), wxPoint(l + 6, t + DPt + 36*2), wxDefaultSize, 0, wxT("Left")); + m_textDpadRight[i] = new wxStaticText(m_pKeys[i], IDT_DPAD_RIGHT, wxT("Right"), wxPoint(l + 6, t + DPt + 36*3), wxDefaultSize, 0, wxT("Right")); + + // Right side buttons + m_JoyShoulderR[i] = new wxTextCtrl(m_pKeys[i], ID_SHOULDER_R, wxT("0"), wxPoint(l + 552, t + 106), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyShoulderR[i]->Enable(false); + m_JoyButtonA[i] = new wxTextCtrl(m_pKeys[i], ID_BUTTON_A, wxT("0"), wxPoint(l + 552, t + 280), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyButtonA[i]->Enable(false); + m_JoyButtonB[i] = new wxTextCtrl(m_pKeys[i], ID_BUTTON_B, wxT("0"), wxPoint(l + 552, t + 80), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyButtonB[i]->Enable(false); + m_JoyButtonX[i] = new wxTextCtrl(m_pKeys[i], ID_BUTTON_X, wxT("0"), wxPoint(l + 552, t + 242), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyButtonX[i]->Enable(false); + m_JoyButtonY[i] = new wxTextCtrl(m_pKeys[i], ID_BUTTON_Y, wxT("0"), wxPoint(l + 552, t + 171), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyButtonY[i]->Enable(false); + m_JoyButtonZ[i] = new wxTextCtrl(m_pKeys[i], ID_BUTTON_Z, wxT("0"), wxPoint(l + 552, t + 145), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyButtonZ[i]->Enable(false); + m_bJoyShoulderR[i] = new wxButton(m_pKeys[i], IDB_SHOULDER_R, wxEmptyString, wxPoint(l + 526, t + 108), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyButtonA[i] = new wxButton(m_pKeys[i], IDB_BUTTON_A, wxEmptyString, wxPoint(l + 526, t + 282), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyButtonB[i] = new wxButton(m_pKeys[i], IDB_BUTTON_B, wxEmptyString, wxPoint(l + 526, t + 82), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyButtonX[i] = new wxButton(m_pKeys[i], IDB_BUTTON_X, wxEmptyString, wxPoint(l + 526, t + 244), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyButtonY[i] = new wxButton(m_pKeys[i], IDB_BUTTON_Y, wxEmptyString, wxPoint(l + 526, t + 173), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyButtonZ[i] = new wxButton(m_pKeys[i], IDB_BUTTON_Z, wxEmptyString, wxPoint(l + 526, t + 147), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + + // C-buttons + m_JoyAnalogSubX[i] = new wxTextCtrl(m_pKeys[i], ID_ANALOG_SUB_X, wxT("0"), wxPoint(l + 552, t + 336), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyAnalogSubX[i]->Enable(false); + m_JoyAnalogSubY[i] = new wxTextCtrl(m_pKeys[i], ID_ANALOG_SUB_Y, wxT("0"), wxPoint(l + 552, t + 373), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyAnalogSubY[i]->Enable(false); + m_bJoyAnalogSubX[i] = new wxButton(m_pKeys[i], IDB_ANALOG_SUB_X, wxEmptyString, wxPoint(l + 526, t + 338), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_bJoyAnalogSubY[i] = new wxButton(m_pKeys[i], IDB_ANALOG_SUB_Y, wxEmptyString, wxPoint(l + 526, t + 375), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_textSubX[i] = new wxStaticText(m_pKeys[i], IDT_ANALOG_SUB_X, wxT("X-axis"), wxPoint(l + 552, t + 321), wxDefaultSize, 0, wxT("X-axis")); + m_textSubY[i] = new wxStaticText(m_pKeys[i], IDT_ANALOG_SUB_Y, wxT("Y-axis"), wxPoint(l + 552, t + 358), wxDefaultSize, 0, wxT("Y-axis")); + + // Start button + m_bJoyButtonStart[i] = new wxButton(m_pKeys[i], IDB_BUTTONSTART, wxEmptyString, wxPoint(l + 284, t + 365), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + m_JoyButtonStart[i] = new wxTextCtrl(m_pKeys[i], ID_BUTTONSTART, wxT("0"), wxPoint(l + 220, t + 363), wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyButtonStart[i]->Enable(false); + + // Website text + #ifdef _WIN32 + m_textWebsite[i] = new wxStaticText(m_pKeys[i], IDT_WEBSITE, wxT("www.multigesture.net"), wxPoint(l + 400, t + 380), wxDefaultSize, 0, wxT("www.multigesture.net")); + #else + m_textWebsite[i] = new wxStaticText(m_Controller[i], IDT_WEBSITE, wxT("www.multigesture.net"), wxPoint(l + 480, t + 418), wxDefaultSize, 0, wxT("www.multigesture.net")); + #endif + + + // -------------------------------------------------------------------- + // Populate Controller sizer + // ----------------------------- + // Groups + #ifdef _WIN32 + m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, wxEmptyString, wxDefaultPosition, wxSize(476, 21), arrayStringFor_Joyname, 0, wxDefaultValidator, wxT("m_Joyname")); + m_Joyattach[i] = new wxCheckBox(m_Controller[i], IDC_JOYATTACH, wxT("Controller attached"), wxDefaultPosition, wxSize(109, 25), 0, wxDefaultValidator, wxT("Controller attached")); + #else + m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, wxEmptyString, wxDefaultPosition, wxSize(450, 25), arrayStringFor_Joyname, 0, wxDefaultValidator, wxT("m_Joyname")); + m_Joyattach[i] = new wxCheckBox(m_Controller[i], IDC_JOYATTACH, wxT("Controller attached"), wxDefaultPosition, wxSize(140, 25), 0, wxDefaultValidator, wxT("Controller attached")); + #endif + + m_gJoyname[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Controller:")); + m_gJoyname[i]->Add(m_Joyname[i], 0, (wxLEFT | wxRIGHT), 5); + m_gJoyname[i]->Add(m_Joyattach[i], 0, (wxRIGHT | wxLEFT | wxBOTTOM), 1); + + // -------------------------------------------------------------------- + // Populate settings sizer + // ----------------------------- + + // Extra settings members + m_gGBExtrasettings[i] = new wxGridBagSizer(0, 0); + m_JoyButtonHalfpress[i] = new wxTextCtrl(m_Controller[i], ID_BUTTONHALFPRESS, wxT("0"), wxDefaultPosition, wxSize(59, 19), wxTE_READONLY | wxTE_CENTRE, wxDefaultValidator, wxT("0")); + m_JoyButtonHalfpress[i]->Enable(false); + m_bJoyButtonHalfpress[i] = new wxButton(m_Controller[i], IDB_BUTTONHALFPRESS, wxEmptyString, wxPoint(231, 426), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); + #ifdef _WIN32 + m_Deadzone[i] = new wxComboBox(m_Controller[i], IDC_DEADZONE, wxEmptyString, wxDefaultPosition, wxSize(59, 21), arrayStringFor_Deadzone, 0, wxDefaultValidator, wxT("m_Deadzone")); + m_textDeadzone[i] = new wxStaticText(m_Controller[i], IDT_DEADZONE, wxT("Deadzone"), wxDefaultPosition, wxDefaultSize, 0, wxT("Deadzone")); + m_textHalfpress[i] = new wxStaticText(m_Controller[i], IDT_BUTTONHALFPRESS, wxT("Half press"), wxDefaultPosition, wxDefaultSize, 0, wxT("Half press")); + #else + m_Deadzone[i] = new wxComboBox(m_Controller[i], IDC_DEADZONE, wxEmptyString, wxPoint(167, 398), wxSize(80, 25), arrayStringFor_Deadzone, 0, wxDefaultValidator, wxT("m_Deadzone")); + m_textDeadzone[i] = new wxStaticText(m_Controller[i], IDT_DEADZONE, wxT("Deadzone"), wxPoint(105, 404), wxDefaultSize, 0, wxT("Deadzone")); + m_textHalfpress[i] = new wxStaticText(m_Controller[i], IDT_BUTTONHALFPRESS, wxT("Half press"), wxPoint(105, 428), wxDefaultSize, 0, wxT("Half press")); + #endif + + // Populate extra settings + m_gExtrasettings[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Extra settings")); + m_gGBExtrasettings[i]->Add(m_textDeadzone[i], wxGBPosition(0, 0), wxGBSpan(1, 1), (wxRIGHT | wxTOP), 2); + m_gGBExtrasettings[i]->Add(m_Deadzone[i], wxGBPosition(0, 1), wxGBSpan(1, 1), (wxBOTTOM), 2); + m_gGBExtrasettings[i]->Add(m_textHalfpress[i], wxGBPosition(1, 0), wxGBSpan(1, 1), (wxRIGHT | wxTOP), 2); + m_gGBExtrasettings[i]->Add(m_JoyButtonHalfpress[i], wxGBPosition(1, 1), wxGBSpan(1, 1), wxALL, 0); + m_gGBExtrasettings[i]->Add(m_bJoyButtonHalfpress[i], wxGBPosition(1, 2), wxGBSpan(1, 1), (wxLEFT | wxTOP), 2); + m_gExtrasettings[i]->Add(m_gGBExtrasettings[i], 0, wxEXPAND | wxALL, 3); + + // Populate controller typ + m_gControllertype[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Controller type")); + #ifdef _WIN32 + m_Controltype[i] = new wxComboBox(m_Controller[i], IDC_CONTROLTYPE, wxEmptyString, wxDefaultPosition, wxSize(131, 21), arrayStringFor_Controltype, 0, wxDefaultValidator, wxT("m_Controltype")); + #else + m_Controltype[i] = new wxComboBox(m_Controller[i], IDC_CONTROLTYPE, wxEmptyString, wxDefaultPosition, wxSize(150, 25), arrayStringFor_Controltype, 0, wxDefaultValidator, wxT("m_Controltype")); + #endif + m_gControllertype[i]->Add(m_Controltype[i], 0, wxEXPAND | wxALL, 3); + + // Populate input status + /* + m_gStatusIn[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("In")); + CreateAdvancedControls(i); + m_gStatusIn[i]->Add(m_pInStatus[i], 0, wxALL, 0); + */ + + // Populate settings + m_sSettings[i] = new wxBoxSizer ( wxHORIZONTAL ); + m_sSettings[i]->Add(m_gExtrasettings[i], 0, wxEXPAND | wxALL, 0); + m_sSettings[i]->Add(m_gControllertype[i], 0, wxEXPAND | wxLEFT, 5); + //m_sSettings[i]->Add(m_gStatusIn[i], 0, wxLEFT, 5); + + + // -------------------------------------------------------------------- + // Populate main sizer + // ----------------------------- + m_sMain[i] = new wxBoxSizer(wxVERTICAL); + m_sMain[i]->Add(m_gJoyname[i], 0, wxEXPAND | (wxALL), 5); + m_sMain[i]->Add(m_sKeys[i], 1, wxEXPAND | (wxLEFT | wxRIGHT), 5); + m_sMain[i]->Add(m_sSettings[i], 0, wxEXPAND | (wxALL), 5); + m_Controller[i]->SetSizer(m_sMain[i]); // Set the main sizer + + + // Disable when running if(emulator_running) { m_Joyname[i]->Enable(false); @@ -271,35 +399,64 @@ void ConfigBox::CreateGUIControls() m_Controltype[i]->Enable(false); } + // Set dialog items SetControllerAll(i); - } + } // end of loop + + + // -------------------------------------------------------------------- + // Populate buttons sizer. + // ----------------------------- + wxBoxSizer * m_sButtons = new wxBoxSizer(wxHORIZONTAL); + m_sButtons->Add(m_About, 0, (wxBOTTOM), 0); + m_sButtons->AddStretchSpacer(1); + m_sButtons->Add(m_OK, 0, wxALIGN_RIGHT | (wxBOTTOM), 0); + m_sButtons->Add(m_Cancel, 0, wxALIGN_RIGHT | (wxLEFT), 5); + + + // -------------------------------------------------------------------- + // Populate master sizer. + // ----------------------------- + wxBoxSizer * 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); + + // Set window size + SetClientSize(m_MainSizer->GetMinSize().GetWidth(), m_MainSizer->GetMinSize().GetHeight()); + Center(); } + +// Close window +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void ConfigBox::OnClose(wxCloseEvent& /*event*/) { EndModal(0); } -void ConfigBox::AboutClick(wxCommandEvent& event) -{ + // Call about dialog // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -#ifdef _WIN32 - wxWindow win; - win.SetHWND((WXHWND)this->GetHWND()); - win.Enable(false); +void ConfigBox::AboutClick(wxCommandEvent& event) +{ + #ifdef _WIN32 + wxWindow win; + win.SetHWND((WXHWND)this->GetHWND()); + win.Enable(false); - AboutBox frame(&win); - frame.ShowModal(); + AboutBox frame(&win); + frame.ShowModal(); - win.Enable(true); - win.SetHWND(0); -#else - AboutBox frame(NULL); - frame.ShowModal(); -#endif + win.Enable(true); + win.SetHWND(0); + #else + AboutBox frame(NULL); + frame.ShowModal(); + #endif } + void ConfigBox::OKClick(wxCommandEvent& event) { if (event.GetId() == ID_OK) @@ -370,7 +527,7 @@ void ConfigBox::SetControllerAll(int controller) } } -// Get dialog items +// Get dialog items. Collect button identification. // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void ConfigBox::GetControllerAll(int controller) { @@ -414,6 +571,7 @@ void ConfigBox::GetControllerAll(int controller) joysticks[controller].deadzone = m_Deadzone[controller]->GetSelection(); } + void ConfigBox::UpdateVisibleItems(int controller) { if(joysticks[controller].controllertype) @@ -463,8 +621,7 @@ void ConfigBox::ChangeControllertype(wxCommandEvent& event) joysticks[2].controllertype = m_Controltype[2]->GetSelection(); joysticks[3].controllertype = m_Controltype[3]->GetSelection(); - for(int i=0; i<4 ;i++) - UpdateVisibleItems(i); + for(int i=0; i<4 ;i++) UpdateVisibleItems(i); } void ConfigBox::NotebookPageChanged(wxNotebookEvent& event) @@ -585,6 +742,7 @@ void ConfigBox::SetButtonText(int id, char text[128]) } } + // Wait for button press // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void ConfigBox::GetButtons(wxCommandEvent& event) diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h index 0623fa9b10..ba6b94a8ab 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h @@ -29,6 +29,7 @@ // ////////////////////////////////////////////////////////////////////////////////////////// + #ifndef __CONFIGBOX_h__ #define __CONFIGBOX_h__ @@ -45,6 +46,7 @@ #include #include #include +#include class ConfigBox : public wxDialog @@ -53,9 +55,16 @@ class ConfigBox : public wxDialog DECLARE_EVENT_TABLE(); public: - ConfigBox(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); + ConfigBox(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 ~ConfigBox(); + + #if wxUSE_TIMER + void OnTimer(wxTimerEvent& WXUNUSED(event)) { Update(); } + wxTimer m_timer; + #endif private: wxButton *m_About; @@ -65,15 +74,21 @@ class ConfigBox : public wxDialog wxPanel *m_Controller[4]; wxNotebook *m_Notebook; + wxPanel * m_pKeys[4], * m_pInStatus[4]; + wxBitmap WxStaticBitmap1_BITMAP; + wxStaticBoxSizer * m_sKeys[4]; + wxBoxSizer * m_sMain[4], * m_sSettings[4]; + wxComboBox *m_Joyname[4]; wxComboBox *m_Controltype[4]; wxComboBox *m_Deadzone[4]; wxCheckBox *m_Joyattach[4]; + wxStaticBoxSizer *m_gJoyname[4]; - wxStaticBox *m_gJoyname[4]; - wxStaticBox *m_gExtrasettings[4]; - wxStaticBox *m_gControllertype[4]; + wxStaticBoxSizer *m_gExtrasettings[4]; wxGridBagSizer * m_gGBExtrasettings[4]; // Settings + wxStaticBoxSizer *m_gControllertype[4]; + wxStaticBoxSizer *m_gStatusIn[4]; wxTextCtrl *m_JoyShoulderL[4]; wxTextCtrl *m_JoyShoulderR[4]; @@ -130,7 +145,7 @@ class ConfigBox : public wxDialog wxStaticText *m_textWebsite[4]; wxTextCtrl *m_PlaceholderBMP[4]; - wxStaticBitmap *m_controllerimage[4]; + wxStaticBitmap *m_controllerimage[4], *m_bmpSquare[4], *m_bmpDot[4]; int notebookpage; private: @@ -145,6 +160,10 @@ class ConfigBox : public wxDialog ID_CONTROLLERPAGE3, ID_CONTROLLERPAGE4, + ID_INSTATUS1, ID_INSTATUS2, ID_INSTATUS3, ID_INSTATUS4, // Advanced status + + ID_KEYSPANEL1, ID_KEYSPANEL2, ID_KEYSPANEL3, ID_KEYSPANEL4, + IDC_JOYNAME, IDC_CONTROLTYPE, IDC_DEADZONE, @@ -154,6 +173,8 @@ class ConfigBox : public wxDialog IDG_EXTRASETTINGS, IDG_CONTROLLERTYPE, ID_CONTROLLERPICTURE, + ID_STATUSBMP1, ID_STATUSBMP2, ID_STATUSBMP3, ID_STATUSBMP4, + ID_STATUSDOTBMP1, ID_STATUSDOTBMP2, ID_STATUSDOTBMP3, ID_STATUSDOTBMP4, ID_SHOULDER_L = 2000, ID_SHOULDER_R, @@ -221,8 +242,10 @@ class ConfigBox : public wxDialog void ChangeControllertype(wxCommandEvent& event); void OnClose(wxCloseEvent& event); - void CreateGUIControls(); - + void CreateGUIControls(); void CreateAdvancedControls(int i); + wxBitmap CreateBitmap(); wxBitmap CreateBitmapDot(); + void PadGetStatus(); void Update(); + void SetControllerAll(int controller); void UpdateVisibleItems(int controller); void GetControllerAll(int controller); @@ -233,6 +256,8 @@ class ConfigBox : public wxDialog void GetHats(int ID); void GetAxis(wxCommandEvent& event); + void OnPaint(wxPaintEvent &event); + void SetButtonText(int id, char text[128]); }; diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/Rumble.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/Rumble.cpp new file mode 100644 index 0000000000..cf99262d55 --- /dev/null +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/Rumble.cpp @@ -0,0 +1,394 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// Project description +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +// Name: nJoy +// Description: A Dolphin Compatible Input Plugin +// +// Author: Falcon4ever (nJoy@falcon4ever.com) +// Site: www.multigesture.net +// Copyright (C) 2003-2008 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" + + +////////////////////////////////////////////////////////////////////////////////////////// +// Enable or disable rumble. Set USE_RUMBLE_DINPUT_HACK in nJoy.h +// ŻŻŻŻŻŻŻŻŻ +#ifdef USE_RUMBLE_DINPUT_HACK +bool g_rumbleEnable = FALSE; +#endif + +// Rumble in windows +#ifdef _WIN32 + + #ifdef USE_RUMBLE_DINPUT_HACK + LPDIRECTINPUT8 g_pDI = NULL; + LPDIRECTINPUTDEVICE8 g_pDevice = NULL; + LPDIRECTINPUTEFFECT g_pEffect = NULL; + + DWORD g_dwNumForceFeedbackAxis = 0; + INT g_nXForce = 0; + INT g_nYForce = 0; + + #define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } } + + HRESULT InitDirectInput(HWND hDlg); + //VOID FreeDirectInput(); + BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContext); + BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext); + HRESULT SetDeviceForcesXY(); + #endif + +#elif defined(__linux__) + #include + #include + #include + + int fd; + char device_file_name[64]; + struct ff_effect effect; + bool CanRumble = false; +#endif +////////////////////// + + + +// Set PAD rumble. Explanation: Stop = 0, Rumble = 1 +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) +{ + //if (_numPAD > 0) + // return; + + // SDL can't rumble the gamepad so we need to use platform specific code + #ifdef _WIN32 + #ifdef USE_RUMBLE_DINPUT_HACK + static int a = 0; + + if ((_uType == 0) || (_uType == 2)) + { + a = 0; + } + else if (_uType == 1) + { + a = _uStrength > 2 ? 8000 : 0; + } + + a = int ((float)a * 0.96f); + + if (!g_rumbleEnable) + { + a = 0; + } + else + { + g_nYForce = a; + SetDeviceForcesXY(); + } + #endif + #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); + } + } + 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 +} + + + +// Use PAD rumble +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void PAD_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus) +{ + #ifdef _WIN32 + #ifdef USE_RUMBLE_DINPUT_HACK + + // Enable or disable rumble + if (joystate[_numPAD].halfpress) + if (!g_pDI) + if (FAILED(InitDirectInput(m_hWnd))) + { + MessageBox(NULL, SDL_GetError(), "Could not initialize DirectInput!", MB_ICONERROR); + g_rumbleEnable = FALSE; + //return; + } + else + { + g_rumbleEnable = TRUE; + } + + if (g_rumbleEnable) + { + g_pDevice->Acquire(); + + if (g_pEffect) g_pEffect->Start(1, 0); + } + #endif + #elif defined(__linux__) + if (!fd) + { + sprintf(device_file_name, "/dev/input/event%d", joysticks[_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 +} + + + + + + +#ifdef _WIN32 +////////////////////////////////////////////////////////////////////////////////////////// +// Rumble stuff :D! +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +// +#ifdef USE_RUMBLE_DINPUT_HACK +HRESULT InitDirectInput( HWND hDlg ) +{ + 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_pDI, NULL))) + { + return hr; + } + + // Look for a force feedback device we can use + if (FAILED(hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumFFDevicesCallback, NULL, DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK))) + { + return hr; + } + + if (NULL == g_pDevice) + { + MessageBox(NULL, "Force feedback device not found. nJoy will now disable rumble." ,"FFConst" , MB_ICONERROR | MB_OK); + g_rumbleEnable = FALSE; + + return S_OK; + } + + // Set the data format to "simple joystick" - a predefined data format. A + // data format specifies which controls on a device we are interested in, + // and how they should be reported. + // + // This tells DirectInput that we will be passing a DIJOYSTATE structure to + // IDirectInputDevice8::GetDeviceState(). Even though we won't actually do + // it in this sample. But setting the data format is important so that the + // DIJOFS_* values work properly. + if (FAILED(hr = g_pDevice->SetDataFormat(&c_dfDIJoystick))) + return hr; + + // Set the cooperative level to let DInput know how this device should + // interact with the system and with other DInput applications. + // Exclusive access is required in order to perform force feedback. + //if (FAILED(hr = g_pDevice->SetCooperativeLevel(hDlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND))) + + if (FAILED(hr = g_pDevice->SetCooperativeLevel(hDlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND))) + { + return hr; + } + + // Since we will be playing force feedback effects, we should disable the + // auto-centering spring. + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = FALSE; + + if (FAILED(hr = g_pDevice->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph))) + return hr; + + // Enumerate and count the axes of the joystick + if (FAILED(hr = g_pDevice->EnumObjects(EnumAxesCallback, (VOID*)&g_dwNumForceFeedbackAxis, DIDFT_AXIS))) + return hr; + + // This simple sample only supports one or two axis joysticks + if (g_dwNumForceFeedbackAxis > 2) + g_dwNumForceFeedbackAxis = 2; + + // This application needs only one effect: Applying raw forces. + DWORD rgdwAxes[2] = {DIJOFS_X, DIJOFS_Y}; + LONG rglDirection[2] = {0, 0}; + DICONSTANTFORCE cf = {0}; + + DIEFFECT eff; + ZeroMemory(&eff, sizeof(eff)); + eff.dwSize = sizeof(DIEFFECT); + eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + eff.dwDuration = INFINITE; + eff.dwSamplePeriod = 0; + eff.dwGain = DI_FFNOMINALMAX; + eff.dwTriggerButton = DIEB_NOTRIGGER; + eff.dwTriggerRepeatInterval = 0; + eff.cAxes = g_dwNumForceFeedbackAxis; + eff.rgdwAxes = rgdwAxes; + eff.rglDirection = rglDirection; + eff.lpEnvelope = 0; + eff.cbTypeSpecificParams = sizeof( DICONSTANTFORCE ); + eff.lpvTypeSpecificParams = &cf; + eff.dwStartDelay = 0; + + // Create the prepared effect + if (FAILED(hr = g_pDevice->CreateEffect(GUID_ConstantForce, &eff, &g_pEffect, NULL))) + { + return hr; + } + + if (NULL == g_pEffect) + return E_FAIL; + + return S_OK; +} + +VOID FreeDirectInput() +{ + // Unacquire the device one last time just in case + // the app tried to exit while the device is still acquired. + if (g_pDevice) + g_pDevice->Unacquire(); + + // Release any DirectInput objects. + SAFE_RELEASE(g_pEffect); + SAFE_RELEASE(g_pDevice); + SAFE_RELEASE(g_pDI); +} + +BOOL CALLBACK EnumFFDevicesCallback( const DIDEVICEINSTANCE* pInst, VOID* pContext ) +{ + LPDIRECTINPUTDEVICE8 pDevice; + HRESULT hr; + + // Obtain an interface to the enumerated force feedback device. + hr = g_pDI->CreateDevice(pInst->guidInstance, &pDevice, NULL); + + // If it failed, then we can't use this device for some bizarre reason. + // (Maybe the user unplugged it while we were in the middle of enumerating it.) So continue enumerating + if (FAILED(hr)) + return DIENUM_CONTINUE; + + // We successfully created an IDirectInputDevice8. So stop looking for another one. + g_pDevice = pDevice; + + return DIENUM_STOP; +} + +BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext) +{ + DWORD* pdwNumForceFeedbackAxis = (DWORD*)pContext; + if ((pdidoi->dwFlags & DIDOI_FFACTUATOR) != 0) + (*pdwNumForceFeedbackAxis)++; + + return DIENUM_CONTINUE; +} + +HRESULT SetDeviceForcesXY() +{ + // Modifying an effect is basically the same as creating a new one, except you need only specify the parameters you are modifying + LONG rglDirection[2] = { 0, 0 }; + + DICONSTANTFORCE cf; + + if (g_dwNumForceFeedbackAxis == 1) + { + // If only one force feedback axis, then apply only one direction and keep the direction at zero + cf.lMagnitude = g_nXForce; + rglDirection[0] = 0; + } + else + { + // If two force feedback axis, then apply magnitude from both directions + rglDirection[0] = g_nXForce; + rglDirection[1] = g_nYForce; + cf.lMagnitude = (DWORD)sqrt((double)g_nXForce * (double)g_nXForce + (double)g_nYForce * (double)g_nYForce ); + } + + DIEFFECT eff; + ZeroMemory(&eff, sizeof(eff)); + eff.dwSize = sizeof(DIEFFECT); + eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + eff.cAxes = g_dwNumForceFeedbackAxis; + eff.rglDirection = rglDirection; + eff.lpEnvelope = 0; + eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + eff.lpvTypeSpecificParams = &cf; + eff.dwStartDelay = 0; + + // Now set the new parameters and start the effect immediately. + return g_pEffect->SetParameters(&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START); +} +#endif +#endif diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/SConscript b/Source/Plugins/Plugin_nJoy_SDL/Src/SConscript index f0adaae060..7d611cc268 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/SConscript +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/SConscript @@ -11,11 +11,14 @@ if not env['HAVE_SDL']: Return() files = [ + 'Config.cpp', 'nJoy.cpp', + 'Rumble.cpp', ] if padenv['HAVE_WX']: files += [ 'GUI/AboutBox.cpp', + 'GUI/ConfigAdvanced.cpp', 'GUI/ConfigBox.cpp', ] diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp index ded466079e..24c7b10910 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp @@ -29,73 +29,52 @@ // ////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////// +// Include +// ŻŻŻŻŻŻŻŻŻ #include "nJoy.h" + ////////////////////////////////////////////////////////////////////////////////////////// // Variables // ŻŻŻŻŻŻŻŻŻ +// Rumble in windows +#define _CONTROLLER_STATE_H // avoid certain declarations in nJoy.h FILE *pFile; HINSTANCE nJoy_hInst = NULL; CONTROLLER_INFO *joyinfo = 0; CONTROLLER_STATE joystate[4]; CONTROLLER_MAPPING joysticks[4]; bool emulator_running = FALSE; +HWND m_hWnd; // Handle to window -// Handle to window -HWND m_hWnd; - -#ifdef USE_RUMBLE_DINPUT_HACK -bool g_rumbleEnable = FALSE; -#endif - -// Rumble in windows +// Rumble #ifdef _WIN32 -#ifdef USE_RUMBLE_DINPUT_HACK -LPDIRECTINPUT8 g_pDI = NULL; -LPDIRECTINPUTDEVICE8 g_pDevice = NULL; -LPDIRECTINPUTEFFECT g_pEffect = NULL; - -DWORD g_dwNumForceFeedbackAxis = 0; -INT g_nXForce = 0; -INT g_nYForce = 0; - -#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } } - -HRESULT InitDirectInput(HWND hDlg); -VOID FreeDirectInput(); -BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContext); -BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext); -HRESULT SetDeviceForcesXY(); -#endif - #elif defined(__linux__) -#include -#include -#include - - int fd; - char device_file_name[64]; - struct ff_effect effect; - bool CanRumble = false; + extern int fd; #endif -#if defined(HAVE_WX) && HAVE_WX + ////////////////////////////////////////////////////////////////////////////////////////// // wxWidgets // ŻŻŻŻŻŻŻŻŻ -class wxDLLApp : public wxApp -{ - bool OnInit() +#if defined(HAVE_WX) && HAVE_WX + class wxDLLApp : public wxApp { - return true; - } -}; + bool OnInit() + { + return true; + } + }; -IMPLEMENT_APP_NO_MAIN(wxDLLApp) -WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst); + IMPLEMENT_APP_NO_MAIN(wxDLLApp) + WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst); #endif + + ////////////////////////////////////////////////////////////////////////////////////////// // DllMain // ŻŻŻŻŻŻŻ @@ -181,10 +160,12 @@ void DllConfig(HWND _hParent) } LoadConfig(); // load settings -#if defined(HAVE_WX) && HAVE_WX - ConfigBox frame(NULL); - frame.ShowModal(); -#endif + + #if defined(HAVE_WX) && HAVE_WX + ConfigBox frame(NULL); + frame.ShowModal(); + #endif + #endif } @@ -242,7 +223,7 @@ void PAD_Shutdown() SDL_Quit(); #ifdef _DEBUG - DEBUG_QUIT(); + DEBUG_QUIT(); #endif delete [] joyinfo; @@ -250,14 +231,15 @@ void PAD_Shutdown() emulator_running = FALSE; #ifdef _WIN32 - #ifdef USE_RUMBLE_DINPUT_HACK - FreeDirectInput(); - #endif + #ifdef USE_RUMBLE_DINPUT_HACK + FreeDirectInput(); + #endif #elif defined(__linux__) - close(fd); + close(fd); #endif } + // Set PAD status // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) @@ -265,10 +247,10 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) if (!joysticks[_numPAD].enabled) return; - // clear pad status + // Clear pad status memset(_pPADStatus, 0, sizeof(SPADStatus)); - // get pad status + // Get pad status GetJoyState(_numPAD); // Reset! @@ -287,10 +269,10 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) // Adjust range // The value returned by SDL_JoystickGetAxis is a signed integer (-32768 to 32768) // The value used for the gamecube controller is an unsigned char (0 to 255) - int main_stick_x = (joystate[_numPAD].axis[CTL_MAIN_X]>>8); - int main_stick_y = -(joystate[_numPAD].axis[CTL_MAIN_Y]>>8); - int sub_stick_x = (joystate[_numPAD].axis[CTL_SUB_X]>>8); - int sub_stick_y = -(joystate[_numPAD].axis[CTL_SUB_Y]>>8); + int main_stick_x = (joystate[_numPAD].axis[CTL_MAIN_X] >> 8); + int main_stick_y = -(joystate[_numPAD].axis[CTL_MAIN_Y] >> 8); + int sub_stick_x = (joystate[_numPAD].axis[CTL_SUB_X] >> 8); + int sub_stick_y = -(joystate[_numPAD].axis[CTL_SUB_Y] >> 8); // Quick fix if (main_stick_x > 127) @@ -351,8 +333,8 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) // Set D-pad if (joysticks[_numPAD].controllertype == CTL_TYPE_JOYSTICK) { - if (joystate[_numPAD].dpad == SDL_HAT_LEFTUP || joystate[_numPAD].dpad == SDL_HAT_UP || joystate[_numPAD].dpad == SDL_HAT_RIGHTUP ) _pPADStatus->button|=PAD_BUTTON_UP; - if (joystate[_numPAD].dpad == SDL_HAT_LEFTUP || joystate[_numPAD].dpad == SDL_HAT_LEFT || joystate[_numPAD].dpad == SDL_HAT_LEFTDOWN ) _pPADStatus->button|=PAD_BUTTON_LEFT; + if (joystate[_numPAD].dpad == SDL_HAT_LEFTUP || joystate[_numPAD].dpad == SDL_HAT_UP || joystate[_numPAD].dpad == SDL_HAT_RIGHTUP ) _pPADStatus->button|=PAD_BUTTON_UP; + if (joystate[_numPAD].dpad == SDL_HAT_LEFTUP || joystate[_numPAD].dpad == SDL_HAT_LEFT || joystate[_numPAD].dpad == SDL_HAT_LEFTDOWN ) _pPADStatus->button|=PAD_BUTTON_LEFT; if (joystate[_numPAD].dpad == SDL_HAT_LEFTDOWN || joystate[_numPAD].dpad == SDL_HAT_DOWN || joystate[_numPAD].dpad == SDL_HAT_RIGHTDOWN ) _pPADStatus->button|=PAD_BUTTON_DOWN; if (joystate[_numPAD].dpad == SDL_HAT_RIGHTUP || joystate[_numPAD].dpad == SDL_HAT_RIGHT || joystate[_numPAD].dpad == SDL_HAT_RIGHTDOWN ) _pPADStatus->button|=PAD_BUTTON_RIGHT; } @@ -368,127 +350,15 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) _pPADStatus->button|=PAD_BUTTON_RIGHT; } + // _pPADStatus->err = PAD_ERR_NONE; - - #ifdef _WIN32 - #ifdef USE_RUMBLE_DINPUT_HACK - if (joystate[_numPAD].halfpress) - if (!g_pDI) - if (FAILED(InitDirectInput(m_hWnd))) - { - MessageBox(NULL, SDL_GetError(), "Could not initialize DirectInput!", MB_ICONERROR); - g_rumbleEnable = FALSE; - //return; - } - else - g_rumbleEnable = TRUE; - - if (g_rumbleEnable) - { - g_pDevice->Acquire(); - - if (g_pEffect) - g_pEffect->Start(1, 0); - } - #endif - #elif defined(__linux__) - if (!fd) - { - sprintf(device_file_name, "/dev/input/event%d", joysticks[_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 + // Use rumble + PAD_Use_Rumble(_numPAD, _pPADStatus); } -// Set PAD rumble -// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -// (Stop=0, Rumble=1) -void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) -{ - //if (_numPAD > 0) - // return; - // not supported by SDL - // So we need to use platform specific stuff - #ifdef _WIN32 - #ifdef USE_RUMBLE_DINPUT_HACK - static int a = 0; - if ((_uType == 0) || (_uType == 2)) - { - a = 0; - } - else if (_uType == 1) - { - a = _uStrength > 2 ? 8000 : 0; - } - - a = int ((float)a * 0.96f); - - if (!g_rumbleEnable) - { - a = 0; - } - else - { - g_nYForce = a; - SetDeviceForcesXY(); - } - #endif - #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); - } - } - 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 -} // Set PAD attached pads // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ @@ -510,13 +380,19 @@ unsigned int PAD_GetAttachedPads() return connected; } + + ////////////////////////////////////////////////////////////////////////////////////////// // Custom Functions // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -void ReadButton(int controller, int button) { +// Read buttons status. Called from GetJoyState(). +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void ReadButton(int controller, int button) +{ int ctl_button = joysticks[controller].buttons[button]; - if (ctl_button < joyinfo[joysticks[controller].ID].NumButtons) { + if (ctl_button < joyinfo[joysticks[controller].ID].NumButtons) + { joystate[controller].buttons[button] = SDL_JoystickGetButton(joystate[controller].joy, ctl_button); } } @@ -540,10 +416,14 @@ void GetJoyState(int controller) ReadButton(controller, CTL_Y_BUTTON); ReadButton(controller, CTL_Z_TRIGGER); ReadButton(controller, CTL_START); + + PanicAlert("%i", CTL_A_BUTTON); + // if (joysticks[controller].halfpress < joyinfo[controller].NumButtons) joystate[controller].halfpress = SDL_JoystickGetButton(joystate[controller].joy, joysticks[controller].halfpress); + // Check if we have an analog or digital joypad if (joysticks[controller].controllertype == CTL_TYPE_JOYSTICK) { joystate[controller].dpad = SDL_JoystickGetHat(joystate[controller].joy, joysticks[controller].dpad); @@ -578,6 +458,7 @@ int Search_Devices() joyinfo = new CONTROLLER_INFO [numjoy]; } + // Warn the user of no joysticks are detected if (numjoy == 0) { #ifdef _WIN32 @@ -619,305 +500,3 @@ int Search_Devices() return numjoy; } - -// 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 v"INPUT_VERSION" 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 SaveConfig() -{ - IniFile file; - file.Load("nJoy.ini"); - - for (int i = 0; i < 4; i++) - { - char SectionName[32]; - sprintf(SectionName, "PAD%i", i+1); - - file.Set(SectionName, "l_shoulder", joysticks[i].buttons[CTL_L_SHOULDER]); - file.Set(SectionName, "r_shoulder", joysticks[i].buttons[CTL_R_SHOULDER]); - file.Set(SectionName, "a_button", joysticks[i].buttons[CTL_A_BUTTON]); - file.Set(SectionName, "b_button", joysticks[i].buttons[CTL_B_BUTTON]); - file.Set(SectionName, "x_button", joysticks[i].buttons[CTL_X_BUTTON]); - file.Set(SectionName, "y_button", joysticks[i].buttons[CTL_Y_BUTTON]); - file.Set(SectionName, "z_trigger", joysticks[i].buttons[CTL_Z_TRIGGER]); - file.Set(SectionName, "start_button", joysticks[i].buttons[CTL_START]); - file.Set(SectionName, "dpad", joysticks[i].dpad); - file.Set(SectionName, "dpad_up", joysticks[i].dpad2[CTL_D_PAD_UP]); - file.Set(SectionName, "dpad_down", joysticks[i].dpad2[CTL_D_PAD_DOWN]); - file.Set(SectionName, "dpad_left", joysticks[i].dpad2[CTL_D_PAD_LEFT]); - file.Set(SectionName, "dpad_right", joysticks[i].dpad2[CTL_D_PAD_RIGHT]); - file.Set(SectionName, "main_x", joysticks[i].axis[CTL_MAIN_X]); - file.Set(SectionName, "main_y", joysticks[i].axis[CTL_MAIN_Y]); - file.Set(SectionName, "sub_x", joysticks[i].axis[CTL_SUB_X]); - file.Set(SectionName, "sub_y", joysticks[i].axis[CTL_SUB_Y]); - file.Set(SectionName, "enabled", joysticks[i].enabled); - file.Set(SectionName, "deadzone", joysticks[i].deadzone); - file.Set(SectionName, "halfpress", joysticks[i].halfpress); - file.Set(SectionName, "joy_id", joysticks[i].ID); - file.Set(SectionName, "controllertype", joysticks[i].controllertype); - file.Set(SectionName, "eventnum", joysticks[i].eventnum); - } - - file.Save("nJoy.ini"); -} - -// Load settings from file -// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -void LoadConfig() -{ - IniFile file; - file.Load("nJoy.ini"); - - for (int i = 0; i < 4; i++) - { - char SectionName[32]; - sprintf(SectionName, "PAD%i", i+1); - - file.Get(SectionName, "l_shoulder", &joysticks[i].buttons[CTL_L_SHOULDER], 4); - file.Get(SectionName, "r_shoulder", &joysticks[i].buttons[CTL_R_SHOULDER], 5); - file.Get(SectionName, "a_button", &joysticks[i].buttons[CTL_A_BUTTON], 0); - file.Get(SectionName, "b_button", &joysticks[i].buttons[CTL_B_BUTTON], 1); - file.Get(SectionName, "x_button", &joysticks[i].buttons[CTL_X_BUTTON], 3); - file.Get(SectionName, "y_button", &joysticks[i].buttons[CTL_Y_BUTTON], 2); - file.Get(SectionName, "z_trigger", &joysticks[i].buttons[CTL_Z_TRIGGER], 7); - file.Get(SectionName, "start_button", &joysticks[i].buttons[CTL_START], 9); - file.Get(SectionName, "dpad", &joysticks[i].dpad, 0); - file.Get(SectionName, "dpad_up", &joysticks[i].dpad2[CTL_D_PAD_UP], 0); - file.Get(SectionName, "dpad_down", &joysticks[i].dpad2[CTL_D_PAD_DOWN], 0); - file.Get(SectionName, "dpad_left", &joysticks[i].dpad2[CTL_D_PAD_LEFT], 0); - file.Get(SectionName, "dpad_right", &joysticks[i].dpad2[CTL_D_PAD_RIGHT], 0); - file.Get(SectionName, "main_x", &joysticks[i].axis[CTL_MAIN_X], 0); - file.Get(SectionName, "main_y", &joysticks[i].axis[CTL_MAIN_Y], 1); - file.Get(SectionName, "sub_x", &joysticks[i].axis[CTL_SUB_X], 2); - file.Get(SectionName, "sub_y", &joysticks[i].axis[CTL_SUB_Y], 3); - file.Get(SectionName, "enabled", &joysticks[i].enabled, 1); - file.Get(SectionName, "deadzone", &joysticks[i].deadzone, 9); - file.Get(SectionName, "halfpress", &joysticks[i].halfpress, 6); - file.Get(SectionName, "joy_id", &joysticks[i].ID, 0); - file.Get(SectionName, "controllertype", &joysticks[i].controllertype, 0); - file.Get(SectionName, "eventnum", &joysticks[i].eventnum, 0); - } -} - - -#ifdef _WIN32 -////////////////////////////////////////////////////////////////////////////////////////// -// Rumble stuff :D! -// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -// -#ifdef USE_RUMBLE_DINPUT_HACK -HRESULT InitDirectInput( HWND hDlg ) -{ - 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_pDI, NULL))) - { - return hr; - } - - // Look for a force feedback device we can use - if (FAILED(hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumFFDevicesCallback, NULL, DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK))) - { - return hr; - } - - if (NULL == g_pDevice) - { - MessageBox(NULL, "Force feedback device not found. nJoy will now disable rumble." ,"FFConst" , MB_ICONERROR | MB_OK); - g_rumbleEnable = FALSE; - - return S_OK; - } - - // Set the data format to "simple joystick" - a predefined data format. A - // data format specifies which controls on a device we are interested in, - // and how they should be reported. - // - // This tells DirectInput that we will be passing a DIJOYSTATE structure to - // IDirectInputDevice8::GetDeviceState(). Even though we won't actually do - // it in this sample. But setting the data format is important so that the - // DIJOFS_* values work properly. - if (FAILED(hr = g_pDevice->SetDataFormat(&c_dfDIJoystick))) - return hr; - - // Set the cooperative level to let DInput know how this device should - // interact with the system and with other DInput applications. - // Exclusive access is required in order to perform force feedback. - //if (FAILED(hr = g_pDevice->SetCooperativeLevel(hDlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND))) - - if (FAILED(hr = g_pDevice->SetCooperativeLevel(hDlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND))) - { - return hr; - } - - // Since we will be playing force feedback effects, we should disable the - // auto-centering spring. - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = FALSE; - - if (FAILED(hr = g_pDevice->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph))) - return hr; - - // Enumerate and count the axes of the joystick - if (FAILED(hr = g_pDevice->EnumObjects(EnumAxesCallback, (VOID*)&g_dwNumForceFeedbackAxis, DIDFT_AXIS))) - return hr; - - // This simple sample only supports one or two axis joysticks - if (g_dwNumForceFeedbackAxis > 2) - g_dwNumForceFeedbackAxis = 2; - - // This application needs only one effect: Applying raw forces. - DWORD rgdwAxes[2] = {DIJOFS_X, DIJOFS_Y}; - LONG rglDirection[2] = {0, 0}; - DICONSTANTFORCE cf = {0}; - - DIEFFECT eff; - ZeroMemory(&eff, sizeof(eff)); - eff.dwSize = sizeof(DIEFFECT); - eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; - eff.dwDuration = INFINITE; - eff.dwSamplePeriod = 0; - eff.dwGain = DI_FFNOMINALMAX; - eff.dwTriggerButton = DIEB_NOTRIGGER; - eff.dwTriggerRepeatInterval = 0; - eff.cAxes = g_dwNumForceFeedbackAxis; - eff.rgdwAxes = rgdwAxes; - eff.rglDirection = rglDirection; - eff.lpEnvelope = 0; - eff.cbTypeSpecificParams = sizeof( DICONSTANTFORCE ); - eff.lpvTypeSpecificParams = &cf; - eff.dwStartDelay = 0; - - // Create the prepared effect - if (FAILED(hr = g_pDevice->CreateEffect(GUID_ConstantForce, &eff, &g_pEffect, NULL))) - { - return hr; - } - - if (NULL == g_pEffect) - return E_FAIL; - - return S_OK; -} - -VOID FreeDirectInput() -{ - // Unacquire the device one last time just in case - // the app tried to exit while the device is still acquired. - if (g_pDevice) - g_pDevice->Unacquire(); - - // Release any DirectInput objects. - SAFE_RELEASE(g_pEffect); - SAFE_RELEASE(g_pDevice); - SAFE_RELEASE(g_pDI); -} - -BOOL CALLBACK EnumFFDevicesCallback( const DIDEVICEINSTANCE* pInst, VOID* pContext ) -{ - LPDIRECTINPUTDEVICE8 pDevice; - HRESULT hr; - - // Obtain an interface to the enumerated force feedback device. - hr = g_pDI->CreateDevice(pInst->guidInstance, &pDevice, NULL); - - // If it failed, then we can't use this device for some bizarre reason. - // (Maybe the user unplugged it while we were in the middle of enumerating it.) So continue enumerating - if (FAILED(hr)) - return DIENUM_CONTINUE; - - // We successfully created an IDirectInputDevice8. So stop looking for another one. - g_pDevice = pDevice; - - return DIENUM_STOP; -} - -BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext) -{ - DWORD* pdwNumForceFeedbackAxis = (DWORD*)pContext; - if ((pdidoi->dwFlags & DIDOI_FFACTUATOR) != 0) - (*pdwNumForceFeedbackAxis)++; - - return DIENUM_CONTINUE; -} - -HRESULT SetDeviceForcesXY() -{ - // Modifying an effect is basically the same as creating a new one, except you need only specify the parameters you are modifying - LONG rglDirection[2] = { 0, 0 }; - - DICONSTANTFORCE cf; - - if (g_dwNumForceFeedbackAxis == 1) - { - // If only one force feedback axis, then apply only one direction and keep the direction at zero - cf.lMagnitude = g_nXForce; - rglDirection[0] = 0; - } - else - { - // If two force feedback axis, then apply magnitude from both directions - rglDirection[0] = g_nXForce; - rglDirection[1] = g_nYForce; - cf.lMagnitude = (DWORD)sqrt((double)g_nXForce * (double)g_nXForce + (double)g_nYForce * (double)g_nYForce ); - } - - DIEFFECT eff; - ZeroMemory(&eff, sizeof(eff)); - eff.dwSize = sizeof(DIEFFECT); - eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; - eff.cAxes = g_dwNumForceFeedbackAxis; - eff.rglDirection = rglDirection; - eff.lpEnvelope = 0; - eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); - eff.lpvTypeSpecificParams = &cf; - eff.dwStartDelay = 0; - - // Now set the new parameters and start the effect immediately. - return g_pEffect->SetParameters(&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START); -} -#endif -#endif diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h index 1555f6acaf..c31c5966ef 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h @@ -47,20 +47,21 @@ #endif #ifdef _WIN32 -#pragma comment(lib, "SDL.lib") -#pragma comment(lib, "comctl32.lib") -#include -#include -#define _CRT_SECURE_NO_WARNINGS -#define DIRECTINPUT_VERSION 0x0800 -#define WIN32_LEAN_AND_MEAN + #pragma comment(lib, "SDL.lib") + #pragma comment(lib, "comctl32.lib") + #include + #include + #define _CRT_SECURE_NO_WARNINGS + #define DIRECTINPUT_VERSION 0x0800 + #define WIN32_LEAN_AND_MEAN -#ifdef USE_RUMBLE_DINPUT_HACK -#pragma comment(lib, "dxguid.lib") -#pragma comment(lib, "dinput8.lib") -#pragma comment(lib, "winmm.lib") -#include -#endif + #ifdef USE_RUMBLE_DINPUT_HACK + #pragma comment(lib, "dxguid.lib") + #pragma comment(lib, "dinput8.lib") + #pragma comment(lib, "winmm.lib") + #include + VOID FreeDirectInput(); // Needed in both nJoy.cpp and Rumble.cpp + #endif #endif // _WIN32 #ifdef _WIN32 @@ -75,6 +76,7 @@ #include #endif + ////////////////////////////////////////////////////////////////////////////////////////// // Define // ŻŻŻŻŻŻ @@ -86,6 +88,7 @@ #define RELYEAR "2008" #define THANKYOU "`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." + ////////////////////////////////////////////////////////////////////////////////////////// // Structures // ŻŻŻŻŻŻŻŻŻŻ @@ -158,6 +161,18 @@ enum CTL_D_PAD_RIGHT }; + +////////////////////////////////////////////////////////////////////////////////////////// +// Variables +// ŻŻŻŻŻŻŻŻŻ +#ifndef _CONTROLLER_STATE_H + extern FILE *pFile; + extern CONTROLLER_STATE joystate[4]; + extern CONTROLLER_MAPPING joysticks[4]; + extern HWND m_hWnd; // Handle to window +#endif + + ////////////////////////////////////////////////////////////////////////////////////////// // Custom Functions // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ @@ -167,5 +182,7 @@ int Search_Devices(); void DEBUG_INIT(); void DEBUG_QUIT(); +void PAD_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus); // Rumble + void SaveConfig(); void LoadConfig();