Merge branch 'master' into wii-network

This commit is contained in:
Matthew Parlane 2013-01-08 21:18:48 +13:00
commit 5b96fb766f
38 changed files with 826 additions and 687 deletions

1
.gitignore vendored
View File

@ -35,4 +35,3 @@ Source/Core/Common/Src/scmrev.h
*.ipch
.sconsign.dblite
Externals/scons-local/*
*~

View File

@ -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")

View File

@ -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;

View File

@ -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); }

View File

@ -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

View File

@ -301,6 +301,7 @@
<ClCompile Include="Src\HW\SI_DeviceAMBaseboard.cpp" />
<ClCompile Include="Src\HW\SI_DeviceGBA.cpp" />
<ClCompile Include="Src\HW\SI_DeviceGCController.cpp" />
<ClCompile Include="Src\HW\SI_DeviceGCSteeringWheel.cpp" />
<ClCompile Include="Src\HW\Sram.cpp" />
<ClCompile Include="Src\HW\StreamADPCM.cpp" />
<ClCompile Include="Src\HW\SystemTimers.cpp" />
@ -505,6 +506,7 @@
<ClInclude Include="Src\HW\SI_DeviceAMBaseboard.h" />
<ClInclude Include="Src\HW\SI_DeviceGBA.h" />
<ClInclude Include="Src\HW\SI_DeviceGCController.h" />
<ClInclude Include="Src\HW\SI_DeviceGCSteeringWheel.h" />
<ClInclude Include="Src\HW\Sram.h" />
<ClInclude Include="Src\HW\StreamADPCM.h" />
<ClInclude Include="Src\HW\SystemTimers.h" />

View File

@ -290,6 +290,9 @@
<ClCompile Include="Src\HW\SI_DeviceGCController.cpp">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClCompile>
<ClCompile Include="Src\HW\SI_DeviceGCSteeringWheel.cpp">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClCompile>
<ClCompile Include="Src\HW\VideoInterface.cpp">
<Filter>HW %28Flipper/Hollywood%29\VI - Video Interface</Filter>
</ClCompile>
@ -820,6 +823,9 @@
<ClInclude Include="Src\HW\SI_DeviceGCController.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude>
<ClInclude Include="Src\HW\SI_DeviceGCSteeringWheel.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude>
<ClInclude Include="Src\HW\SI.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude>

View File

@ -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<std::recursive_mutex> 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);
}
}
}

View File

@ -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);
}

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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 <stdio.h>
#include <stdlib.h>
#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<EBufferCommands>(_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<u8*>(&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<u8*>(&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);
}

View File

@ -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

View File

@ -256,15 +256,15 @@ void DoState(PointerWrap &p)
u32 i;
for (i=0; i<IPC_MAX_FDS; i++)
{
u32 exists;
u32 exists = 0;
p.Do(exists);
if (exists)
{
u32 isHw;
u32 isHw = 0;
p.Do(isHw);
if (isHw)
{
u32 hwId;
u32 hwId = 0;
p.Do(hwId);
g_FdMap[i] = AccessDeviceByID(hwId);
}

View File

@ -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()

View File

@ -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");

View File

@ -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)

View File

@ -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,

View File

@ -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)))

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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

View File

@ -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;

View File

@ -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"));

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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<float> s_cached_sourcerc;
static MathUtil::Rectangle<float> 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<float> &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();
}

View File

@ -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;
}
}

View File

@ -17,16 +17,12 @@
#include "GLUtil.h"
#include <string.h>
#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_height; y++) {
for(u32 c=0; c<char_count; c++) {
for(u32 x=0; x<char_width; x++) {
bool pixel = rasters[c][y] & (1<<(char_width-x-1));
texture_data[char_width*char_count*y+char_width*c+x] = pixel ? -1 : 0;
}
}
// set GL modes
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// create the raster font
fontOffset = glGenLists(128);
for (int i = 32; i < 127; i++) {
glNewList(i + fontOffset, GL_COMPILE);
glBitmap(8, 13, 0.0f, 2.0f, 10.0f, 0.0f, rasters[i - 32]);
glEndList();
}
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, char_width*char_count, char_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);
delete [] texture_data;
// generate shader
shader_program = OpenGL_CompileProgram(s_vertex_shader, s_fragment_shader);
// bound uniforms
glUseProgram(shader_program);
glUniform1i(glGetUniformLocation(shader_program,"textureSampler"), 0); // GL_TEXTURE0
uniform_color_id = glGetUniformLocation(shader_program,"color");
glUniform4f(uniform_color_id, 1, 1, 1, 1);
cached_color = -1;
glUseProgram(0);
// generate VBO & VAO
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(VAO);
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "vertexPosition"));
glVertexAttribPointer(glGetAttribLocation(shader_program, "vertexPosition"), 2, GL_FLOAT, 0, sizeof(GLfloat)*4, NULL);
glEnableVertexAttribArray(glGetAttribLocation(shader_program, "texturePosition"));
glVertexAttribPointer(glGetAttribLocation(shader_program, "texturePosition"), 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
// TODO: this after merging with graphic_update
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
temp_buffer = new char[TEMP_BUFFER_SIZE];
}
RasterFont::~RasterFont()
{
glDeleteTextures(1, &texture);
glDeleteBuffers(1, &VBO);
glDeleteVertexArrays(1, &VAO);
glDeleteProgram(shader_program);
glDeleteLists(fontOffset, 128);
delete [] temp_buffer;
}
void RasterFont::printMultilineText(const char *text, double start_x, double start_y, double z, int bbWidth, int bbHeight, u32 color)
void RasterFont::printString(const char *s, double x, double y, double z)
{
int length = (int)strlen(text);
int length = (int)strlen(s);
if (!length)
return; // nothing to do
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, length*4*6*sizeof(GLfloat), NULL, GL_STREAM_DRAW);
GLfloat *vertices = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
int usage = 0;
GLfloat delta_x = 2*char_width/GLfloat(bbWidth);
GLfloat delta_y = 2*char_height/GLfloat(bbHeight);
GLfloat border_x = 1*2/GLfloat(bbWidth);
GLfloat border_y = 2*2/GLfloat(bbHeight);
GLfloat x = start_x;
GLfloat y = start_y;
for(int i=0; i<length; i++) {
u8 c = text[i];
if(c == '\n') {
x = start_x;
y -= delta_y + border_y;
continue;
}
// do not print spaces, they can be skipped easyly
if(c == ' ') {
x += delta_x + border_x;
continue;
}
if(c < char_offset || c >= 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);
}

View File

@ -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_

View File

@ -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<u32> 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<EFBRectangle>::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);

View File

@ -56,13 +56,6 @@
namespace OGL
{
struct VBOCache {
GLuint vbo;
GLuint vao;
TargetRectangle targetSource;
};
static std::map<u64,VBOCache> 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<u64, VBOCache>::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<u64,VBOCache>(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<u64, VBOCache>::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)

View File

@ -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();

View File

@ -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();

View File

@ -64,6 +64,9 @@ VertexManager::VertexManager()
// max_Index_size = MAXIBUFFERSIZE;
//
//GL_REPORT_ERRORD();
glEnableClientState(GL_VERTEX_ARRAY);
GL_REPORT_ERRORD();
}
void VertexManager::CreateDeviceObjects()

View File

@ -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
}