From 5ccbcf455e437031cb2542db0804a341cc9150cc Mon Sep 17 00:00:00 2001 From: skidau Date: Sun, 30 Dec 2012 13:41:48 +1100 Subject: [PATCH 01/16] Added preliminary GameCube Steering Wheel emulation via a PC Force Feedback Steering Wheel. --- Source/Core/Core/CMakeLists.txt | 1 + Source/Core/Core/Core.vcxproj | 2 + Source/Core/Core/Core.vcxproj.filters | 6 + Source/Core/Core/Src/HW/GCPad.cpp | 27 +- Source/Core/Core/Src/HW/GCPad.h | 1 + Source/Core/Core/Src/HW/GCPadEmu.cpp | 7 +- Source/Core/Core/Src/HW/GCPadEmu.h | 2 +- Source/Core/Core/Src/HW/SI_Device.cpp | 5 + .../Core/Src/HW/SI_DeviceGCSteeringWheel.cpp | 301 ++++++++++++++++++ .../Core/Src/HW/SI_DeviceGCSteeringWheel.h | 118 +++++++ Source/Core/Core/Src/NetPlay.cpp | 11 + Source/Core/DolphinWX/Src/ConfigMain.cpp | 13 +- .../DInput/DInputJoystick.cpp | 27 +- 13 files changed, 506 insertions(+), 15 deletions(-) create mode 100644 Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp create mode 100644 Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.h diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 124d7aa879..6ffeeaec3a 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -115,6 +115,7 @@ set(SRCS Src/ActionReplay.cpp Src/HW/SI_Device.cpp Src/HW/SI_DeviceGBA.cpp Src/HW/SI_DeviceGCController.cpp + Src/HW/SI_DeviceGCSteeringWheel.cpp Src/HW/Sram.cpp Src/HW/StreamADPCM.cpp Src/HW/SystemTimers.cpp diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index e626ccd033..bd3d97f11b 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -301,6 +301,7 @@ + @@ -503,6 +504,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index ad6db227d5..246dafd972 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -290,6 +290,9 @@ HW %28Flipper/Hollywood%29\SI - Serial Interface + + HW %28Flipper/Hollywood%29\SI - Serial Interface + HW %28Flipper/Hollywood%29\VI - Video Interface @@ -814,6 +817,9 @@ HW %28Flipper/Hollywood%29\SI - Serial Interface + + HW %28Flipper/Hollywood%29\SI - Serial Interface + HW %28Flipper/Hollywood%29\SI - Serial Interface diff --git a/Source/Core/Core/Src/HW/GCPad.cpp b/Source/Core/Core/Src/HW/GCPad.cpp index 4c1b4dabdd..61b666af12 100644 --- a/Source/Core/Core/Src/HW/GCPad.cpp +++ b/Source/Core/Core/Src/HW/GCPad.cpp @@ -101,7 +101,32 @@ void Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) { // TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time // set rumble - ((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput( 1 == _uType && _uStrength > 2 ); + if (1 == _uType && _uStrength > 2) + { + ((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput(255); + } + } +} + +// __________________________________________________________________________________________________ +// Function: Motor +// Purpose: For devices with constant Force feedback +// input: Type - 06 = Motor On, 04 = Motor Off +// Strength - 00 = Left Strong, 127 = Left Weak, 128 = Right Weak, 255 = Right Strong +// output: none +// +void Motor(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) +{ + std::unique_lock lk(g_plugin.controls_lock, std::try_to_lock); + + if (lk.owns_lock()) + { + // TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time + // set rumble + if (_uType == 06) + { + ((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput(_uStrength); + } } } diff --git a/Source/Core/Core/Src/HW/GCPad.h b/Source/Core/Core/Src/HW/GCPad.h index f7f6af2f20..fb07e82ccc 100644 --- a/Source/Core/Core/Src/HW/GCPad.h +++ b/Source/Core/Core/Src/HW/GCPad.h @@ -32,6 +32,7 @@ InputPlugin *GetPlugin(); void GetStatus(u8 _numPAD, SPADStatus* _pPADStatus); void Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength); +void Motor(u8 _numPAD, unsigned int _uType, unsigned int _uStrength); bool GetMicButton(u8 pad); } diff --git a/Source/Core/Core/Src/HW/GCPadEmu.cpp b/Source/Core/Core/Src/HW/GCPadEmu.cpp index 837c9104cc..5233ed2877 100644 --- a/Source/Core/Core/Src/HW/GCPadEmu.cpp +++ b/Source/Core/Core/Src/HW/GCPadEmu.cpp @@ -130,10 +130,13 @@ void GCPad::GetInput(SPADStatus* const pad) } } -void GCPad::SetOutput(const bool on) +void GCPad::SetOutput(const u8 on) { // only rumble if window has focus or background input is enabled - m_rumble->controls[0]->control_ref->State(on && (Host_RendererHasFocus() || m_options[0].settings[0]->value)); + if (Host_RendererHasFocus() || m_options[0].settings[0]->value) + m_rumble->controls[0]->control_ref->State((float)on / 255); + else + m_rumble->controls[0]->control_ref->State(0); } void GCPad::LoadDefaults(const ControllerInterface& ciface) diff --git a/Source/Core/Core/Src/HW/GCPadEmu.h b/Source/Core/Core/Src/HW/GCPadEmu.h index 5185ff221c..cf0940245e 100644 --- a/Source/Core/Core/Src/HW/GCPadEmu.h +++ b/Source/Core/Core/Src/HW/GCPadEmu.h @@ -28,7 +28,7 @@ public: GCPad(const unsigned int index); void GetInput(SPADStatus* const pad); - void SetOutput(const bool on); + void SetOutput(const u8 on); bool GetMicButton() const; diff --git a/Source/Core/Core/Src/HW/SI_Device.cpp b/Source/Core/Core/Src/HW/SI_Device.cpp index 8abddbe472..062499f16f 100644 --- a/Source/Core/Core/Src/HW/SI_Device.cpp +++ b/Source/Core/Core/Src/HW/SI_Device.cpp @@ -17,6 +17,7 @@ #include "SI_Device.h" #include "SI_DeviceGCController.h" +#include "SI_DeviceGCSteeringWheel.h" #include "SI_DeviceGBA.h" #include "SI_DeviceAMBaseboard.h" @@ -76,6 +77,10 @@ ISIDevice* SIDevice_Create(const SIDevices device, const int port_number) return new CSIDevice_GCController(device, port_number); break; + case SIDEVICE_GC_STEERING: + return new CSIDevice_GCSteeringWheel(device, port_number); + break; + case SIDEVICE_GC_TARUKONGA: return new CSIDevice_TaruKonga(device, port_number); break; diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp new file mode 100644 index 0000000000..113fe186b1 --- /dev/null +++ b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp @@ -0,0 +1,301 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include + +#include "SI.h" +#include "SI_Device.h" +#include "SI_DeviceGCSteeringWheel.h" + +#include "EXI_Device.h" +#include "EXI_DeviceMic.h" + +#include "GCPad.h" + +#include "../Movie.h" + +#include "../CoreTiming.h" +#include "SystemTimers.h" +#include "ProcessorInterface.h" +#include "../Core.h" + +// --- standard gamecube controller --- +CSIDevice_GCSteeringWheel::CSIDevice_GCSteeringWheel(SIDevices device, int _iDeviceNumber) + : ISIDevice(device, _iDeviceNumber) + , m_TButtonComboStart(0) + , m_TButtonCombo(0) + , m_LastButtonCombo(COMBO_NONE) +{ + memset(&m_Origin, 0, sizeof(SOrigin)); + m_Origin.uCommand = CMD_ORIGIN; + m_Origin.uOriginStickX = 0x80; // center + m_Origin.uOriginStickY = 0x80; + m_Origin.uSubStickStickX = 0x80; + m_Origin.uSubStickStickY = 0x80; + m_Origin.uTrigger_L = 0x1F; // 0-30 is the lower deadzone + m_Origin.uTrigger_R = 0x1F; + + // Dunno if we need to do this, game/lib should set it? + m_Mode = 0x03; +} + +int CSIDevice_GCSteeringWheel::RunBuffer(u8* _pBuffer, int _iLength) +{ + // For debug logging only + ISIDevice::RunBuffer(_pBuffer, _iLength); + + // Read the command + EBufferCommands command = static_cast(_pBuffer[3]); + + // Handle it + switch (command) + { + case CMD_RESET: + *(u32*)&_pBuffer[0] = SI_GC_STEERING; + break; + + case CMD_ORIGIN: + { + INFO_LOG(SERIALINTERFACE, "PAD - Get Origin"); + u8* pCalibration = reinterpret_cast(&m_Origin); + for (int i = 0; i < (int)sizeof(SOrigin); i++) + { + _pBuffer[i ^ 3] = *pCalibration++; + } + } + break; + + // Recalibrate (FiRES: i am not 100 percent sure about this) + case CMD_RECALIBRATE: + { + INFO_LOG(SERIALINTERFACE, "PAD - Recalibrate"); + u8* pCalibration = reinterpret_cast(&m_Origin); + for (int i = 0; i < (int)sizeof(SOrigin); i++) + { + _pBuffer[i ^ 3] = *pCalibration++; + } + } + break; + + // DEFAULT + default: + { + ERROR_LOG(SERIALINTERFACE, "unknown SI command (0x%x)", command); + } + break; + } + + return _iLength; +} + + +// GetData + +// Return true on new data (max 7 Bytes and 6 bits ;) +// [00?SYXBA] [1LRZUDRL] [x] [y] [cx] [cy] [l] [r] +// |\_ ERR_LATCH (error latched - check SISR) +// |_ ERR_STATUS (error on last GetData or SendCmd?) +bool CSIDevice_GCSteeringWheel::GetData(u32& _Hi, u32& _Low) +{ + SPADStatus PadStatus; + memset(&PadStatus, 0, sizeof(PadStatus)); + + Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); + Movie::CallInputManip(&PadStatus, ISIDevice::m_iDeviceNumber); + + u32 netValues[2]; + if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, PadStatus, netValues)) + { + _Hi = netValues[0]; // first 4 bytes + _Low = netValues[1]; // last 4 bytes + return true; + } + + Movie::SetPolledDevice(); + + if(Movie::IsPlayingInput()) + { + Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber); + if(!Movie::IsUsingWiimote(0)) + Movie::InputUpdate(); + } + else if(Movie::IsRecordingInput()) + { + Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber); + if(!Movie::IsUsingWiimote(0)) + Movie::InputUpdate(); + } + else + Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); + + // Thankfully changing mode does not change the high bits ;) + _Hi = (u32)((u8)PadStatus.stickY); + _Hi |= (u32)((u8)PadStatus.stickX << 8); + _Hi |= (u32)((u16)(PadStatus.button | PAD_USE_ORIGIN) << 16); + + // Low bits are packed differently per mode + if (m_Mode == 0 || m_Mode == 5 || m_Mode == 6 || m_Mode == 7) + { + _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 8); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 12); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.substickY) << 16); // All 8 bits + _Low |= (u32)((u8)(PadStatus.substickX) << 24); // All 8 bits + } + else if (m_Mode == 1) + { + _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits + _Low |= (u32)((u8)PadStatus.triggerRight << 8); // All 8 bits + _Low |= (u32)((u8)PadStatus.triggerLeft << 16); // All 8 bits + _Low |= (u32)((u8)PadStatus.substickY << 24); // Top 4 bits + _Low |= (u32)((u8)PadStatus.substickX << 28); // Top 4 bits + } + else if (m_Mode == 2) + { + _Low = (u8)(PadStatus.analogB); // All 8 bits + _Low |= (u32)((u8)(PadStatus.analogA) << 8); // All 8 bits + _Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 16); // Top 4 bits + _Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 20); // Top 4 bits + _Low |= (u32)((u8)PadStatus.substickY << 24); // Top 4 bits + _Low |= (u32)((u8)PadStatus.substickX << 28); // Top 4 bits + } + else if (m_Mode == 3) + { + // Analog A/B are always 0 + _Low = (u8)PadStatus.triggerRight; // All 8 bits + _Low |= (u32)((u8)PadStatus.triggerLeft << 8); // All 8 bits + _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits + _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits + } + else if (m_Mode == 4) + { + _Low = (u8)(PadStatus.analogB); // All 8 bits + _Low |= (u32)((u8)(PadStatus.analogA) << 8); // All 8 bits + // triggerLeft/Right are always 0 + _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits + _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits + } + + // Keep track of the special button combos (embedded in controller hardware... :( ) + EButtonCombo tempCombo; + if ((PadStatus.button & 0xff00) == (PAD_BUTTON_Y|PAD_BUTTON_X|PAD_BUTTON_START)) + tempCombo = COMBO_ORIGIN; + else if ((PadStatus.button & 0xff00) == (PAD_BUTTON_B|PAD_BUTTON_X|PAD_BUTTON_START)) + tempCombo = COMBO_RESET; + else + tempCombo = COMBO_NONE; + if (tempCombo != m_LastButtonCombo) + { + m_LastButtonCombo = tempCombo; + if (m_LastButtonCombo != COMBO_NONE) + m_TButtonComboStart = CoreTiming::GetTicks(); + } + if (m_LastButtonCombo != COMBO_NONE) + { + m_TButtonCombo = CoreTiming::GetTicks(); + if ((m_TButtonCombo - m_TButtonComboStart) > SystemTimers::GetTicksPerSecond() * 3) + { + if (m_LastButtonCombo == COMBO_RESET) + ProcessorInterface::ResetButton_Tap(); + else if (m_LastButtonCombo == COMBO_ORIGIN) + { + m_Origin.uOriginStickX = PadStatus.stickX; + m_Origin.uOriginStickY = PadStatus.stickY; + m_Origin.uSubStickStickX = PadStatus.substickX; + m_Origin.uSubStickStickY = PadStatus.substickY; + m_Origin.uTrigger_L = PadStatus.triggerLeft; + m_Origin.uTrigger_R = PadStatus.triggerRight; + } + m_LastButtonCombo = COMBO_NONE; + } + } + + return true; +} + + +// SendCommand +void CSIDevice_GCSteeringWheel::SendCommand(u32 _Cmd, u8 _Poll) +{ + UCommand command(_Cmd); + + switch (command.Command) + { + // Costis sent it in some demos :) + case 0x00: + break; + + case CMD_FORCE: + { + unsigned int uStrength = command.Parameter1; // 0 = left strong, 127 = left weak, 128 = right weak, 255 = right strong + unsigned int uType = command.Parameter2; // 06 = motor on, 04 = motor off + + // get the correct pad number that should rumble locally when using netplay + const u8 numPAD = NetPlay_GetPadNum(ISIDevice::m_iDeviceNumber); + + NOTICE_LOG(COMMON, "Type: %d Strength: %d", uType, uStrength); + + if (numPAD < 4) + Pad::Motor(numPAD, uType, uStrength); + + if (!_Poll) + { + m_Mode = command.Parameter2; + INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode); + } + } + break; + + case CMD_WRITE: + { + unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard + unsigned int uStrength = command.Parameter2; + + // get the correct pad number that should rumble locally when using netplay + const u8 numPAD = NetPlay_GetPadNum(ISIDevice::m_iDeviceNumber); + + if (numPAD < 4) + Pad::Rumble(numPAD, uType, uStrength); + + if (!_Poll) + { + m_Mode = command.Parameter2; + INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode); + } + } + break; + + default: + { + ERROR_LOG(SERIALINTERFACE, "unknown direct command (0x%x)", _Cmd); + } + break; + } +} + +// Savestate support +void CSIDevice_GCSteeringWheel::DoState(PointerWrap& p) +{ + p.Do(m_Origin); + p.Do(m_Mode); + p.Do(m_TButtonComboStart); + p.Do(m_TButtonCombo); + p.Do(m_LastButtonCombo); +} diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.h b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.h new file mode 100644 index 0000000000..1814c8d6e4 --- /dev/null +++ b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.h @@ -0,0 +1,118 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _SI_DEVICEGCSTEERINGWHEEL_H +#define _SI_DEVICEGCSTEERINGWHEEL_H + +#include "SI_Device.h" +#include "GCPadStatus.h" + + +// standard gamecube controller +class CSIDevice_GCSteeringWheel : public ISIDevice +{ +private: + + // Commands + enum EBufferCommands + { + CMD_RESET = 0x00, + CMD_ORIGIN = 0x41, + CMD_RECALIBRATE = 0x42, + }; + + struct SOrigin + { + u8 uCommand;// Maybe should be button bits? + u8 unk_1; // ..and this would be the other half + u8 uOriginStickX; + u8 uOriginStickY; + u8 uSubStickStickX; + u8 uSubStickStickY; + u8 uTrigger_L; + u8 uTrigger_R; + u8 unk_4; + u8 unk_5; + u8 unk_6; + u8 unk_7; + }; + + enum EDirectCommands + { + CMD_FORCE = 0x30, + CMD_WRITE = 0x40 + }; + + union UCommand + { + u32 Hex; + struct + { + u32 Parameter1 : 8; + u32 Parameter2 : 8; + u32 Command : 8; + u32 : 8; + }; + UCommand() {Hex = 0;} + UCommand(u32 _iValue) {Hex = _iValue;} + }; + + enum EButtonCombo + { + COMBO_NONE = 0, + COMBO_ORIGIN, + COMBO_RESET + }; + + // struct to compare input against + // Set on connection and (standard pad only) on button combo + SOrigin m_Origin; + + // PADAnalogMode + u8 m_Mode; + + // Timer to track special button combos: + // y, X, start for 3 seconds updates origin with current status + // Technically, the above is only on standard pad, wavebird does not support it for example + // b, x, start for 3 seconds triggers reset (PI reset button interrupt) + u64 m_TButtonComboStart, m_TButtonCombo; + // Type of button combo from the last/current poll + EButtonCombo m_LastButtonCombo; + +public: + + // Constructor + CSIDevice_GCSteeringWheel(SIDevices device, int _iDeviceNumber); + + // Run the SI Buffer + virtual int RunBuffer(u8* _pBuffer, int _iLength); + + // Send and Receive pad input from network + static bool NetPlay_GetInput(u8 numPAD, SPADStatus status, u32 *PADStatus); + static u8 NetPlay_GetPadNum(u8 numPAD); + + // Return true on new data + virtual bool GetData(u32& _Hi, u32& _Low); + + // Send a command directly + virtual void SendCommand(u32 _Cmd, u8 _Poll); + + // Savestate support + virtual void DoState(PointerWrap& p); +}; + +#endif diff --git a/Source/Core/Core/Src/NetPlay.cpp b/Source/Core/Core/Src/NetPlay.cpp index 1c19f763ec..05331bc6cc 100644 --- a/Source/Core/Core/Src/NetPlay.cpp +++ b/Source/Core/Core/Src/NetPlay.cpp @@ -22,6 +22,7 @@ #include "IPC_HLE/WII_IPC_HLE_WiiMote.h" // for gcpad #include "HW/SI_DeviceGCController.h" +#include "HW/SI_DeviceGCSteeringWheel.h" // for gctime #include "HW/EXI_DeviceIPL.h" // for wiimote/ OSD messages @@ -296,6 +297,11 @@ bool CSIDevice_GCController::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u return false; } +bool CSIDevice_GCSteeringWheel::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus) +{ + return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus); +} + // called from ---CPU--- thread // so all players' games get the same time u32 CEXIIPL::NetPlay_GetGCTime() @@ -320,6 +326,11 @@ u8 CSIDevice_GCController::NetPlay_GetPadNum(u8 numPAD) return numPAD; } +u8 CSIDevice_GCSteeringWheel::NetPlay_GetPadNum(u8 numPAD) +{ + return CSIDevice_GCController::NetPlay_GetPadNum(numPAD); +} + // called from ---CPU--- thread // wiimote update / used for frame counting //void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number) diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index 76508daf7c..6e9987b1f4 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -79,6 +79,7 @@ static const wxLanguage langIds[] = #define DEV_DUMMY_STR _trans("Dummy") #define SIDEV_STDCONT_STR _trans("Standard Controller") +#define SIDEV_STEERING_STR _trans("Steering Wheel") #define SIDEV_BONGO_STR _trans("TaruKonga (Bongos)") #define SIDEV_GBA_STR "GBA" #define SIDEV_AM_BB_STR _trans("AM-Baseboard") @@ -391,6 +392,7 @@ void CConfigMain::InitializeGUIValues() wxArrayString SIDevices; SIDevices.Add(_(DEV_NONE_STR)); SIDevices.Add(_(SIDEV_STDCONT_STR)); + SIDevices.Add(_(SIDEV_STEERING_STR)); SIDevices.Add(_(SIDEV_BONGO_STR)); SIDevices.Add(_(SIDEV_GBA_STR)); SIDevices.Add(_(SIDEV_AM_BB_STR)); @@ -443,15 +445,18 @@ void CConfigMain::InitializeGUIValues() case SIDEVICE_GC_CONTROLLER: GCSIDevice[i]->SetStringSelection(SIDevices[1]); break; - case SIDEVICE_GC_TARUKONGA: + case SIDEVICE_GC_STEERING: GCSIDevice[i]->SetStringSelection(SIDevices[2]); break; - case SIDEVICE_GC_GBA: + case SIDEVICE_GC_TARUKONGA: GCSIDevice[i]->SetStringSelection(SIDevices[3]); break; - case SIDEVICE_AM_BASEBOARD: + case SIDEVICE_GC_GBA: GCSIDevice[i]->SetStringSelection(SIDevices[4]); break; + case SIDEVICE_AM_BASEBOARD: + GCSIDevice[i]->SetStringSelection(SIDevices[5]); + break; default: GCSIDevice[i]->SetStringSelection(SIDevices[0]); break; @@ -1053,6 +1058,8 @@ void CConfigMain::ChooseSIDevice(wxString deviceName, int deviceNum) SIDevices tempType; if (!deviceName.compare(WXSTR_TRANS(SIDEV_STDCONT_STR))) tempType = SIDEVICE_GC_CONTROLLER; + else if (!deviceName.compare(WXSTR_TRANS(SIDEV_STEERING_STR))) + tempType = SIDEVICE_GC_STEERING; else if (!deviceName.compare(WXSTR_TRANS(SIDEV_BONGO_STR))) tempType = SIDEVICE_GC_TARUKONGA; else if (!deviceName.compare(wxT(SIDEV_GBA_STR))) diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp index 08d62bcfc1..5f80b6f32b 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp @@ -145,7 +145,7 @@ LCleanup: void InitJoystick(IDirectInput8* const idi8, std::vector& devices, HWND hwnd) { std::list joysticks; - idi8->EnumDevices( DI8DEVCLASS_GAMECTRL, DIEnumDevicesCallback, (LPVOID)&joysticks, DIEDFL_ATTACHEDONLY ); + idi8->EnumDevices( DI8DEVCLASS_GAMECTRL, DIEnumDevicesCallback, (LPVOID)&joysticks, DIEDFL_FORCEFEEDBACK | DIEDFL_ATTACHEDONLY ); // this is used to number the joysticks // multiple joysticks with the same name shall get unique ids starting at 0 @@ -254,9 +254,9 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI for (unsigned int offset = 0; offset < DIJOFS_BUTTON(0) / sizeof(LONG); ++offset) { range.diph.dwObj = offset * sizeof(LONG); - // try to set some nice power of 2 values (8192) - range.lMin = -(1 << 13); - range.lMax = (1 << 13); + // try to set some nice power of 2 values (128) to match the GameCube controls + range.lMin = -(1 << 7); + range.lMax = (1 << 7); m_device->SetProperty(DIPROP_RANGE, &range.diph); // but i guess not all devices support setting range // so i getproperty right afterward incase it didn't set :P @@ -281,17 +281,19 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI if ( objects.size() ) { // temporary - DWORD rgdwAxes[] = {DIJOFS_X, DIJOFS_Y}; - LONG rglDirection[] = {0, 0}; + DWORD rgdwAxes[2] = {DIJOFS_X, DIJOFS_Y}; + LONG rglDirection[2] = {-200, 0}; DIEFFECT eff; ZeroMemory(&eff, sizeof(eff)); eff.dwSize = sizeof(DIEFFECT); eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; eff.dwDuration = INFINITE; // (4 * DI_SECONDS) + eff.dwSamplePeriod = 0; eff.dwGain = DI_FFNOMINALMAX; eff.dwTriggerButton = DIEB_NOTRIGGER; - eff.cAxes = std::min((DWORD)2, (DWORD)objects.size()); + eff.dwTriggerRepeatInterval = 0; + eff.cAxes = std::min((DWORD)1, (DWORD)objects.size()); eff.rgdwAxes = rgdwAxes; eff.rglDirection = rglDirection; @@ -310,7 +312,12 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI { // ugly if ladder if (0 == f) + { + DICONSTANTFORCE diCF = {-10000}; + diCF.lMagnitude = DI_FFNOMINALMAX; eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + eff.lpvTypeSpecificParams = &diCF; + } else if (1 == f) eff.cbTypeSpecificParams = sizeof(DIRAMPFORCE); else @@ -528,7 +535,11 @@ ControlState Joystick::Hat::GetState() const void Joystick::ForceConstant::SetState(const ControlState state) { - const LONG new_val = LONG(10000 * state); + float force = abs(state - 0.5) * 2; + if (state < 0.5) + force = -force; + + const LONG new_val = LONG(10000 * force); LONG &val = params.lMagnitude; if (val != new_val) From 51603f052220b6240ac9c316ab791c3738e260ef Mon Sep 17 00:00:00 2001 From: skidau Date: Tue, 1 Jan 2013 13:49:22 +1100 Subject: [PATCH 02/16] * Implemented working pedal support. * Changed the mapping of the steering wheel to: Main Stick Left/Right = Steer Left/Right Main Stick Up = Accelerate Main Stick Down = Brake * Fixed non-force feedback controllers that were not detected --- .../Core/Src/HW/SI_DeviceGCSteeringWheel.cpp | 23 ++++++++++++++++--- .../Core/Src/HW/SI_DeviceGCSteeringWheel.h | 1 + .../DInput/DInputJoystick.cpp | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp index 113fe186b1..7783261da9 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp @@ -92,6 +92,10 @@ int CSIDevice_GCSteeringWheel::RunBuffer(u8* _pBuffer, int _iLength) } break; + // Seen in F-Zero GX + case CMD_MOTOR_OFF: + break; + // DEFAULT default: { @@ -144,12 +148,12 @@ bool CSIDevice_GCSteeringWheel::GetData(u32& _Hi, u32& _Low) Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); // Thankfully changing mode does not change the high bits ;) - _Hi = (u32)((u8)PadStatus.stickY); - _Hi |= (u32)((u8)PadStatus.stickX << 8); + _Hi = (u32)((u8)PadStatus.stickX); // Steering + _Hi |= 0x800; // Pedal connected flag _Hi |= (u32)((u16)(PadStatus.button | PAD_USE_ORIGIN) << 16); // Low bits are packed differently per mode - if (m_Mode == 0 || m_Mode == 5 || m_Mode == 6 || m_Mode == 7) + if (m_Mode == 0 || m_Mode == 5 || m_Mode == 7) { _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits @@ -192,6 +196,19 @@ bool CSIDevice_GCSteeringWheel::GetData(u32& _Hi, u32& _Low) _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits } + else if (m_Mode == 6) + { + _Low = (u8)PadStatus.triggerRight; // All 8 bits + _Low |= (u32)((u8)PadStatus.triggerLeft << 8); // All 8 bits + + // The GC Steering Wheel appears to have combined pedals + // (both the Accelerate and Brake pedals are mapped to a single axis) + // We use the stickY axis for the pedals. + if (PadStatus.stickY < 128) + _Low |= (u32)((u8)(255 - ((PadStatus.stickY & 0x7f) * 2)) << 16); // All 8 bits (Brake) + if (PadStatus.stickY >= 128) + _Low |= (u32)((u8)((PadStatus.stickY & 0x7f) * 2) << 24); // All 8 bits (Accelerate) + } // Keep track of the special button combos (embedded in controller hardware... :( ) EButtonCombo tempCombo; diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.h b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.h index 1814c8d6e4..2245765863 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.h +++ b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.h @@ -33,6 +33,7 @@ private: CMD_RESET = 0x00, CMD_ORIGIN = 0x41, CMD_RECALIBRATE = 0x42, + CMD_MOTOR_OFF = 0xff, }; struct SOrigin diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp index 5f80b6f32b..b7ac3bf82e 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp @@ -145,7 +145,7 @@ LCleanup: void InitJoystick(IDirectInput8* const idi8, std::vector& devices, HWND hwnd) { std::list joysticks; - idi8->EnumDevices( DI8DEVCLASS_GAMECTRL, DIEnumDevicesCallback, (LPVOID)&joysticks, DIEDFL_FORCEFEEDBACK | DIEDFL_ATTACHEDONLY ); + idi8->EnumDevices( DI8DEVCLASS_GAMECTRL, DIEnumDevicesCallback, (LPVOID)&joysticks, DIEDFL_ATTACHEDONLY ); // this is used to number the joysticks // multiple joysticks with the same name shall get unique ids starting at 0 From 9af711b12c8248f3f806725644e93fdf9024bd37 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Mon, 31 Dec 2012 21:57:39 -0500 Subject: [PATCH 03/16] Always count GC wheel inputs too. --- Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp index 7783261da9..f69ccd2fc1 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp @@ -135,14 +135,12 @@ bool CSIDevice_GCSteeringWheel::GetData(u32& _Hi, u32& _Low) if(Movie::IsPlayingInput()) { Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber); - if(!Movie::IsUsingWiimote(0)) - Movie::InputUpdate(); + Movie::InputUpdate(); } else if(Movie::IsRecordingInput()) { Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber); - if(!Movie::IsUsingWiimote(0)) - Movie::InputUpdate(); + Movie::InputUpdate(); } else Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); From 3fd1b4ee83e02de1d9ed8d145ec21b88c16b523c Mon Sep 17 00:00:00 2001 From: skidau Date: Tue, 1 Jan 2013 15:13:18 +1100 Subject: [PATCH 04/16] Removed some debug testing code. --- Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp index f69ccd2fc1..ade19b758e 100644 --- a/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp +++ b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp @@ -265,8 +265,6 @@ void CSIDevice_GCSteeringWheel::SendCommand(u32 _Cmd, u8 _Poll) // get the correct pad number that should rumble locally when using netplay const u8 numPAD = NetPlay_GetPadNum(ISIDevice::m_iDeviceNumber); - NOTICE_LOG(COMMON, "Type: %d Strength: %d", uType, uStrength); - if (numPAD < 4) Pad::Motor(numPAD, uType, uStrength); From 5fbce28bbce934bbe01cb8cd9acb853e6c8f1707 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Tue, 1 Jan 2013 16:18:52 -0500 Subject: [PATCH 05/16] Save git hash to .dtm header. --- Source/Core/Core/Src/Movie.cpp | 8 ++++++++ Source/Core/Core/Src/Movie.h | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/Movie.cpp b/Source/Core/Core/Src/Movie.cpp index 5eb1660d8e..316181d449 100644 --- a/Source/Core/Core/Src/Movie.cpp +++ b/Source/Core/Core/Src/Movie.cpp @@ -36,6 +36,7 @@ #include "HW/DVDInterface.h" #include "../../Common/Src/NandPaths.h" #include "Crypto/md5.h" +#include "scmrev.h" // The chunk to allocate movie data in multiples of. #define DTM_BASE_LENGTH (1024) @@ -72,6 +73,7 @@ std::string author = ""; u64 g_titleID = 0; unsigned char MD5[16]; u8 bongos; +u8 revision[20]; bool g_bRecordingFromSaveState = false; bool g_bPolled = false; @@ -687,6 +689,7 @@ void ReadHeader() g_bClearSave = tmpHeader.bClearSave; bMemcard = tmpHeader.bMemcard; bongos = tmpHeader.bongos; + memcpy(revision, tmpHeader.revision, ARRAYSIZE(revision)); } else { @@ -1132,6 +1135,7 @@ void SaveRecording(const char *filename) strncpy((char *)header.author, author.c_str(),ARRAYSIZE(header.author)); memcpy(header.md5,MD5,16); header.bongos = bongos; + memcpy(header.revision, revision, ARRAYSIZE(header.revision)); // TODO header.uniqueID = 0; @@ -1189,6 +1193,10 @@ void GetSettings() if (!Core::g_CoreStartupParameter.bWii) g_bClearSave = !File::Exists(SConfig::GetInstance().m_strMemoryCardA); bMemcard = SConfig::GetInstance().m_EXIDevice[0] == EXIDEVICE_MEMORYCARD; + + std::stringstream ss; + ss << std::hex << SCM_REV_STR; + ss >> revision; } void CheckMD5() diff --git a/Source/Core/Core/Src/Movie.h b/Source/Core/Core/Src/Movie.h index 2cb4c78e23..79b5e72f29 100644 --- a/Source/Core/Core/Src/Movie.h +++ b/Source/Core/Core/Src/Movie.h @@ -121,7 +121,8 @@ struct DTMHeader { u8 bongos; u8 reserved[15]; // Padding for any new config options u8 discChange[40]; // Name of iso file to switch to, for two disc games. - u8 reserved2[47]; // Make heading 256 bytes, just because we can + u8 revision[20]; // Git hash + u8 reserved2[27]; // Make heading 256 bytes, just because we can }; static_assert(sizeof(DTMHeader) == 256, "DTMHeader should be 256 bytes"); From 91023e133b4639f93fbcdb153f66179f7b9b5dff Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Wed, 2 Jan 2013 01:21:20 -0500 Subject: [PATCH 06/16] Move widescreen hack to enhancements tab. --- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 20bd4dfb38..f59c7c34c9 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -405,6 +405,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con _3d_vision = CreateCheckBox(page_enh, _("3D Vision"), wxGetTranslation(_3d_vision_desc), vconfig.b3DVision); _3d_vision->Show(vconfig.backend_info.bSupports3DVision); szr_enh->Add(_3d_vision); + szr_enh->Add(CreateCheckBox(page_enh, _("Widescreen Hack"), wxGetTranslation(ws_hack_desc), vconfig.bWidescreenHack)); // TODO: Add anaglyph 3d here wxStaticBoxSizer* const group_enh = new wxStaticBoxSizer(wxVERTICAL, page_enh, _("Enhancements")); @@ -553,8 +554,6 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con szr_misc->Add(CreateCheckBox(page_advanced, _("Crop"), wxGetTranslation(crop_desc), vconfig.bCrop)); szr_misc->Add(CreateCheckBox(page_advanced, _("Enable Hotkeys"), wxGetTranslation(hotkeys_desc), vconfig.bOSDHotKey)); - szr_misc->Add(CreateCheckBox(page_advanced, _("Widescreen Hack"), wxGetTranslation(ws_hack_desc), vconfig.bWidescreenHack)); - // Progressive Scan { wxCheckBox* const cb_prog_scan = new wxCheckBox(page_advanced, wxID_ANY, _("Enable Progressive Scan")); From 3da05af30ab82639b5898f6ef46326bdd2f1dc7e Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Thu, 3 Jan 2013 10:35:07 -0600 Subject: [PATCH 07/16] Fix truncated names and descriptions in the game list on linux. --- Source/Core/Common/Src/ChunkFile.h | 9 ++++++++- Source/Core/DolphinWX/Src/GameListCtrl.cpp | 15 ++++++++------- Source/Core/DolphinWX/Src/ISOFile.cpp | 6 +++--- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Source/Core/Common/Src/ChunkFile.h b/Source/Core/Common/Src/ChunkFile.h index be8b49a3a3..e26536735d 100644 --- a/Source/Core/Common/Src/ChunkFile.h +++ b/Source/Core/Common/Src/ChunkFile.h @@ -155,7 +155,14 @@ public: Do(stringLen); switch (mode) { - case MODE_READ: x = (wchar_t*)*ptr; break; + case MODE_READ: + { + wchar_t* tmp = new wchar_t[stringLen / sizeof(wchar_t)]; + memcpy(tmp, *ptr, stringLen); + x = tmp; + delete[] tmp; + } + break; case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; case MODE_MEASURE: break; case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (wchar_t*)*ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index fbefb1c769..c67ee83ed3 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -464,14 +464,15 @@ void CGameListCtrl::InsertItemInReportView(long _Index) SelectedLanguage = 0; default: { - wxCSConv WindowsCP1252(wxFontMapper::GetEncodingName(wxFONTENCODING_CP1252)); - rISOFile.GetName(wstring_name, SelectedLanguage); + wxCSConv WindowsCP1252(wxFontMapper::GetEncodingName(wxFONTENCODING_CP1252)); + rISOFile.GetName(wstring_name, SelectedLanguage); - name = wxString(rISOFile.GetName(SelectedLanguage).c_str(), WindowsCP1252); - m_gameList.append(StringFromFormat("%s (%c)\n", - rISOFile.GetName(SelectedLanguage).c_str(), (rISOFile.GetCountry() == DiscIO::IVolume::COUNTRY_USA)?'U':'E')); - description = wxString(company.size() ? company.c_str() : - rISOFile.GetDescription(SelectedLanguage).c_str(), WindowsCP1252); + name = wxString(rISOFile.GetName(SelectedLanguage).c_str(), WindowsCP1252); + m_gameList.append(StringFromFormat("%s (%c)\n", + rISOFile.GetName(SelectedLanguage).c_str(), + (rISOFile.GetCountry() == DiscIO::IVolume::COUNTRY_USA) ? 'U' : 'E')); + description = wxString(company.size() ? company.c_str() : + rISOFile.GetDescription(SelectedLanguage).c_str(), WindowsCP1252); } break; } diff --git a/Source/Core/DolphinWX/Src/ISOFile.cpp b/Source/Core/DolphinWX/Src/ISOFile.cpp index a3d3761e62..a00ce2c496 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.cpp +++ b/Source/Core/DolphinWX/Src/ISOFile.cpp @@ -140,8 +140,8 @@ GameListItem::GameListItem(const std::string& _rFileName) SplitPath(m_FileName, NULL, &FileName, NULL); int length = FileName.length(); wFileName.reserve(length+1); - for (int i = 0; i < length; ++i) - wFileName.push_back(FileName[i]); + for (int j = 0; j < length; ++j) + wFileName.push_back(FileName[j]); wFileName.push_back(0); } *i = wFileName; @@ -283,7 +283,7 @@ bool GameListItem::GetName(std::wstring& wName, int index) const // This function will only succeed for wii discs with banners or WADs // utilize the same array as for gc discs (-1= Japanese, 0 = English etc index++; - if ((index >=0) && (index < 10)) + if ((index >= 0) && (index < 10)) { if (m_wNames.size() > (size_t)index) { From 4f531fe1229b2f18b17feb82f12f0a75b0a781eb Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Thu, 3 Jan 2013 16:40:18 -0500 Subject: [PATCH 08/16] Remove unused progressive scan option from iso properties, and disable audio settings while a game is running. --- Source/Core/DolphinWX/Src/ConfigMain.cpp | 6 ++++++ Source/Core/DolphinWX/Src/ISOProperties.cpp | 20 -------------------- Source/Core/DolphinWX/Src/ISOProperties.h | 2 +- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index 76508daf7c..8fad769b29 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -618,6 +618,12 @@ void CConfigMain::CreateGUIControls() FrequencySelection->Append(wxString::Format(_("%d Hz"), 48000)); FrequencySelection->Append(wxString::Format(_("%d Hz"), 32000)); + if (Core::GetState() != Core::CORE_UNINITIALIZED) + { + FrequencySelection->Disable(); + BackendSelection->Disable(); + } + // Create sizer and add items to dialog wxStaticBoxSizer *sbAudioSettings = new wxStaticBoxSizer(wxVERTICAL, AudioPage, _("Sound Settings")); sbAudioSettings->Add(DSPEngine, 0, wxALL | wxEXPAND, 5); diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 61139d985f..0b75b03d59 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -328,7 +328,6 @@ void CISOProperties::CreateGUIControls(bool IsWad) DSPHLE = new wxCheckBox(m_GameConfig, ID_AUDIO_DSP_HLE, _("DSP HLE emulation (fast)"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); // Wii Console - EnableProgressiveScan = new wxCheckBox(m_GameConfig, ID_ENABLEPROGRESSIVESCAN, _("Enable Progressive Scan"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); EnableWideScreen = new wxCheckBox(m_GameConfig, ID_ENABLEWIDESCREEN, _("Enable WideScreen"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); DisableWiimoteSpeaker = new wxCheckBox(m_GameConfig, ID_DISABLEWIIMOTESPEAKER, _("Alternate Wiimote Timing"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); DisableWiimoteSpeaker->SetToolTip(_("Mutes the Wiimote speaker. Fixes random disconnections on real wiimotes. No effect on emulated wiimotes.")); @@ -378,18 +377,9 @@ void CISOProperties::CreateGUIControls(bool IsWad) if (!DiscIO::IsVolumeWiiDisc(OpenISO) && !DiscIO::IsVolumeWadFile(OpenISO)) { sbWiiOverrides->ShowItems(false); - EnableProgressiveScan->Hide(); EnableWideScreen->Hide(); DisableWiimoteSpeaker->Hide(); } - else - { - // Progressive Scan is not used by Dolphin itself, and changing it on a per-game - // basis would have the side-effect of changing the SysConf, making this setting - // rather useless. - EnableProgressiveScan->Disable(); - } - sbWiiOverrides->Add(EnableProgressiveScan, 0, wxLEFT, 5); sbWiiOverrides->Add(EnableWideScreen, 0, wxLEFT, 5); sbWiiOverrides->Add(DisableWiimoteSpeaker, 0, wxLEFT, 5); @@ -971,11 +961,6 @@ void CISOProperties::LoadGameConfig() else DSPHLE->Set3StateValue(wxCHK_UNDETERMINED); - if (GameIni.Get("Display", "ProgressiveScan", &bTemp)) - EnableProgressiveScan->Set3StateValue((wxCheckBoxState)bTemp); - else - EnableProgressiveScan->Set3StateValue(wxCHK_UNDETERMINED); - // ?? if (GameIni.Get("Wii", "Widescreen", &bTemp)) EnableWideScreen->Set3StateValue((wxCheckBoxState)bTemp); @@ -1071,11 +1056,6 @@ bool CISOProperties::SaveGameConfig() else GameIni.Set("Core", "DSPHLE", DSPHLE->Get3StateValue()); - if (EnableProgressiveScan->Get3StateValue() == wxCHK_UNDETERMINED) - GameIni.DeleteKey("Display", "ProgressiveScan"); - else - GameIni.Set("Display", "ProgressiveScan", EnableProgressiveScan->Get3StateValue()); - if (EnableWideScreen->Get3StateValue() == wxCHK_UNDETERMINED) GameIni.DeleteKey("Wii", "Widescreen"); else diff --git a/Source/Core/DolphinWX/Src/ISOProperties.h b/Source/Core/DolphinWX/Src/ISOProperties.h index da275136fe..9d71e675e2 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.h +++ b/Source/Core/DolphinWX/Src/ISOProperties.h @@ -72,7 +72,7 @@ private: wxCheckBox *CPUThread, *SkipIdle, *MMU, *MMUBAT, *TLBHack; wxCheckBox *VBeam, *FastDiscSpeed, *BlockMerging, *DSPHLE; // Wii - wxCheckBox *EnableProgressiveScan, *EnableWideScreen, *DisableWiimoteSpeaker; + wxCheckBox *EnableWideScreen, *DisableWiimoteSpeaker; // Video wxCheckBox *UseZTPSpeedupHack, *PHackEnable, *UseBBox; wxButton *PHSettings; From 12a606501c108de1c513f4aacf4e345fe077bd8d Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Thu, 3 Jan 2013 19:21:20 -0600 Subject: [PATCH 09/16] Fix the name and description truncation issue in a cleaner way. --- Source/Core/Common/Src/ChunkFile.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Source/Core/Common/Src/ChunkFile.h b/Source/Core/Common/Src/ChunkFile.h index e26536735d..5a6f26e7c3 100644 --- a/Source/Core/Common/Src/ChunkFile.h +++ b/Source/Core/Common/Src/ChunkFile.h @@ -155,14 +155,7 @@ public: Do(stringLen); switch (mode) { - case MODE_READ: - { - wchar_t* tmp = new wchar_t[stringLen / sizeof(wchar_t)]; - memcpy(tmp, *ptr, stringLen); - x = tmp; - delete[] tmp; - } - break; + case MODE_READ: x.assign((wchar_t*)*ptr, stringLen / sizeof(wchar_t)); break; case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; case MODE_MEASURE: break; case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (wchar_t*)*ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; From 9b51c99c6ba5f1b5f256032f6750540d7d8b2b0e Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Thu, 3 Jan 2013 19:49:19 -0600 Subject: [PATCH 10/16] Make sure the null character is not included in the string. --- Source/Core/Common/Src/ChunkFile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/Src/ChunkFile.h b/Source/Core/Common/Src/ChunkFile.h index 5a6f26e7c3..38e1b2176c 100644 --- a/Source/Core/Common/Src/ChunkFile.h +++ b/Source/Core/Common/Src/ChunkFile.h @@ -155,7 +155,7 @@ public: Do(stringLen); switch (mode) { - case MODE_READ: x.assign((wchar_t*)*ptr, stringLen / sizeof(wchar_t)); break; + case MODE_READ: x.assign((wchar_t*)*ptr, (stringLen / sizeof(wchar_t)) - 1); break; case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; case MODE_MEASURE: break; case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (wchar_t*)*ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; From 7a957134968963a1c53f635afbb91c53b15d9e2b Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 5 Jan 2013 22:45:32 -0600 Subject: [PATCH 11/16] Fix some warnings. Changes suggested by nerzhultheking. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 47737326f4..c5ea6fcb06 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -253,15 +253,15 @@ void DoState(PointerWrap &p) u32 i; for (i=0; i Date: Mon, 7 Jan 2013 12:25:18 +1100 Subject: [PATCH 12/16] Fixed the infinite rumble problem caused by r4d6056f14625. --- Source/Core/Core/Src/HW/GCPad.cpp | 8 ++++++-- Source/Core/Core/Src/HW/GCPadEmu.cpp | 19 +++++++++++++++---- Source/Core/Core/Src/HW/GCPadEmu.h | 1 + .../DInput/DInputJoystick.cpp | 6 +----- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Source/Core/Core/Src/HW/GCPad.cpp b/Source/Core/Core/Src/HW/GCPad.cpp index 61b666af12..68ba3ab88a 100644 --- a/Source/Core/Core/Src/HW/GCPad.cpp +++ b/Source/Core/Core/Src/HW/GCPad.cpp @@ -105,6 +105,10 @@ void Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) { ((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput(255); } + else + { + ((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput(0); + } } } @@ -123,9 +127,9 @@ void Motor(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) { // TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time // set rumble - if (_uType == 06) + if (_uType == 6) { - ((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput(_uStrength); + ((GCPad*)g_plugin.controllers[ _numPAD ])->SetMotor(_uStrength); } } } diff --git a/Source/Core/Core/Src/HW/GCPadEmu.cpp b/Source/Core/Core/Src/HW/GCPadEmu.cpp index 5233ed2877..a2c0c2afa9 100644 --- a/Source/Core/Core/Src/HW/GCPadEmu.cpp +++ b/Source/Core/Core/Src/HW/GCPadEmu.cpp @@ -130,13 +130,24 @@ void GCPad::GetInput(SPADStatus* const pad) } } +void GCPad::SetMotor(const u8 on) +{ + float state = (float)on / 255; + float force = abs(state - 0.5) * 2; + if (state < 0.5) + force = -force; + + // only rumble if window has focus or background input is enabled + if (Host_RendererHasFocus() || m_options[0].settings[0]->value) + m_rumble->controls[0]->control_ref->State(force); + else + m_rumble->controls[0]->control_ref->State(0); +} + void GCPad::SetOutput(const u8 on) { // only rumble if window has focus or background input is enabled - if (Host_RendererHasFocus() || m_options[0].settings[0]->value) - m_rumble->controls[0]->control_ref->State((float)on / 255); - else - m_rumble->controls[0]->control_ref->State(0); + m_rumble->controls[0]->control_ref->State(on && (Host_RendererHasFocus() || m_options[0].settings[0]->value)); } void GCPad::LoadDefaults(const ControllerInterface& ciface) diff --git a/Source/Core/Core/Src/HW/GCPadEmu.h b/Source/Core/Core/Src/HW/GCPadEmu.h index cf0940245e..e57e6b0b68 100644 --- a/Source/Core/Core/Src/HW/GCPadEmu.h +++ b/Source/Core/Core/Src/HW/GCPadEmu.h @@ -29,6 +29,7 @@ public: GCPad(const unsigned int index); void GetInput(SPADStatus* const pad); void SetOutput(const u8 on); + void SetMotor(const u8 on); bool GetMicButton() const; diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp index b7ac3bf82e..af6ee7e77c 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp @@ -535,11 +535,7 @@ ControlState Joystick::Hat::GetState() const void Joystick::ForceConstant::SetState(const ControlState state) { - float force = abs(state - 0.5) * 2; - if (state < 0.5) - force = -force; - - const LONG new_val = LONG(10000 * force); + const LONG new_val = LONG(10000 * state); LONG &val = params.lMagnitude; if (val != new_val) From d0301ca89d318d8d6e3e7fde9c4b60e470e184e4 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 7 Jan 2013 13:47:34 -0600 Subject: [PATCH 13/16] Revert 30dd9c2 e9d00bf db5f4c8 and bff0fae --- .gitignore | 1 - Source/Core/Common/Src/MathUtil.h | 2 - Source/Core/VideoCommon/Src/BPFunctions.cpp | 2 +- .../Src/FramebufferManager.cpp | 85 ++---- .../Src/NativeVertexFormat.cpp | 37 +-- .../Plugin_VideoOGL/Src/RasterFont.cpp | 240 ++++++---------- .../Plugins/Plugin_VideoOGL/Src/RasterFont.h | 20 +- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 268 +++++------------- .../Plugin_VideoOGL/Src/TextureCache.cpp | 91 +----- .../Plugin_VideoOGL/Src/TextureCache.h | 3 - .../Plugin_VideoOGL/Src/TextureConverter.cpp | 112 +------- .../Plugin_VideoOGL/Src/VertexManager.cpp | 3 + .../Plugin_VideoSoftware/Src/SWRenderer.cpp | 5 +- 13 files changed, 242 insertions(+), 627 deletions(-) diff --git a/.gitignore b/.gitignore index 6eaaaf119a..3cc8a1d8a4 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,3 @@ Source/Core/Common/Src/scmrev.h *.ipch .sconsign.dblite Externals/scons-local/* -*~ diff --git a/Source/Core/Common/Src/MathUtil.h b/Source/Core/Common/Src/MathUtil.h index c5f613ada1..a6290ff602 100644 --- a/Source/Core/Common/Src/MathUtil.h +++ b/Source/Core/Common/Src/MathUtil.h @@ -117,8 +117,6 @@ struct Rectangle Rectangle(T theLeft, T theTop, T theRight, T theBottom) : left(theLeft), top(theTop), right(theRight), bottom(theBottom) { } - - bool operator==(const Rectangle& r) { return left==r.left && top==r.top && right==r.right && bottom==r.bottom; } T GetWidth() const { return abs(right - left); } T GetHeight() const { return abs(bottom - top); } diff --git a/Source/Core/VideoCommon/Src/BPFunctions.cpp b/Source/Core/VideoCommon/Src/BPFunctions.cpp index b9a76ba7b6..cddeae3000 100644 --- a/Source/Core/VideoCommon/Src/BPFunctions.cpp +++ b/Source/Core/VideoCommon/Src/BPFunctions.cpp @@ -236,7 +236,7 @@ bool GetConfig(const int &type) case CONFIG_DISABLEFOG: return g_ActiveConfig.bDisableFog; case CONFIG_SHOWEFBREGIONS: - return g_ActiveConfig.bShowEFBCopyRegions; + return false; default: PanicAlert("GetConfig Error: Unknown Config Type!"); return false; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp index e7fb7ad7b7..0e37c3adb6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp @@ -17,7 +17,6 @@ #include "Globals.h" #include "FramebufferManager.h" -#include "VertexShaderGen.h" #include "TextureConverter.h" #include "Render.h" @@ -28,11 +27,6 @@ namespace OGL extern bool s_bHaveFramebufferBlit; // comes from Render.cpp. ugly. -static GLuint s_VBO = 0; -static GLuint s_VAO = 0; -static MathUtil::Rectangle s_cached_sourcerc; -static MathUtil::Rectangle s_cached_drawrc; - int FramebufferManager::m_targetWidth; int FramebufferManager::m_targetHeight; int FramebufferManager::m_msaaSamples; @@ -59,15 +53,6 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms m_resolvedDepthTexture = 0; m_xfbFramebuffer = 0; - s_cached_sourcerc.bottom = -1; - s_cached_sourcerc.left = -1; - s_cached_sourcerc.right = -1; - s_cached_sourcerc.top = -1; - s_cached_drawrc.bottom = -1; - s_cached_drawrc.left = -1; - s_cached_drawrc.right = -1; - s_cached_drawrc.top = -1; - m_targetWidth = targetWidth; m_targetHeight = targetHeight; @@ -184,28 +169,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms // Create XFB framebuffer; targets will be created elsewhere. glGenFramebuffersEXT(1, &m_xfbFramebuffer); - - // Generate VBO & VAO - and initialize the VAO for "Draw" - glGenBuffers(1, &s_VBO); - glGenVertexArrays(1, &s_VAO); - glBindBuffer(GL_ARRAY_BUFFER, s_VBO); - glBindVertexArray(s_VAO); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 6*sizeof(GLfloat), NULL); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 6*sizeof(GLfloat), (GLfloat*)NULL+2); - - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 6*sizeof(GLfloat), (GLfloat*)NULL+4); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - + // EFB framebuffer is currently bound, make sure to clear its alpha value to 1.f glViewport(0, 0, m_targetWidth, m_targetHeight); glScissor(0, 0, m_targetWidth, m_targetHeight); @@ -217,8 +181,6 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms FramebufferManager::~FramebufferManager() { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - glDeleteBuffers(1, &s_VBO); - glDeleteVertexArrays(1, &s_VAO); GLuint glObj[3]; @@ -343,35 +305,24 @@ void XFBSource::Draw(const MathUtil::Rectangle &sourcerc, glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); - if(!(s_cached_sourcerc == sourcerc) || !(s_cached_drawrc == drawrc)) { - GLfloat vertices[] = { - drawrc.left, drawrc.bottom, - sourcerc.left, sourcerc.bottom, - 0.0f, 0.0f, - drawrc.left, drawrc.top, - sourcerc.left, sourcerc.top, - 0.0f, 1.0f, - drawrc.right, drawrc.top, - sourcerc.right, sourcerc.top, - 1.0f, 1.0f, - drawrc.right, drawrc.bottom, - sourcerc.right, sourcerc.bottom, - 1.0f, 0.0f - }; - glBindBuffer(GL_ARRAY_BUFFER, s_VBO); - glBufferData(GL_ARRAY_BUFFER, 2*4*3*sizeof(GLfloat), vertices, GL_STREAM_DRAW); - - s_cached_sourcerc = sourcerc; - s_cached_drawrc = drawrc; - } + glBegin(GL_QUADS); + glTexCoord2f(sourcerc.left, sourcerc.bottom); + glMultiTexCoord2fARB(GL_TEXTURE1, 0, 0); + glVertex2f(drawrc.left, drawrc.bottom); + + glTexCoord2f(sourcerc.left, sourcerc.top); + glMultiTexCoord2fARB(GL_TEXTURE1, 0, 1); + glVertex2f(drawrc.left, drawrc.top); + + glTexCoord2f(sourcerc.right, sourcerc.top); + glMultiTexCoord2fARB(GL_TEXTURE1, 1, 1); + glVertex2f(drawrc.right, drawrc.top); + + glTexCoord2f(sourcerc.right, sourcerc.bottom); + glMultiTexCoord2fARB(GL_TEXTURE1, 1, 0); + glVertex2f(drawrc.right, drawrc.bottom); + glEnd(); - glBindVertexArray(s_VAO); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - GL_REPORT_ERRORD(); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp index a435be0dca..ae20649433 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp @@ -27,9 +27,8 @@ #define COMPILED_CODE_SIZE 4096 -// TODO: Use this again for performance, but without VAO we never know exactly the last configuration -static u32 s_prevcomponents; // previous state set - +// TODO: this guy is never initialized +u32 s_prevcomponents; // previous state set /* #ifdef _WIN32 #ifdef _M_IX86 @@ -65,6 +64,7 @@ public: virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); virtual void SetupVertexPointers(); + virtual void EnableComponents(u32 components); }; namespace OGL @@ -187,7 +187,6 @@ void GLVertexFormat::SetupVertexPointers() { #ifdef USE_JIT ((void (*)())(void*)m_compiledCode)(); #else - glVertexPointer(3, GL_FLOAT, vtx_decl.stride, VertexManager::s_pBaseBufferPointer); if (vtx_decl.num_normals >= 1) { glNormalPointer(VarToGL(vtx_decl.normal_gl_type), vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.normal_offset[0])); @@ -220,32 +219,34 @@ void GLVertexFormat::SetupVertexPointers() { glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)(VertexManager::s_pBaseBufferPointer + vtx_decl.posmtx_offset)); } #endif +} - if (s_prevcomponents != m_components) +void GLVertexFormat::EnableComponents(u32 components) +{ + if (s_prevcomponents != components) { - // vertices - glEnableClientState(GL_VERTEX_ARRAY); + VertexManager::Flush(); // matrices - if ((m_components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX)) + if ((components & VB_HAS_POSMTXIDX) != (s_prevcomponents & VB_HAS_POSMTXIDX)) { - if (m_components & VB_HAS_POSMTXIDX) + if (components & VB_HAS_POSMTXIDX) glEnableVertexAttribArray(SHADER_POSMTX_ATTRIB); else glDisableVertexAttribArray(SHADER_POSMTX_ATTRIB); } // normals - if ((m_components & VB_HAS_NRM0) != (s_prevcomponents & VB_HAS_NRM0)) + if ((components & VB_HAS_NRM0) != (s_prevcomponents & VB_HAS_NRM0)) { - if (m_components & VB_HAS_NRM0) + if (components & VB_HAS_NRM0) glEnableClientState(GL_NORMAL_ARRAY); else glDisableClientState(GL_NORMAL_ARRAY); } - if ((m_components & VB_HAS_NRM1) != (s_prevcomponents & VB_HAS_NRM1)) + if ((components & VB_HAS_NRM1) != (s_prevcomponents & VB_HAS_NRM1)) { - if (m_components & VB_HAS_NRM1) { + if (components & VB_HAS_NRM1) { glEnableVertexAttribArray(SHADER_NORM1_ATTRIB); glEnableVertexAttribArray(SHADER_NORM2_ATTRIB); } @@ -258,9 +259,9 @@ void GLVertexFormat::SetupVertexPointers() { // color for (int i = 0; i < 2; ++i) { - if ((m_components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i))) + if ((components & (VB_HAS_COL0 << i)) != (s_prevcomponents & (VB_HAS_COL0 << i))) { - if (m_components & (VB_HAS_COL0 << i)) + if (components & (VB_HAS_COL0 << i)) glEnableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY); else glDisableClientState(i ? GL_SECONDARY_COLOR_ARRAY : GL_COLOR_ARRAY); @@ -270,16 +271,16 @@ void GLVertexFormat::SetupVertexPointers() { // tex for (int i = 0; i < 8; ++i) { - if ((m_components & (VB_HAS_UV0 << i)) != (s_prevcomponents & (VB_HAS_UV0 << i))) + if ((components & (VB_HAS_UV0 << i)) != (s_prevcomponents & (VB_HAS_UV0 << i))) { glClientActiveTexture(GL_TEXTURE0 + i); - if (m_components & (VB_HAS_UV0 << i)) + if (components & (VB_HAS_UV0 << i)) glEnableClientState(GL_TEXTURE_COORD_ARRAY); else glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } - s_prevcomponents = m_components; + s_prevcomponents = components; } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.cpp b/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.cpp index 95c99ac78c..da53fae6d5 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.cpp @@ -17,16 +17,12 @@ #include "GLUtil.h" +#include + #include "RasterFont.h" // globals - -static const u32 char_width = 8; -static const u32 char_height = 13; -static const u32 char_offset = 32; -static const u32 char_count = 95; - -const u8 rasters[char_count][char_height] = { +const GLubyte rasters[][13] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36}, @@ -124,160 +120,104 @@ const u8 rasters[char_count][char_height] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00} }; -static const char *s_vertex_shader = - "attribute vec2 vertexPosition;\n" - "attribute vec2 texturePosition;\n" - "varying vec2 tpos;\n" - "void main(void) {\n" - " gl_Position = vec4(vertexPosition,0,1);\n" - " tpos = texturePosition;\n" - "}\n"; - -static const char *s_fragment_shader = - "#extension GL_ARB_texture_rectangle : enable\n" - "uniform sampler2DRect textureSampler;\n" - "uniform vec4 color;\n" - "varying vec2 tpos;\n" - "void main(void) {\n" - " gl_FragColor = texture2DRect(textureSampler,tpos) * color;\n" - "}\n"; - RasterFont::RasterFont() { - // generate the texture - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_RECTANGLE, texture); - u32* texture_data = new u32[char_width*char_count*char_height]; - for(u32 y=0; y= char_count+char_offset) continue; - - vertices[usage++] = x; - vertices[usage++] = y; - vertices[usage++] = (c-char_offset)*char_width; - vertices[usage++] = 0; - - vertices[usage++] = x+delta_x; - vertices[usage++] = y; - vertices[usage++] = (c-char_offset+1)*char_width; - vertices[usage++] = 0; - - vertices[usage++] = x+delta_x; - vertices[usage++] = y+delta_y; - vertices[usage++] = (c-char_offset+1)*char_width; - vertices[usage++] = char_height; - - vertices[usage++] = x; - vertices[usage++] = y; - vertices[usage++] = (c-char_offset)*char_width; - vertices[usage++] = 0; - - vertices[usage++] = x+delta_x; - vertices[usage++] = y+delta_y; - vertices[usage++] = (c-char_offset+1)*char_width; - vertices[usage++] = char_height; - - vertices[usage++] = x; - vertices[usage++] = y+delta_y; - vertices[usage++] = (c-char_offset)*char_width; - vertices[usage++] = char_height; - - x += delta_x + border_x; - } - glUnmapBuffer(GL_ARRAY_BUFFER); + return; + if (length >= TEMP_BUFFER_SIZE) + length = TEMP_BUFFER_SIZE - 1; - glUseProgram(shader_program); - - if(color != cached_color) { - glUniform4f(uniform_color_id, ((color>>16)&0xff)/255.f,((color>>8)&0xff)/255.f,((color>>0)&0xff)/255.f,((color>>24)&0xff)/255.f); - cached_color = color; + // Sanitize string to avoid GL errors. + char *s2 = temp_buffer; + memcpy(s2, s, length); + s2[length] = 0; + for (int i = 0; i < length; i++) { + if (s2[i] < 32 || s2[i] > 126) + s2[i] = '!'; + } + + // go to the right spot + glRasterPos3d(x, y, z); + GL_REPORT_ERRORD(); + + glPushAttrib (GL_LIST_BIT); + glListBase(fontOffset); + glCallLists((GLsizei)strlen(s2), GL_UNSIGNED_BYTE, (GLubyte *) s2); + GL_REPORT_ERRORD(); + glPopAttrib(); + GL_REPORT_ERRORD(); +} + +void RasterFont::printCenteredString(const char *s, double y, int screen_width, double z) +{ + int length = (int)strlen(s); + int x = (int)(screen_width/2.0 - (length/2.0)*char_width); + printString(s, x, y, z); +} + +void RasterFont::printMultilineText(const char *text, double start_x, double start_y, double z, int bbWidth, int bbHeight) +{ + double x = start_x; + double y = start_y; + char temp[1024]; + char *t = temp; + while (*text) + { + if (*text == '\n') + { + *t = 0; + printString(temp, x, y, z); + y -= char_height * 2.0f / bbHeight; + x = start_x; + t = temp; + } + else if (*text == '\r') + { + t = temp; + } + else if (*text == '\t') + { + //todo: add tabs every something like 4*char_width + *t = 0; + int cpos = (int)strlen(temp); + int newpos = (cpos + 4) & (~3); + printString(temp, x, y, z); + x = start_x + (char_width*newpos) * 2.0f / bbWidth; + t = temp; + *t++ = ' '; + } + else + *t++ = *text; + + text++; + } + + // ???? + if (t != text) + { + *t = 0; + printString(temp, x, y, z); } - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_RECTANGLE, texture); - glDrawArrays(GL_TRIANGLES, 0, usage/4); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glUseProgram(0); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.h b/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.h index fcbfdfff61..3ebc684dd0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/RasterFont.h @@ -23,16 +23,20 @@ public: RasterFont(); ~RasterFont(void); static int debug; + + // some useful constants + enum {char_width = 10}; + enum {char_height = 15}; + + // and the happy helper functions + void printString(const char *s, double x, double y, double z=0.0); + void printCenteredString(const char *s, double y, int screen_width, double z=0.0); - void printMultilineText(const char *text, double x, double y, double z, int bbWidth, int bbHeight, u32 color); + void printMultilineText(const char *text, double x, double y, double z, int bbWidth, int bbHeight); private: - - u32 VBO; - u32 VAO; - u32 texture; - u32 shader_program; - u32 uniform_color_id; - u32 cached_color; + int fontOffset; + char *temp_buffer; + enum {TEMP_BUFFER_SIZE = 64 * 1024}; }; #endif // _RASTERFONT_H_ diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index a2d0a94ee3..e2fff07b10 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -107,14 +107,10 @@ namespace OGL // Declarations and definitions // ---------------------------- -static int s_fps = 0; -static GLuint s_ShowEFBCopyRegions_VBO = 0; -static GLuint s_ShowEFBCopyRegions_VAO = 0; -static GLuint s_Swap_VBO = 0; -static GLuint s_Swap_VAO[2]; -static TargetRectangle s_cached_targetRc; +int s_fps=0; -static RasterFont* s_pfont = NULL; + +RasterFont* s_pfont = NULL; // 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA. static int s_MSAASamples = 1; @@ -130,9 +126,9 @@ static std::thread scrshotThread; #endif // EFB cache related -static const u32 EFB_CACHE_RECT_SIZE = 64; // Cache 64x64 blocks. -static const u32 EFB_CACHE_WIDTH = (EFB_WIDTH + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; // round up -static const u32 EFB_CACHE_HEIGHT = (EFB_HEIGHT + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; +const u32 EFB_CACHE_RECT_SIZE = 64; // Cache 64x64 blocks. +const u32 EFB_CACHE_WIDTH = (EFB_WIDTH + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; // round up +const u32 EFB_CACHE_HEIGHT = (EFB_HEIGHT + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; static bool s_efbCacheValid[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT]; static std::vector s_efbCache[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT]; // 2 for PEEK_Z and PEEK_COLOR @@ -255,16 +251,7 @@ Renderer::Renderer() OSDInternalH = 0; s_fps=0; - s_ShowEFBCopyRegions_VBO = 0; - s_Swap_VBO = 0; s_blendMode = 0; - - // should be invalid, so there will be an upload on the first call - s_cached_targetRc.bottom = -1; - s_cached_targetRc.top = -1; - s_cached_targetRc.left = -1; - s_cached_targetRc.right = -1; - InitFPSCounter(); @@ -325,13 +312,6 @@ Renderer::Renderer() bSuccess = false; } - if (!GLEW_ARB_vertex_array_object) - { - ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_vertex_array_object.\n" - "GPU: Does your video card support OpenGL 3.0?"); - bSuccess = false; - } - s_bHaveFramebufferBlit = strstr(ptoken, "GL_EXT_framebuffer_blit") != NULL; s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL; @@ -471,46 +451,17 @@ Renderer::Renderer() cgGLSetDebugMode(GL_FALSE); #endif #endif - - // creating buffers - glGenBuffers(1, &s_ShowEFBCopyRegions_VBO); - glGenVertexArrays(1, &s_ShowEFBCopyRegions_VAO); - glBindBuffer(GL_ARRAY_BUFFER, s_ShowEFBCopyRegions_VBO); - glBindVertexArray( s_ShowEFBCopyRegions_VAO ); - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer (3, GL_FLOAT, sizeof(GLfloat)*5, (GLfloat*)NULL+2); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*5, NULL); - - glGenBuffers(1, &s_Swap_VBO); - glGenVertexArrays(2, s_Swap_VAO); - glBindBuffer(GL_ARRAY_BUFFER, s_Swap_VBO); - glBindVertexArray(s_Swap_VAO[0]); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 7*sizeof(GLfloat), NULL); - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 7*sizeof(GLfloat), (GLfloat*)NULL+3); - - glBindVertexArray(s_Swap_VAO[1]); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 7*sizeof(GLfloat), NULL); - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 7*sizeof(GLfloat), (GLfloat*)NULL+3); - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 7*sizeof(GLfloat), (GLfloat*)NULL+5); - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glStencilFunc(GL_ALWAYS, 0, 0); glBlendFunc(GL_ONE, GL_ONE); glViewport(0, 0, GetTargetWidth(), GetTargetHeight()); // Reset The Current Viewport + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.0f); @@ -527,6 +478,11 @@ Renderer::Renderer() glBlendColorEXT(0, 0, 0, 0.5f); glClearDepth(1.0f); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + // legacy multitexturing: select texture channel only. glActiveTexture(GL_TEXTURE0); glClientActiveTexture(GL_TEXTURE0); @@ -542,13 +498,6 @@ Renderer::~Renderer() { g_Config.bRunning = false; UpdateActiveConfig(); - - glDeleteBuffers(1, &s_ShowEFBCopyRegions_VBO); - glDeleteVertexArrays(1, &s_ShowEFBCopyRegions_VAO); - glDeleteBuffers(1, &s_Swap_VBO); - glDeleteVertexArrays(2, s_Swap_VAO); - s_ShowEFBCopyRegions_VBO = 0; - delete s_pfont; s_pfont = 0; @@ -596,15 +545,9 @@ void Renderer::DrawDebugInfo() // Set Line Size glLineWidth(3.0f); - // 2*Coords + 3*Color - glBindBuffer(GL_ARRAY_BUFFER, s_ShowEFBCopyRegions_VBO); - glBufferData(GL_ARRAY_BUFFER, stats.efb_regions.size() * sizeof(GLfloat) * (2+3)*2*6, NULL, GL_STREAM_DRAW); - GLfloat *Vertices = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + glBegin(GL_LINES); // Draw EFB copy regions rectangles - int a = 0; - GLfloat color[3] = {0.0f, 1.0f, 1.0f}; - for (std::vector::const_iterator it = stats.efb_regions.begin(); it != stats.efb_regions.end(); ++it) { @@ -615,97 +558,22 @@ void Renderer::DrawDebugInfo() GLfloat x2 = (GLfloat) -1.0f + ((GLfloat)it->right / halfWidth); GLfloat y2 = (GLfloat) 1.0f - ((GLfloat)it->bottom / halfHeight); - Vertices[a++] = x; - Vertices[a++] = y; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - Vertices[a++] = x2; - Vertices[a++] = y; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - - Vertices[a++] = x2; - Vertices[a++] = y; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - Vertices[a++] = x2; - Vertices[a++] = y2; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - - Vertices[a++] = x2; - Vertices[a++] = y2; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - Vertices[a++] = x; - Vertices[a++] = y2; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - - Vertices[a++] = x; - Vertices[a++] = y2; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - Vertices[a++] = x; - Vertices[a++] = y; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - - Vertices[a++] = x; - Vertices[a++] = y; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - Vertices[a++] = x2; - Vertices[a++] = y2; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - - Vertices[a++] = x2; - Vertices[a++] = y; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - Vertices[a++] = x; - Vertices[a++] = y2; - Vertices[a++] = color[0]; - Vertices[a++] = color[1]; - Vertices[a++] = color[2]; - - // TO DO: build something nicer here - GLfloat temp = color[0]; - color[0] = color[1]; - color[1] = color[2]; - color[2] = temp; + // Draw shadow of rect + glColor3f(0.0f, 0.0f, 0.0f); + glVertex2f(x, y - 0.01); glVertex2f(x2, y - 0.01); + glVertex2f(x, y2 - 0.01); glVertex2f(x2, y2 - 0.01); + glVertex2f(x + 0.005, y); glVertex2f(x + 0.005, y2); + glVertex2f(x2 + 0.005, y); glVertex2f(x2 + 0.005, y2); + + // Draw rect + glColor3f(0.0f, 1.0f, 1.0f); + glVertex2f(x, y); glVertex2f(x2, y); + glVertex2f(x, y2); glVertex2f(x2, y2); + glVertex2f(x, y); glVertex2f(x, y2); + glVertex2f(x2, y); glVertex2f(x2, y2); } - glUnmapBuffer(GL_ARRAY_BUFFER); - - glBindVertexArray( s_ShowEFBCopyRegions_VAO ); - glDrawArrays(GL_LINES, 0, stats.efb_regions.size() * 2*6); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); + + glEnd(); // Restore Line Size glLineWidth(lSize); @@ -733,13 +601,16 @@ void Renderer::RenderText(const char *text, int left, int top, u32 color) const int nBackbufferWidth = (int)GLInterface->GetBackBufferWidth(); const int nBackbufferHeight = (int)GLInterface->GetBackBufferHeight(); + glColor4f(((color>>16) & 0xff)/255.0f, ((color>> 8) & 0xff)/255.0f, + ((color>> 0) & 0xff)/255.0f, ((color>>24) & 0xFF)/255.0f); + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); s_pfont->printMultilineText(text, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight, - 0, nBackbufferWidth, nBackbufferHeight, color); + 0, nBackbufferWidth, nBackbufferHeight); GL_REPORT_ERRORD(); @@ -1264,42 +1135,43 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // Render to the real buffer now. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture); + if (applyShader) + { + glBegin(GL_QUADS); + glTexCoord2f(targetRc.left, targetRc.bottom); + glMultiTexCoord2fARB(GL_TEXTURE1, 0, 0); + glVertex2f(-1, -1); - if(!( s_cached_targetRc == targetRc)) { - GLfloat vertices[] = { - -1.0f, -1.0f, 1.0f, - (GLfloat)targetRc.left, (GLfloat)targetRc.bottom, - 0.0f, 0.0f, - - -1.0f, 1.0f, 1.0f, - (GLfloat)targetRc.left, (GLfloat)targetRc.top, - 0.0f, 1.0f, - - 1.0f, 1.0f, 1.0f, - (GLfloat)targetRc.right, (GLfloat)targetRc.top, - 1.0f, 1.0f, - - 1.0f, -1.0f, 1.0f, - (GLfloat)targetRc.right, (GLfloat)targetRc.bottom, - 1.0f, 0.0f - }; - - glBindBuffer(GL_ARRAY_BUFFER, s_Swap_VBO); - glBufferData(GL_ARRAY_BUFFER, 4*7*sizeof(GLfloat), vertices, GL_STREAM_DRAW); - - s_cached_targetRc = targetRc; - } - - glBindVertexArray(s_Swap_VAO[applyShader]); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glTexCoord2f(targetRc.left, targetRc.top); + glMultiTexCoord2fARB(GL_TEXTURE1, 0, 1); + glVertex2f(-1, 1); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - if(applyShader) + glTexCoord2f(targetRc.right, targetRc.top); + glMultiTexCoord2fARB(GL_TEXTURE1, 1, 1); + glVertex2f( 1, 1); + + glTexCoord2f(targetRc.right, targetRc.bottom); + glMultiTexCoord2fARB(GL_TEXTURE1, 1, 0); + glVertex2f( 1, -1); + glEnd(); PixelShaderCache::DisableShader(); + } + else + { + glBegin(GL_QUADS); + glTexCoord2f(targetRc.left, targetRc.bottom); + glVertex2f(-1, -1); + + glTexCoord2f(targetRc.left, targetRc.top); + glVertex2f(-1, 1); + + glTexCoord2f(targetRc.right, targetRc.top); + glVertex2f( 1, 1); + + glTexCoord2f(targetRc.right, targetRc.bottom); + glVertex2f( 1, -1); + glEnd(); + } } glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index d90f651a82..7a62131f90 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -56,13 +56,6 @@ namespace OGL { -struct VBOCache { - GLuint vbo; - GLuint vao; - TargetRectangle targetSource; -}; -static std::map s_VBO; - static u32 s_TempFramebuffer = 0; static const GLint c_MinLinearFilter[8] = { @@ -113,8 +106,6 @@ TextureCache::TCacheEntry::~TCacheEntry() TextureCache::TCacheEntry::TCacheEntry() { glGenTextures(1, &texture); - currmode.hex = 0; - currmode1.hex = 0; GL_REPORT_ERRORD(); } @@ -127,9 +118,7 @@ void TextureCache::TCacheEntry::Bind(unsigned int stage) // TODO: is this already done somewhere else? TexMode0 &tm0 = bpmem.tex[stage >> 2].texMode0[stage & 3]; TexMode1 &tm1 = bpmem.tex[stage >> 2].texMode1[stage & 3]; - - if(currmode.hex != tm0.hex || currmode1.hex != tm1.hex) - SetTextureParameters(tm0, tm1); + SetTextureParameters(tm0, tm1); } bool TextureCache::TCacheEntry::Save(const char filename[], unsigned int level) @@ -315,57 +304,13 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo GL_REPORT_ERRORD(); TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(srcRect); - GL_REPORT_ERRORD(); - - // should be unique enough, if not, vbo will "only" be uploaded to much - u64 targetSourceHash = u64(targetSource.left)<<48 | u64(targetSource.top)<<32 | u64(targetSource.right)<<16 | u64(targetSource.bottom); - std::map::iterator vbo_it = s_VBO.find(targetSourceHash); - - if(vbo_it == s_VBO.end()) { - VBOCache item; - item.targetSource.bottom = -1; - item.targetSource.top = -1; - item.targetSource.left = -1; - item.targetSource.right = -1; - glGenBuffers(1, &item.vbo); - glGenVertexArrays(1, &item.vao); - - glBindBuffer(GL_ARRAY_BUFFER, item.vbo); - glBindVertexArray(item.vao); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*4, 0); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat)*4, (GLfloat*)NULL + 2); - - vbo_it = s_VBO.insert(std::pair(targetSourceHash, item)).first; - } - if(!(vbo_it->second.targetSource == targetSource)) { - GLfloat vertices[] = { - -1.f, 1.f, - (GLfloat)targetSource.left, (GLfloat)targetSource.bottom, - -1.f, -1.f, - (GLfloat)targetSource.left, (GLfloat)targetSource.top, - 1.f, -1.f, - (GLfloat)targetSource.right, (GLfloat)targetSource.top, - 1.f, 1.f, - (GLfloat)targetSource.right, (GLfloat)targetSource.bottom - }; - - glBindBuffer(GL_ARRAY_BUFFER, vbo_it->second.vbo); - glBufferData(GL_ARRAY_BUFFER, 4*4*sizeof(GLfloat), vertices, GL_STREAM_DRAW); - - vbo_it->second.targetSource = targetSource; - } - glBindVertexArray(vbo_it->second.vao); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBegin(GL_QUADS); + glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1); + glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.top ); glVertex2f(-1, -1); + glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.top ); glVertex2f( 1, -1); + glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.bottom); glVertex2f( 1, 1); + glEnd(); GL_REPORT_ERRORD(); @@ -412,9 +357,6 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo void TextureCache::TCacheEntry::SetTextureParameters(const TexMode0 &newmode, const TexMode1 &newmode1) { - currmode = newmode; - currmode1 = newmode1; - // TODO: not used anywhere TexMode0 mode = newmode; //mode1 = newmode1; @@ -446,24 +388,13 @@ void TextureCache::TCacheEntry::SetTextureParameters(const TexMode0 &newmode, co (float)(1 << g_ActiveConfig.iMaxAnisotropy)); } -TextureCache::TextureCache() -{ -} - - TextureCache::~TextureCache() { - for(std::map::iterator it = s_VBO.begin(); it != s_VBO.end(); it++) { - glDeleteBuffers(1, &it->second.vbo); - glDeleteVertexArrays(1, &it->second.vao); - } - s_VBO.clear(); - - if (s_TempFramebuffer) + if (s_TempFramebuffer) { - glDeleteFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer); - s_TempFramebuffer = 0; - } + glDeleteFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer); + s_TempFramebuffer = 0; + } } void TextureCache::DisableStage(unsigned int stage) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h index dc560e098b..30f44b797d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h @@ -32,7 +32,6 @@ namespace OGL class TextureCache : public ::TextureCache { public: - TextureCache(); static void DisableStage(unsigned int stage); private: @@ -67,8 +66,6 @@ private: private: void SetTextureParameters(const TexMode0 &newmode, const TexMode1 &newmode1); - TexMode0 currmode; - TexMode1 currmode1; }; ~TextureCache(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp index 54a2e2464c..c73d3abdbf 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp @@ -57,14 +57,6 @@ static FRAGMENTSHADER s_yuyvToRgbProgram; const u32 NUM_ENCODING_PROGRAMS = 64; static FRAGMENTSHADER s_encodingPrograms[NUM_ENCODING_PROGRAMS]; -static GLuint s_encode_VBO = 0; -static GLuint s_encode_VAO = 0; -static GLuint s_decode_VBO = 0; -static GLuint s_decode_VAO = 0; -static TargetRectangle s_cached_sourceRc; -static int s_cached_srcWidth = 0; -static int s_cached_srcHeight = 0; - void CreateRgbToYuyvProgram() { // Output is BGRA because that is slightly faster than RGBA. @@ -148,40 +140,9 @@ FRAGMENTSHADER &GetOrCreateEncodingShader(u32 format) void Init() { glGenFramebuffersEXT(1, &s_texConvFrameBuffer); - - glGenBuffers(1, &s_encode_VBO ); - glGenVertexArrays(1, &s_encode_VAO ); - glBindBuffer(GL_ARRAY_BUFFER, s_encode_VBO ); - glBindVertexArray( s_encode_VAO ); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 4*sizeof(GLfloat), NULL); - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 4*sizeof(GLfloat), (GLfloat*)NULL + 2); - s_cached_sourceRc.top = -1; - s_cached_sourceRc.bottom = -1; - s_cached_sourceRc.left = -1; - s_cached_sourceRc.right = -1; - - glGenBuffers(1, &s_decode_VBO ); - glGenVertexArrays(1, &s_decode_VAO ); - glBindBuffer(GL_ARRAY_BUFFER, s_decode_VBO ); - glBindVertexArray( s_decode_VAO ); - s_cached_srcWidth = -1; - s_cached_srcHeight = -1; - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, sizeof(GLfloat)*4, NULL); - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat)*4, (GLfloat*)NULL+2); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); glGenRenderbuffersEXT(1, &s_dstRenderBuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_dstRenderBuffer); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, renderBufferWidth, renderBufferHeight); s_srcTextureWidth = 0; @@ -201,10 +162,6 @@ void Shutdown() glDeleteTextures(1, &s_srcTexture); glDeleteRenderbuffersEXT(1, &s_dstRenderBuffer); glDeleteFramebuffersEXT(1, &s_texConvFrameBuffer); - glDeleteBuffers(1, &s_encode_VBO ); - glDeleteVertexArrays(1, &s_encode_VAO ); - glDeleteBuffers(1, &s_decode_VBO ); - glDeleteVertexArrays(1, &s_decode_VAO ); s_rgbToYuyvProgram.Destroy(); s_yuyvToRgbProgram.Destroy(); @@ -256,31 +213,13 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar PixelShaderCache::SetCurrentShader(shader.glprogid); - GL_REPORT_ERRORD(); - if(!(s_cached_sourceRc == sourceRc)) { - GLfloat vertices[] = { - -1.f, -1.f, - (float)sourceRc.left, (float)sourceRc.top, - -1.f, 1.f, - (float)sourceRc.left, (float)sourceRc.bottom, - 1.f, 1.f, - (float)sourceRc.right, (float)sourceRc.bottom, - 1.f, -1.f, - (float)sourceRc.right, (float)sourceRc.top - }; - glBindBuffer(GL_ARRAY_BUFFER, s_encode_VBO ); - glBufferData(GL_ARRAY_BUFFER, 4*4*sizeof(GLfloat), vertices, GL_STREAM_DRAW); - - s_cached_sourceRc = sourceRc; - } - - glBindVertexArray( s_encode_VAO ); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - + // Draw... + glBegin(GL_QUADS); + glTexCoord2f((float)sourceRc.left, (float)sourceRc.top); glVertex2f(-1,-1); + glTexCoord2f((float)sourceRc.left, (float)sourceRc.bottom); glVertex2f(-1,1); + glTexCoord2f((float)sourceRc.right, (float)sourceRc.bottom); glVertex2f(1,1); + glTexCoord2f((float)sourceRc.right, (float)sourceRc.top); glVertex2f(1,-1); + glEnd(); GL_REPORT_ERRORD(); // .. and then read back the results. @@ -436,39 +375,18 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur PixelShaderCache::SetCurrentShader(s_yuyvToRgbProgram.glprogid); GL_REPORT_ERRORD(); - - if(s_cached_srcHeight != srcHeight || s_cached_srcWidth != srcWidth) { - GLfloat vertices[] = { - 1.f, -1.f, - (float)srcFmtWidth, (float)srcHeight, - 1.f, 1.f, - (float)srcFmtWidth, 0.f, - -1.f, 1.f, - 0.f, 0.f, - -1.f, -1.f, - 0.f, (float)srcHeight - }; - - glBindBuffer(GL_ARRAY_BUFFER, s_decode_VBO ); - glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*4*4, vertices, GL_STREAM_DRAW); - - s_cached_srcHeight = srcHeight; - s_cached_srcWidth = srcWidth; - } - - glBindVertexArray( s_decode_VAO ); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // TODO: this after merging with graphic_update - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - GL_REPORT_ERRORD(); + + glBegin(GL_QUADS); + glTexCoord2f((float)srcFmtWidth, (float)srcHeight); glVertex2f(1,-1); + glTexCoord2f((float)srcFmtWidth, 0); glVertex2f(1,1); + glTexCoord2f(0, 0); glVertex2f(-1,1); + glTexCoord2f(0, (float)srcHeight); glVertex2f(-1,-1); + glEnd(); // reset state glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0); - TextureCache::DisableStage(0); + TextureCache::DisableStage(0); VertexShaderManager::SetViewportChanged(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 3725d87add..501c4969e5 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -64,6 +64,9 @@ VertexManager::VertexManager() // max_Index_size = MAXIBUFFERSIZE; // //GL_REPORT_ERRORD(); + + glEnableClientState(GL_VERTEX_ARRAY); + GL_REPORT_ERRORD(); } void VertexManager::CreateDeviceObjects() diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp index d2f77cd256..49739b7f6e 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp @@ -96,11 +96,12 @@ void SWRenderer::RenderText(const char* pstr, int left, int top, u32 color) #ifndef USE_GLES int nBackbufferWidth = (int)GLInterface->GetBackBufferWidth(); int nBackbufferHeight = (int)GLInterface->GetBackBufferHeight(); - + glColor4f(((color>>16) & 0xff)/255.0f, ((color>> 8) & 0xff)/255.0f, + ((color>> 0) & 0xff)/255.0f, ((color>>24) & 0xFF)/255.0f); s_pfont->printMultilineText(pstr, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight, - 0, nBackbufferWidth, nBackbufferHeight, color); + 0, nBackbufferWidth, nBackbufferHeight); #endif } From bb7c262539a5b2b663bbec065e9120fa9fb21e46 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Mon, 7 Jan 2013 16:50:48 -0600 Subject: [PATCH 14/16] Add a linux .desktop file to add dolphin-emu to the menu, and install it when running 'make install'. --- CMakeLists.txt | 7 +++++++ Source/Core/DolphinWX/resources/dolphin-emu.desktop | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 Source/Core/DolphinWX/resources/dolphin-emu.desktop diff --git a/CMakeLists.txt b/CMakeLists.txt index b025de11ef..5f36e1f8a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -622,6 +622,13 @@ endif() if((NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|Darwin")) install(FILES Data/license.txt DESTINATION ${datadir}) endif() +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + # Install the application icon and menu item + install(FILES Source/Core/DolphinWX/resources/Dolphin.xpm + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME dolphin-emu.xpm) + install(FILES Source/Core/DolphinWX/resources/dolphin-emu.desktop + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) +endif() # packaging information set(CPACK_PACKAGE_NAME "dolphin-emu") diff --git a/Source/Core/DolphinWX/resources/dolphin-emu.desktop b/Source/Core/DolphinWX/resources/dolphin-emu.desktop new file mode 100644 index 0000000000..0ce4678f00 --- /dev/null +++ b/Source/Core/DolphinWX/resources/dolphin-emu.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=Dolphin-emu +Comment=A Wii/GameCube Emulator +Icon=dolphin-emu +Exec=dolphin-emu +Categories=Game; + From 8cfceb1186c80a4ad94618cfa8d8aa942134247e Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Tue, 8 Jan 2013 00:00:30 +0100 Subject: [PATCH 15/16] Disable swapping cmp with instructions potentially raising interrupts Workaround for issue 5864 disabling parts of an optimization in the JIT. This is not the best solution to fix this issue, but at least it does not crash. --- Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp index ddfec1c328..fa9f278c29 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp @@ -246,17 +246,13 @@ bool CanSwapAdjacentOps(const CodeOp &a, const CodeOp &b) return false; } - // For now, only integer ops acceptable. - switch (b_info->type) { - case OPTYPE_INTEGER: - case OPTYPE_LOAD: - case OPTYPE_STORE: - //case OPTYPE_LOADFP: - //case OPTYPE_STOREFP: - break; - default: + // For now, only integer ops acceptable. Any instruction which can raise an + // interrupt is *not* a possible swap candidate: see [1] for an example of + // a crash caused by this error. + // + // [1] https://code.google.com/p/dolphin-emu/issues/detail?id=5864#c7 + if (b_info->type != OPTYPE_INTEGER) return false; - } // Check that we have no register collisions. // That is, check that none of b's outputs matches any of a's inputs, From 6bd8474d054db7eafa546063e88f23e7ffe0d9d0 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Mon, 7 Jan 2013 17:05:51 -0600 Subject: [PATCH 16/16] Change the application name to "Dolphin Emulator" (from "Dolphin-emu"). --- Source/Core/DolphinWX/resources/dolphin-emu.desktop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/DolphinWX/resources/dolphin-emu.desktop b/Source/Core/DolphinWX/resources/dolphin-emu.desktop index 0ce4678f00..f201f07f22 100644 --- a/Source/Core/DolphinWX/resources/dolphin-emu.desktop +++ b/Source/Core/DolphinWX/resources/dolphin-emu.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Version=1.0 Type=Application -Name=Dolphin-emu +Name=Dolphin Emulator Comment=A Wii/GameCube Emulator Icon=dolphin-emu Exec=dolphin-emu