Netplay: Fixed some potential multithreading issues
This commit is contained in:
parent
72f0d961db
commit
13103551cf
13 changed files with 113 additions and 98 deletions
|
@ -31,6 +31,7 @@ double EmulationSettings::_stereoAngle = 0;
|
||||||
double EmulationSettings::_reverbStrength = 0;
|
double EmulationSettings::_reverbStrength = 0;
|
||||||
double EmulationSettings::_reverbDelay = 0;
|
double EmulationSettings::_reverbDelay = 0;
|
||||||
uint32_t EmulationSettings::_crossFeedRatio = 0;
|
uint32_t EmulationSettings::_crossFeedRatio = 0;
|
||||||
|
SimpleLock EmulationSettings::_equalizerLock;
|
||||||
|
|
||||||
NesModel EmulationSettings::_model = NesModel::Auto;
|
NesModel EmulationSettings::_model = NesModel::Auto;
|
||||||
PpuModel EmulationSettings::_ppuModel = PpuModel::Ppu2C02;
|
PpuModel EmulationSettings::_ppuModel = PpuModel::Ppu2C02;
|
||||||
|
@ -115,28 +116,6 @@ uint8_t EmulationSettings::_paletteLut[11][64] = {
|
||||||
/* 2C05-05 */ { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,15,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,15,62,63 },
|
/* 2C05-05 */ { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,15,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,15,62,63 },
|
||||||
};
|
};
|
||||||
|
|
||||||
void EmulationSettings::SetEqualizerBands(double *bands, uint32_t bandCount)
|
|
||||||
{
|
|
||||||
Console::Pause();
|
|
||||||
_bands.clear();
|
|
||||||
_bandGains.clear();
|
|
||||||
for(uint32_t i = 0; i < bandCount; i++) {
|
|
||||||
_bands.push_back(bands[i]);
|
|
||||||
_bandGains.push_back(0);
|
|
||||||
}
|
|
||||||
Console::Resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmulationSettings::SetRewindBufferSize(uint32_t seconds)
|
|
||||||
{
|
|
||||||
if(seconds == 0 || _rewindBufferSize == 0) {
|
|
||||||
Console::Pause();
|
|
||||||
RewindManager::ClearBuffer();
|
|
||||||
Console::Resume();
|
|
||||||
}
|
|
||||||
_rewindBufferSize = seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t EmulationSettings::GetEmulationSpeed(bool ignoreTurbo)
|
uint32_t EmulationSettings::GetEmulationSpeed(bool ignoreTurbo)
|
||||||
{
|
{
|
||||||
if(ignoreTurbo) {
|
if(ignoreTurbo) {
|
||||||
|
|
|
@ -537,6 +537,7 @@ private:
|
||||||
static RamPowerOnState _ramPowerOnState;
|
static RamPowerOnState _ramPowerOnState;
|
||||||
|
|
||||||
static SimpleLock _shortcutLock;
|
static SimpleLock _shortcutLock;
|
||||||
|
static SimpleLock _equalizerLock;
|
||||||
static SimpleLock _lock;
|
static SimpleLock _lock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -658,29 +659,37 @@ public:
|
||||||
_audioSettingsChanged = true;
|
_audioSettingsChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double GetBandGain(int band)
|
static vector<double> GetBandGains()
|
||||||
{
|
{
|
||||||
if(band < (int)_bandGains.size()) {
|
auto lock = _equalizerLock.AcquireSafe();
|
||||||
return _bandGains[band];
|
return _bandGains;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetBandGain(int band, double gain)
|
static void SetBandGain(int band, double gain)
|
||||||
{
|
{
|
||||||
|
auto lock = _equalizerLock.AcquireSafe();
|
||||||
if(band < (int)_bandGains.size()) {
|
if(band < (int)_bandGains.size()) {
|
||||||
_bandGains[band] = gain;
|
_bandGains[band] = gain;
|
||||||
}
|
|
||||||
_audioSettingsChanged = true;
|
_audioSettingsChanged = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static vector<double> GetEqualizerBands()
|
static vector<double> GetEqualizerBands()
|
||||||
{
|
{
|
||||||
|
auto lock = _equalizerLock.AcquireSafe();
|
||||||
return _bands;
|
return _bands;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetEqualizerBands(double *bands, uint32_t bandCount);
|
static void SetEqualizerBands(double *bands, uint32_t bandCount)
|
||||||
|
{
|
||||||
|
auto lock = _equalizerLock.AcquireSafe();
|
||||||
|
_bands.clear();
|
||||||
|
_bandGains.clear();
|
||||||
|
for(uint32_t i = 0; i < bandCount; i++) {
|
||||||
|
_bands.push_back(bands[i]);
|
||||||
|
_bandGains.push_back(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static EqualizerFilterType GetEqualizerFilterType()
|
static EqualizerFilterType GetEqualizerFilterType()
|
||||||
{
|
{
|
||||||
|
@ -830,7 +839,10 @@ public:
|
||||||
return _rewindSpeed;
|
return _rewindSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetRewindBufferSize(uint32_t seconds);
|
static void SetRewindBufferSize(uint32_t seconds)
|
||||||
|
{
|
||||||
|
_rewindBufferSize = seconds;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t GetRewindBufferSize()
|
static uint32_t GetRewindBufferSize()
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@ using std::thread;
|
||||||
#include "ClientConnectionData.h"
|
#include "ClientConnectionData.h"
|
||||||
#include "GameClientConnection.h"
|
#include "GameClientConnection.h"
|
||||||
|
|
||||||
unique_ptr<GameClient> GameClient::Instance;
|
shared_ptr<GameClient> GameClient::_instance;
|
||||||
|
|
||||||
GameClient::GameClient()
|
GameClient::GameClient()
|
||||||
{
|
{
|
||||||
|
@ -29,36 +29,42 @@ GameClient::~GameClient()
|
||||||
|
|
||||||
bool GameClient::Connected()
|
bool GameClient::Connected()
|
||||||
{
|
{
|
||||||
if(Instance) {
|
shared_ptr<GameClient> instance = _instance;
|
||||||
return Instance->_connected;
|
return instance ? instance->_connected : false;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameClient::Connect(shared_ptr<ClientConnectionData> connectionData)
|
void GameClient::Connect(shared_ptr<ClientConnectionData> connectionData)
|
||||||
{
|
{
|
||||||
Instance.reset(new GameClient());
|
_instance.reset(new GameClient());
|
||||||
Instance->PrivateConnect(connectionData);
|
|
||||||
Instance->_clientThread.reset(new thread(&GameClient::Exec, Instance.get()));
|
shared_ptr<GameClient> instance = _instance;
|
||||||
|
if(instance) {
|
||||||
|
instance->PrivateConnect(connectionData);
|
||||||
|
instance->_clientThread.reset(new thread(&GameClient::Exec, instance.get()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameClient::Disconnect()
|
void GameClient::Disconnect()
|
||||||
{
|
{
|
||||||
Instance.reset();
|
_instance.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<GameClientConnection> GameClient::GetConnection()
|
||||||
|
{
|
||||||
|
shared_ptr<GameClient> instance = _instance;
|
||||||
|
return instance ? instance->_connection : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameClient::PrivateConnect(shared_ptr<ClientConnectionData> connectionData)
|
void GameClient::PrivateConnect(shared_ptr<ClientConnectionData> connectionData)
|
||||||
{
|
{
|
||||||
_stop = false;
|
_stop = false;
|
||||||
_socket.reset(new Socket());
|
shared_ptr<Socket> socket(new Socket());
|
||||||
if(_socket->Connect(connectionData->Host.c_str(), connectionData->Port)) {
|
if(socket->Connect(connectionData->Host.c_str(), connectionData->Port)) {
|
||||||
_connection.reset(new GameClientConnection(_socket, connectionData));
|
_connection.reset(new GameClientConnection(socket, connectionData));
|
||||||
_connected = true;
|
_connected = true;
|
||||||
} else {
|
} else {
|
||||||
MessageManager::DisplayMessage("NetPlay", "CouldNotConnect");
|
MessageManager::DisplayMessage("NetPlay", "CouldNotConnect");
|
||||||
_connected = false;
|
_connected = false;
|
||||||
_socket.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +77,7 @@ void GameClient::Exec()
|
||||||
_connection->SendInput();
|
_connection->SendInput();
|
||||||
} else {
|
} else {
|
||||||
_connected = false;
|
_connected = false;
|
||||||
_socket.reset();
|
_connection->Shutdown();
|
||||||
_connection.reset();
|
_connection.reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -89,34 +95,26 @@ void GameClient::ProcessNotification(ConsoleNotificationType type, void* paramet
|
||||||
|
|
||||||
uint8_t GameClient::GetControllerState(uint8_t port)
|
uint8_t GameClient::GetControllerState(uint8_t port)
|
||||||
{
|
{
|
||||||
if(Instance && Instance->_connection) {
|
shared_ptr<GameClientConnection> connection = GetConnection();
|
||||||
return Instance->_connection->GetControllerState(port);
|
return connection ? connection->GetControllerState(port) : 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameClient::SelectController(uint8_t port)
|
void GameClient::SelectController(uint8_t port)
|
||||||
{
|
{
|
||||||
if(Instance && Instance->_connection) {
|
shared_ptr<GameClientConnection> connection = GetConnection();
|
||||||
Instance->_connection->SelectController(port);
|
if(connection) {
|
||||||
|
connection->SelectController(port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t GameClient::GetAvailableControllers()
|
uint8_t GameClient::GetAvailableControllers()
|
||||||
{
|
{
|
||||||
if(Instance && Instance->_connection) {
|
shared_ptr<GameClientConnection> connection = GetConnection();
|
||||||
return Instance->_connection->GetAvailableControllers();
|
return connection ? connection->GetAvailableControllers() : 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t GameClient::GetControllerPort()
|
uint8_t GameClient::GetControllerPort()
|
||||||
{
|
{
|
||||||
if(Instance && Instance->_connection) {
|
shared_ptr<GameClientConnection> connection = GetConnection();
|
||||||
return Instance->_connection->GetControllerPort();
|
return connection ? connection->GetControllerPort() : GameConnection::SpectatorPort;
|
||||||
}
|
|
||||||
|
|
||||||
return GameConnection::SpectatorPort;
|
|
||||||
}
|
}
|
|
@ -10,14 +10,15 @@ class ClientConnectionData;
|
||||||
class GameClient : public INotificationListener
|
class GameClient : public INotificationListener
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static unique_ptr<GameClient> Instance;
|
static shared_ptr<GameClient> _instance;
|
||||||
unique_ptr<thread> _clientThread;
|
unique_ptr<thread> _clientThread;
|
||||||
atomic<bool> _stop;
|
atomic<bool> _stop;
|
||||||
|
|
||||||
shared_ptr<Socket> _socket;
|
shared_ptr<GameClientConnection> _connection;
|
||||||
unique_ptr<GameClientConnection> _connection;
|
|
||||||
bool _connected = false;
|
bool _connected = false;
|
||||||
|
|
||||||
|
static shared_ptr<GameClientConnection> GetConnection();
|
||||||
|
|
||||||
void PrivateConnect(shared_ptr<ClientConnectionData> connectionData);
|
void PrivateConnect(shared_ptr<ClientConnectionData> connectionData);
|
||||||
void Exec();
|
void Exec();
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,20 @@ GameClientConnection::GameClientConnection(shared_ptr<Socket> socket, shared_ptr
|
||||||
|
|
||||||
GameClientConnection::~GameClientConnection()
|
GameClientConnection::~GameClientConnection()
|
||||||
{
|
{
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameClientConnection::Shutdown()
|
||||||
|
{
|
||||||
|
if(!_shutdown) {
|
||||||
_shutdown = true;
|
_shutdown = true;
|
||||||
DisableControllers();
|
DisableControllers();
|
||||||
|
|
||||||
|
EmulationSettings::ClearFlags(EmulationFlags::ForceMaxSpeed);
|
||||||
|
MessageManager::UnregisterNotificationListener(this);
|
||||||
MessageManager::SendNotification(ConsoleNotificationType::DisconnectedFromServer);
|
MessageManager::SendNotification(ConsoleNotificationType::DisconnectedFromServer);
|
||||||
MessageManager::DisplayMessage("NetPlay", "ConnectionLost");
|
MessageManager::DisplayMessage("NetPlay", "ConnectionLost");
|
||||||
MessageManager::UnregisterNotificationListener(this);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameClientConnection::SendHandshake()
|
void GameClientConnection::SendHandshake()
|
||||||
|
@ -49,6 +57,7 @@ void GameClientConnection::SendControllerSelection(uint8_t port)
|
||||||
|
|
||||||
void GameClientConnection::ClearInputData()
|
void GameClientConnection::ClearInputData()
|
||||||
{
|
{
|
||||||
|
LockHandler lock = _writeLock.AcquireSafe();
|
||||||
for(int i = 0; i < 4; i++) {
|
for(int i = 0; i < 4; i++) {
|
||||||
_inputSize[i] = 0;
|
_inputSize[i] = 0;
|
||||||
_inputData[i].clear();
|
_inputData[i].clear();
|
||||||
|
|
|
@ -41,6 +41,8 @@ public:
|
||||||
GameClientConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData);
|
GameClientConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData);
|
||||||
~GameClientConnection();
|
~GameClientConnection();
|
||||||
|
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
void ProcessNotification(ConsoleNotificationType type, void* parameter) override;
|
void ProcessNotification(ConsoleNotificationType type, void* parameter) override;
|
||||||
|
|
||||||
uint8_t GetControllerState(uint8_t port);
|
uint8_t GetControllerState(uint8_t port);
|
||||||
|
|
|
@ -20,6 +20,7 @@ GameConnection::GameConnection(shared_ptr<Socket> socket, shared_ptr<ClientConne
|
||||||
|
|
||||||
void GameConnection::ReadSocket()
|
void GameConnection::ReadSocket()
|
||||||
{
|
{
|
||||||
|
auto lock = _socketLock.AcquireSafe();
|
||||||
int bytesReceived = _socket->Recv((char*)_readBuffer + _readPosition, 0x40000 - _readPosition, 0);
|
int bytesReceived = _socket->Recv((char*)_readBuffer + _readPosition, 0x40000 - _readPosition, 0);
|
||||||
if(bytesReceived > 0) {
|
if(bytesReceived > 0) {
|
||||||
_readPosition += bytesReceived;
|
_readPosition += bytesReceived;
|
||||||
|
@ -32,7 +33,7 @@ bool GameConnection::ExtractMessage(void *buffer, uint32_t &messageLength)
|
||||||
|
|
||||||
if(messageLength > 1000000) {
|
if(messageLength > 1000000) {
|
||||||
MessageManager::Log("[Netplay] Invalid data received, closing connection.");
|
MessageManager::Log("[Netplay] Invalid data received, closing connection.");
|
||||||
_socket->Close();
|
Disconnect();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,13 +72,13 @@ NetMessage* GameConnection::ReadMessage()
|
||||||
|
|
||||||
void GameConnection::SendNetMessage(NetMessage &message)
|
void GameConnection::SendNetMessage(NetMessage &message)
|
||||||
{
|
{
|
||||||
_socketLock.Acquire();
|
auto lock = _socketLock.AcquireSafe();
|
||||||
message.Send(*_socket.get());
|
message.Send(*_socket.get());
|
||||||
_socketLock.Release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameConnection::Disconnect()
|
void GameConnection::Disconnect()
|
||||||
{
|
{
|
||||||
|
auto lock = _socketLock.AcquireSafe();
|
||||||
_socket->Close();
|
_socket->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -567,6 +567,7 @@ std::unordered_map<string, string> MessageManager::_caResources = {
|
||||||
|
|
||||||
std::list<string> MessageManager::_log;
|
std::list<string> MessageManager::_log;
|
||||||
SimpleLock MessageManager::_logLock;
|
SimpleLock MessageManager::_logLock;
|
||||||
|
SimpleLock MessageManager::_notificationLock;
|
||||||
IMessageManager* MessageManager::_messageManager = nullptr;
|
IMessageManager* MessageManager::_messageManager = nullptr;
|
||||||
vector<INotificationListener*> MessageManager::_notificationListeners;
|
vector<INotificationListener*> MessageManager::_notificationListeners;
|
||||||
|
|
||||||
|
@ -651,16 +652,20 @@ string MessageManager::GetLog()
|
||||||
|
|
||||||
void MessageManager::RegisterNotificationListener(INotificationListener* notificationListener)
|
void MessageManager::RegisterNotificationListener(INotificationListener* notificationListener)
|
||||||
{
|
{
|
||||||
|
auto lock = _notificationLock.AcquireSafe();
|
||||||
MessageManager::_notificationListeners.push_back(notificationListener);
|
MessageManager::_notificationListeners.push_back(notificationListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageManager::UnregisterNotificationListener(INotificationListener* notificationListener)
|
void MessageManager::UnregisterNotificationListener(INotificationListener* notificationListener)
|
||||||
{
|
{
|
||||||
|
auto lock = _notificationLock.AcquireSafe();
|
||||||
MessageManager::_notificationListeners.erase(std::remove(MessageManager::_notificationListeners.begin(), MessageManager::_notificationListeners.end(), notificationListener), MessageManager::_notificationListeners.end());
|
MessageManager::_notificationListeners.erase(std::remove(MessageManager::_notificationListeners.begin(), MessageManager::_notificationListeners.end(), notificationListener), MessageManager::_notificationListeners.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageManager::SendNotification(ConsoleNotificationType type, void* parameter)
|
void MessageManager::SendNotification(ConsoleNotificationType type, void* parameter)
|
||||||
{
|
{
|
||||||
|
auto lock = _notificationLock.AcquireSafe();
|
||||||
|
|
||||||
//Iterate on a copy to prevent issues if a notification causes a listener to unregister itself
|
//Iterate on a copy to prevent issues if a notification causes a listener to unregister itself
|
||||||
vector<INotificationListener*> listeners = MessageManager::_notificationListeners;
|
vector<INotificationListener*> listeners = MessageManager::_notificationListeners;
|
||||||
vector<INotificationListener*> processedListeners;
|
vector<INotificationListener*> processedListeners;
|
||||||
|
|
|
@ -22,6 +22,7 @@ private:
|
||||||
static std::unordered_map<string, string> _caResources;
|
static std::unordered_map<string, string> _caResources;
|
||||||
|
|
||||||
static SimpleLock _logLock;
|
static SimpleLock _logLock;
|
||||||
|
static SimpleLock _notificationLock;
|
||||||
static std::list<string> _log;
|
static std::list<string> _log;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -28,16 +28,16 @@ RewindManager::~RewindManager()
|
||||||
void RewindManager::ClearBuffer()
|
void RewindManager::ClearBuffer()
|
||||||
{
|
{
|
||||||
if(_instance) {
|
if(_instance) {
|
||||||
_instance->_history.clear();
|
_history.clear();
|
||||||
_instance->_historyBackup.clear();
|
_historyBackup.clear();
|
||||||
_instance->_currentHistory = RewindData();
|
_currentHistory = RewindData();
|
||||||
_instance->_framesToFastForward = 0;
|
_framesToFastForward = 0;
|
||||||
_instance->_videoHistory.clear();
|
_videoHistory.clear();
|
||||||
_instance->_videoHistoryBuilder.clear();
|
_videoHistoryBuilder.clear();
|
||||||
_instance->_audioHistory.clear();
|
_audioHistory.clear();
|
||||||
_instance->_audioHistoryBuilder.clear();
|
_audioHistoryBuilder.clear();
|
||||||
_instance->_rewindState = RewindState::Stopped;
|
_rewindState = RewindState::Stopped;
|
||||||
_instance->AddHistoryBlock();
|
_currentHistory = RewindData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,8 @@ void RewindManager::ProcessNotification(ConsoleNotificationType type, void * par
|
||||||
_currentHistory.FrameCount++;
|
_currentHistory.FrameCount++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ClearBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +82,7 @@ void RewindManager::ProcessNotification(ConsoleNotificationType type, void * par
|
||||||
void RewindManager::AddHistoryBlock()
|
void RewindManager::AddHistoryBlock()
|
||||||
{
|
{
|
||||||
uint32_t maxHistorySize = EmulationSettings::GetRewindBufferSize() * 120;
|
uint32_t maxHistorySize = EmulationSettings::GetRewindBufferSize() * 120;
|
||||||
|
if(maxHistorySize > 0) {
|
||||||
while(_history.size() > maxHistorySize) {
|
while(_history.size() > maxHistorySize) {
|
||||||
_history.pop_front();
|
_history.pop_front();
|
||||||
}
|
}
|
||||||
|
@ -89,6 +92,7 @@ void RewindManager::AddHistoryBlock()
|
||||||
}
|
}
|
||||||
_currentHistory = RewindData();
|
_currentHistory = RewindData();
|
||||||
_currentHistory.SaveState();
|
_currentHistory.SaveState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewindManager::PopHistory()
|
void RewindManager::PopHistory()
|
||||||
|
|
|
@ -40,6 +40,8 @@ private:
|
||||||
void ProcessFrame(void *frameBuffer, uint32_t width, uint32_t height);
|
void ProcessFrame(void *frameBuffer, uint32_t width, uint32_t height);
|
||||||
bool ProcessAudio(int16_t *soundBuffer, uint32_t sampleCount, uint32_t sampleRate);
|
bool ProcessAudio(int16_t *soundBuffer, uint32_t sampleCount, uint32_t sampleRate);
|
||||||
|
|
||||||
|
void ClearBuffer();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RewindManager();
|
RewindManager();
|
||||||
~RewindManager();
|
~RewindManager();
|
||||||
|
@ -47,8 +49,6 @@ public:
|
||||||
void ProcessNotification(ConsoleNotificationType type, void* parameter) override;
|
void ProcessNotification(ConsoleNotificationType type, void* parameter) override;
|
||||||
void ProcessEndOfFrame();
|
void ProcessEndOfFrame();
|
||||||
|
|
||||||
static void ClearBuffer();
|
|
||||||
|
|
||||||
static void RecordInput(uint8_t port, uint8_t input);
|
static void RecordInput(uint8_t port, uint8_t input);
|
||||||
static uint8_t GetInput(uint8_t port);
|
static uint8_t GetInput(uint8_t port);
|
||||||
|
|
||||||
|
|
|
@ -311,6 +311,7 @@ void SoundMixer::UpdateEqualizers(bool forceUpdate)
|
||||||
EqualizerFilterType type = EmulationSettings::GetEqualizerFilterType();
|
EqualizerFilterType type = EmulationSettings::GetEqualizerFilterType();
|
||||||
if(type != EqualizerFilterType::None) {
|
if(type != EqualizerFilterType::None) {
|
||||||
vector<double> bands = EmulationSettings::GetEqualizerBands();
|
vector<double> bands = EmulationSettings::GetEqualizerBands();
|
||||||
|
vector<double> bandGains = EmulationSettings::GetBandGains();
|
||||||
|
|
||||||
if(bands.size() != _eqFrequencyGrid->get_number_of_bands()) {
|
if(bands.size() != _eqFrequencyGrid->get_number_of_bands()) {
|
||||||
_equalizerLeft.reset();
|
_equalizerLeft.reset();
|
||||||
|
@ -332,8 +333,8 @@ void SoundMixer::UpdateEqualizers(bool forceUpdate)
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int i = 0; i < _eqFrequencyGrid->get_number_of_bands(); i++) {
|
for(unsigned int i = 0; i < _eqFrequencyGrid->get_number_of_bands(); i++) {
|
||||||
_equalizerLeft->change_band_gain_db(i, EmulationSettings::GetBandGain(i));
|
_equalizerLeft->change_band_gain_db(i, bandGains[i]);
|
||||||
_equalizerRight->change_band_gain_db(i, EmulationSettings::GetBandGain(i));
|
_equalizerRight->change_band_gain_db(i, bandGains[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_equalizerLeft.reset();
|
_equalizerLeft.reset();
|
||||||
|
|
|
@ -458,7 +458,9 @@ namespace Mesen.GUI.Forms
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InteropEmu.ConsoleNotificationType.DisconnectedFromServer:
|
case InteropEmu.ConsoleNotificationType.DisconnectedFromServer:
|
||||||
|
this.BeginInvoke((MethodInvoker)(() => {
|
||||||
ConfigManager.Config.ApplyConfig();
|
ConfigManager.Config.ApplyConfig();
|
||||||
|
}));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InteropEmu.ConsoleNotificationType.GameStopped:
|
case InteropEmu.ConsoleNotificationType.GameStopped:
|
||||||
|
|
Loading…
Add table
Reference in a new issue