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/CMakeLists.txt b/CMakeLists.txt index 52016227e4..74af394798 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -624,6 +624,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/Common/Src/ChunkFile.h b/Source/Core/Common/Src/ChunkFile.h index be8b49a3a3..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 = (wchar_t*)*ptr; 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; 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/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 3efc6cab47..9ac0271658 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 a87b25932e..e539cfaa68 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -301,6 +301,7 @@ + @@ -505,6 +506,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index 65bcac2c14..c315f46904 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 @@ -820,6 +823,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..68ba3ab88a 100644 --- a/Source/Core/Core/Src/HW/GCPad.cpp +++ b/Source/Core/Core/Src/HW/GCPad.cpp @@ -101,7 +101,36 @@ 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); + } + else + { + ((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput(0); + } + } +} + +// __________________________________________________________________________________________________ +// 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 == 6) + { + ((GCPad*)g_plugin.controllers[ _numPAD ])->SetMotor(_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..a2c0c2afa9 100644 --- a/Source/Core/Core/Src/HW/GCPadEmu.cpp +++ b/Source/Core/Core/Src/HW/GCPadEmu.cpp @@ -130,7 +130,21 @@ void GCPad::GetInput(SPADStatus* const pad) } } -void GCPad::SetOutput(const bool on) +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 m_rumble->controls[0]->control_ref->State(on && (Host_RendererHasFocus() || m_options[0].settings[0]->value)); diff --git a/Source/Core/Core/Src/HW/GCPadEmu.h b/Source/Core/Core/Src/HW/GCPadEmu.h index 5185ff221c..e57e6b0b68 100644 --- a/Source/Core/Core/Src/HW/GCPadEmu.h +++ b/Source/Core/Core/Src/HW/GCPadEmu.h @@ -28,7 +28,8 @@ public: GCPad(const unsigned int index); void GetInput(SPADStatus* const pad); - void SetOutput(const bool on); + void SetOutput(const u8 on); + void SetMotor(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..ade19b758e --- /dev/null +++ b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.cpp @@ -0,0 +1,314 @@ +// 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; + + // Seen in F-Zero GX + case CMD_MOTOR_OFF: + 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); + Movie::InputUpdate(); + } + else if(Movie::IsRecordingInput()) + { + Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber); + Movie::InputUpdate(); + } + else + Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); + + // Thankfully changing mode does not change the high bits ;) + _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 == 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 + } + 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; + 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); + + 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..2245765863 --- /dev/null +++ b/Source/Core/Core/Src/HW/SI_DeviceGCSteeringWheel.h @@ -0,0 +1,119 @@ +// 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, + CMD_MOTOR_OFF = 0xff, + }; + + 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/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 7eb5e89018..e85797b8f8 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -256,15 +256,15 @@ void DoState(PointerWrap &p) u32 i; for (i=0; i> 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"); 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/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, diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index 76508daf7c..ce4cd9cb22 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; @@ -618,6 +623,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); @@ -1053,6 +1064,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/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) { 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; 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")); diff --git a/Source/Core/DolphinWX/resources/dolphin-emu.desktop b/Source/Core/DolphinWX/resources/dolphin-emu.desktop new file mode 100644 index 0000000000..f201f07f22 --- /dev/null +++ b/Source/Core/DolphinWX/resources/dolphin-emu.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=Dolphin Emulator +Comment=A Wii/GameCube Emulator +Icon=dolphin-emu +Exec=dolphin-emu +Categories=Game; + diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp index 08d62bcfc1..af6ee7e77c 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp @@ -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 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 }