diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index 21f30a7f..852cbcf4 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -122,6 +122,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 47912be5..ea22f29b 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -819,6 +819,7 @@
+
diff --git a/Core/Gameboy/GbPpu.cpp b/Core/Gameboy/GbPpu.cpp
index c502ab94..4158b464 100644
--- a/Core/Gameboy/GbPpu.cpp
+++ b/Core/Gameboy/GbPpu.cpp
@@ -8,6 +8,8 @@
#include "Shared/Emulator.h"
#include "Shared/EmuSettings.h"
#include "Shared/RewindManager.h"
+#include "Shared/Interfaces/IControlManager.h"
+#include "Shared/RenderedFrame.h"
#include "Shared/Video/VideoDecoder.h"
#include "Shared/NotificationManager.h"
#include "Shared/MessageManager.h"
@@ -650,7 +652,7 @@ void GbPpu::SendFrame()
}
_isFirstFrame = false;
- RenderedFrame frame(_currentBuffer, GbConstants::ScreenWidth, GbConstants::ScreenHeight, 1.0, _state.FrameCount);
+ RenderedFrame frame(_currentBuffer, GbConstants::ScreenWidth, GbConstants::ScreenHeight, 1.0, _state.FrameCount, _gameboy->GetControlManager()->GetPortStates());
#ifdef LIBRETRO
_emu->GetVideoDecoder()->UpdateFrame(frame, true, false);
#else
diff --git a/Core/Gameboy/Input/GbController.h b/Core/Gameboy/Input/GbController.h
index 88fd10f6..65f07102 100644
--- a/Core/Gameboy/Input/GbController.h
+++ b/Core/Gameboy/Input/GbController.h
@@ -3,6 +3,7 @@
#include "Shared/BaseControlDevice.h"
#include "Shared/Emulator.h"
#include "Shared/EmuSettings.h"
+#include "Shared/InputHud.h"
#include "Utilities/Serializer.h"
class GbController : public BaseControlDevice
@@ -57,4 +58,23 @@ public:
void WriteRam(uint16_t addr, uint8_t value) override
{
}
+
+ void DrawController(InputHud& hud)
+ {
+ hud.DrawOutline(35, 14);
+
+ hud.DrawButton(5, 3, 3, 3, IsPressed(Buttons::Up));
+ hud.DrawButton(5, 9, 3, 3, IsPressed(Buttons::Down));
+ hud.DrawButton(2, 6, 3, 3, IsPressed(Buttons::Left));
+ hud.DrawButton(8, 6, 3, 3, IsPressed(Buttons::Right));
+ hud.DrawButton(5, 6, 3, 3, false);
+
+ hud.DrawButton(30, 7, 3, 3, IsPressed(Buttons::A));
+ hud.DrawButton(25, 7, 3, 3, IsPressed(Buttons::B));
+
+ hud.DrawButton(13, 9, 4, 2, IsPressed(Buttons::Select));
+ hud.DrawButton(18, 9, 4, 2, IsPressed(Buttons::Start));
+
+ hud.DrawNumber(_port + 1, 16, 2);
+ }
};
\ No newline at end of file
diff --git a/Core/NES/Input/NesController.h b/Core/NES/Input/NesController.h
index ff32b13d..36f4f5f4 100644
--- a/Core/NES/Input/NesController.h
+++ b/Core/NES/Input/NesController.h
@@ -3,6 +3,7 @@
#include "Shared/BaseControlDevice.h"
#include "Shared/Emulator.h"
#include "Shared/EmuSettings.h"
+#include "Shared/InputHud.h"
#include "Utilities/Serializer.h"
class NesController : public BaseControlDevice
@@ -132,4 +133,23 @@ public:
{
StrobeProcessWrite(value);
}
+
+ void DrawController(InputHud& hud)
+ {
+ hud.DrawOutline(35, 14);
+
+ hud.DrawButton(5, 3, 3, 3, IsPressed(Buttons::Up));
+ hud.DrawButton(5, 9, 3, 3, IsPressed(Buttons::Down));
+ hud.DrawButton(2, 6, 3, 3, IsPressed(Buttons::Left));
+ hud.DrawButton(8, 6, 3, 3, IsPressed(Buttons::Right));
+ hud.DrawButton(5, 6, 3, 3, false);
+
+ hud.DrawButton(30, 7, 3, 3, IsPressed(Buttons::A));
+ hud.DrawButton(25, 7, 3, 3, IsPressed(Buttons::B));
+
+ hud.DrawButton(13, 9, 4, 2, IsPressed(Buttons::Select));
+ hud.DrawButton(18, 9, 4, 2, IsPressed(Buttons::Start));
+
+ hud.DrawNumber(_port + 1, 16, 2);
+ }
};
\ No newline at end of file
diff --git a/Core/NES/NesPpu.cpp b/Core/NES/NesPpu.cpp
index b91b59f4..f697cba4 100644
--- a/Core/NES/NesPpu.cpp
+++ b/Core/NES/NesPpu.cpp
@@ -20,6 +20,7 @@
#include "Shared/Video/VideoDecoder.h"
#include "Shared/RewindManager.h"
#include "Shared/NotificationManager.h"
+#include "Shared/RenderedFrame.h"
#include "MemoryOperationType.h"
#include "EventType.h"
@@ -1071,7 +1072,7 @@ template void NesPpu::SendFrame()
_emu->GetNotificationManager()->SendNotification(ConsoleNotificationType::PpuFrameDone, _currentOutputBuffer);
}
- RenderedFrame frame(_currentOutputBuffer, NesConstants::ScreenWidth, NesConstants::ScreenHeight, 1.0, _frameCount);
+ RenderedFrame frame(_currentOutputBuffer, NesConstants::ScreenWidth, NesConstants::ScreenHeight, 1.0, _frameCount, _console->GetControlManager()->GetPortStates());
frame.Data = frameData; //HD packs
#ifdef LIBRETRO
@@ -1097,7 +1098,7 @@ template void NesPpu::SendFrameVsDualSystem()
NesConfig& cfg = _settings->GetNesConfig();
bool forRewind = _emu->GetRewindManager()->IsRewinding();
- RenderedFrame frame(_currentOutputBuffer, NesConstants::ScreenWidth, NesConstants::ScreenHeight, 1.0, _frameCount);
+ RenderedFrame frame(_currentOutputBuffer, NesConstants::ScreenWidth, NesConstants::ScreenHeight, 1.0, _frameCount, _console->GetControlManager()->GetPortStates());
if(cfg.VsDualVideoOutput == VsDualOutputOption::MainSystemOnly && _console->IsVsMainConsole()) {
_emu->GetVideoDecoder()->UpdateFrame(frame, forRewind, forRewind);
@@ -1119,7 +1120,7 @@ template void NesPpu::SendFrameVsDualSystem()
in2 += NesConstants::ScreenWidth;
}
- RenderedFrame mergedFrame(mergedBuffer, NesConstants::ScreenWidth*2, NesConstants::ScreenHeight, 1.0, _frameCount);
+ RenderedFrame mergedFrame(mergedBuffer, NesConstants::ScreenWidth*2, NesConstants::ScreenHeight, 1.0, _frameCount, _console->GetControlManager()->GetPortStates());
_emu->GetVideoDecoder()->UpdateFrame(mergedFrame, true, forRewind);
delete[] mergedBuffer;
}
diff --git a/Core/SNES/Input/Multitap.cpp b/Core/SNES/Input/Multitap.cpp
index 426d27f0..85de9182 100644
--- a/Core/SNES/Input/Multitap.cpp
+++ b/Core/SNES/Input/Multitap.cpp
@@ -3,7 +3,9 @@
#include "SNES/Input/SnesController.h"
#include "SNES/SnesConsole.h"
#include "SNES/InternalRegisters.h"
+#include "Shared/InputHud.h"
#include "Shared/Emulator.h"
+#include "Shared/EmuSettings.h"
string Multitap::GetKeyNames()
{
@@ -149,3 +151,43 @@ void Multitap::WriteRam(uint16_t addr, uint8_t value)
StrobeProcessWrite(value);
}
}
+
+void Multitap::DrawController(InputHud& hud)
+{
+ InputConfig& cfg = _emu->GetSettings()->GetInputConfig();
+
+ for(int j = 0; j < 4; j++) {
+ int port = j == 0 ? _port : (j + 1);
+ if(cfg.DisplayInputPort[port]) {
+ DrawController(hud, port);
+ }
+ }
+}
+
+void Multitap::DrawController(InputHud& hud, int port)
+{
+ int offset = port * Multitap::ButtonCount;
+
+ hud.DrawOutline(35, 14);
+
+ hud.DrawButton(5, 3, 3, 3, IsPressed(Buttons::Up + offset));
+ hud.DrawButton(5, 9, 3, 3, IsPressed(Buttons::Down + offset));
+ hud.DrawButton(2, 6, 3, 3, IsPressed(Buttons::Left + offset));
+ hud.DrawButton(8, 6, 3, 3, IsPressed(Buttons::Right + offset));
+ hud.DrawButton(5, 6, 3, 3, false);
+
+ hud.DrawButton(27, 3, 3, 3, IsPressed(Buttons::X + offset));
+ hud.DrawButton(27, 9, 3, 3, IsPressed(Buttons::B + offset));
+ hud.DrawButton(30, 6, 3, 3, IsPressed(Buttons::A + offset));
+ hud.DrawButton(24, 6, 3, 3, IsPressed(Buttons::Y + offset));
+
+ hud.DrawButton(4, 0, 5, 2, IsPressed(Buttons::L + offset));
+ hud.DrawButton(26, 0, 5, 2, IsPressed(Buttons::R + offset));
+
+ hud.DrawButton(13, 9, 4, 2, IsPressed(Buttons::Select + offset));
+ hud.DrawButton(18, 9, 4, 2, IsPressed(Buttons::Start + offset));
+
+ hud.DrawNumber(port + 1, 16, 2);
+
+ hud.EndDrawController();
+}
\ No newline at end of file
diff --git a/Core/SNES/Input/Multitap.h b/Core/SNES/Input/Multitap.h
index aa9ebdc5..98affe7f 100644
--- a/Core/SNES/Input/Multitap.h
+++ b/Core/SNES/Input/Multitap.h
@@ -6,6 +6,7 @@
class InternalRegisters;
class SnesController;
class SnesConsole;
+class InputHud;
class Multitap : public BaseControlDevice
{
@@ -18,6 +19,8 @@ private:
uint16_t _stateBuffer[4] = {};
InternalRegisters *_internalRegs = nullptr;
+ void DrawController(InputHud& hud, int port);
+
protected:
string GetKeyNames() override;
void InternalSetStateFromInput() override;
@@ -33,4 +36,6 @@ public:
uint8_t ReadRam(uint16_t addr) override;
void WriteRam(uint16_t addr, uint8_t value) override;
+
+ void DrawController(InputHud& hud) override;
};
\ No newline at end of file
diff --git a/Core/SNES/Input/SnesController.cpp b/Core/SNES/Input/SnesController.cpp
index 7507091d..35209156 100644
--- a/Core/SNES/Input/SnesController.cpp
+++ b/Core/SNES/Input/SnesController.cpp
@@ -1,6 +1,7 @@
#include "stdafx.h"
#include "SNES/Input/SnesController.h"
#include "Shared/Emulator.h"
+#include "Shared/InputHud.h"
SnesController::SnesController(Emulator* emu, uint8_t port, KeyMappingSet keyMappings) : BaseControlDevice(emu, ControllerType::SnesController, port, keyMappings)
{
@@ -96,3 +97,27 @@ void SnesController::WriteRam(uint16_t addr, uint8_t value)
{
StrobeProcessWrite(value);
}
+
+void SnesController::DrawController(InputHud& hud)
+{
+ hud.DrawOutline(35, 14);
+
+ hud.DrawButton(5, 3, 3, 3, IsPressed(Buttons::Up));
+ hud.DrawButton(5, 9, 3, 3, IsPressed(Buttons::Down));
+ hud.DrawButton(2, 6, 3, 3, IsPressed(Buttons::Left));
+ hud.DrawButton(8, 6, 3, 3, IsPressed(Buttons::Right));
+ hud.DrawButton(5, 6, 3, 3, false);
+
+ hud.DrawButton(27, 3, 3, 3, IsPressed(Buttons::X));
+ hud.DrawButton(27, 9, 3, 3, IsPressed(Buttons::B));
+ hud.DrawButton(30, 6, 3, 3, IsPressed(Buttons::A));
+ hud.DrawButton(24, 6, 3, 3, IsPressed(Buttons::Y));
+
+ hud.DrawButton(4, 0, 5, 2, IsPressed(Buttons::L));
+ hud.DrawButton(26, 0, 5, 2, IsPressed(Buttons::R));
+
+ hud.DrawButton(13, 9, 4, 2, IsPressed(Buttons::Select));
+ hud.DrawButton(18, 9, 4, 2, IsPressed(Buttons::Start));
+
+ hud.DrawNumber(_port + 1, 16, 2);
+}
diff --git a/Core/SNES/Input/SnesController.h b/Core/SNES/Input/SnesController.h
index 71e9250e..307fa637 100644
--- a/Core/SNES/Input/SnesController.h
+++ b/Core/SNES/Input/SnesController.h
@@ -23,4 +23,6 @@ public:
uint8_t ReadRam(uint16_t addr) override;
void WriteRam(uint16_t addr, uint8_t value) override;
+
+ void DrawController(InputHud& hud) override;
};
\ No newline at end of file
diff --git a/Core/SNES/Input/SnesMouse.h b/Core/SNES/Input/SnesMouse.h
index 1626413c..c290a2b9 100644
--- a/Core/SNES/Input/SnesMouse.h
+++ b/Core/SNES/Input/SnesMouse.h
@@ -3,6 +3,7 @@
#include "Shared/BaseControlDevice.h"
#include "Shared/Interfaces/IKeyManager.h"
#include "Shared/KeyManager.h"
+#include "Shared/InputHud.h"
#include "Shared/Emulator.h"
#include "Shared/EmuSettings.h"
#include "Utilities/Serializer.h"
@@ -85,4 +86,14 @@ public:
_stateBuffer = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
}
+
+ void DrawController(InputHud& hud)
+ {
+ hud.DrawOutline(11, 14);
+
+ hud.DrawButton(1, 1, 4, 5, IsPressed(Buttons::Left));
+ hud.DrawButton(6, 1, 4, 5, IsPressed(Buttons::Right));
+
+ hud.DrawNumber(_port + 1, 4, 7);
+ }
};
\ No newline at end of file
diff --git a/Core/SNES/SnesPpu.cpp b/Core/SNES/SnesPpu.cpp
index 372a07e9..2e4ebd20 100644
--- a/Core/SNES/SnesPpu.cpp
+++ b/Core/SNES/SnesPpu.cpp
@@ -12,6 +12,7 @@
#include "Shared/Video/VideoDecoder.h"
#include "Shared/Video/VideoRenderer.h"
#include "Shared/NotificationManager.h"
+#include "Shared/RenderedFrame.h"
#include "Shared/MessageManager.h"
#include "EventType.h"
#include "Shared/RewindManager.h"
@@ -1476,7 +1477,7 @@ void SnesPpu::SendFrame()
bool isRewinding = _emu->GetRewindManager()->IsRewinding();
- RenderedFrame frame(_currentBuffer, width, height, _useHighResOutput ? 0.5 : 1.0, _frameCount);
+ RenderedFrame frame(_currentBuffer, width, height, _useHighResOutput ? 0.5 : 1.0, _frameCount, _console->GetControlManager()->GetPortStates());
#ifdef LIBRETRO
_emu->GetVideoDecoder()->UpdateFrame(frame, true, isRewinding);
#else
diff --git a/Core/Shared/BaseControlDevice.h b/Core/Shared/BaseControlDevice.h
index 1b1fdd74..504aec01 100644
--- a/Core/Shared/BaseControlDevice.h
+++ b/Core/Shared/BaseControlDevice.h
@@ -7,6 +7,7 @@
#include "Utilities/ISerializable.h"
class Emulator;
+class InputHud;
class BaseControlDevice : public ISerializable
{
@@ -81,6 +82,8 @@ public:
void SetRawState(ControlDeviceState state);
ControlDeviceState GetRawState();
+ virtual void DrawController(InputHud& hud) {}
+
virtual uint8_t ReadRam(uint16_t addr) = 0;
virtual void WriteRam(uint16_t addr, uint8_t value) = 0;
diff --git a/Core/Shared/BaseControlManager.cpp b/Core/Shared/BaseControlManager.cpp
index ad5c96d2..4a737867 100644
--- a/Core/Shared/BaseControlManager.cpp
+++ b/Core/Shared/BaseControlManager.cpp
@@ -66,7 +66,7 @@ vector BaseControlManager::GetPortStates()
auto lock = _deviceLock.AcquireSafe();
vector states;
- for(int i = 0; i < 2; i++) {
+ for(int i = 0; i < BaseControlDevice::PortCount; i++) {
shared_ptr device = GetControlDevice(i);
if(device) {
states.push_back({ device->GetControllerType(), device->GetRawState() });
diff --git a/Core/Shared/EmuSettings.cpp b/Core/Shared/EmuSettings.cpp
index 8cd09d9b..285de211 100644
--- a/Core/Shared/EmuSettings.cpp
+++ b/Core/Shared/EmuSettings.cpp
@@ -82,7 +82,7 @@ void EmuSettings::SetInputConfig(InputConfig config)
}*/
}
-InputConfig EmuSettings::GetInputConfig()
+InputConfig& EmuSettings::GetInputConfig()
{
return _input;
}
diff --git a/Core/Shared/EmuSettings.h b/Core/Shared/EmuSettings.h
index a5baf86c..a478c27d 100644
--- a/Core/Shared/EmuSettings.h
+++ b/Core/Shared/EmuSettings.h
@@ -53,7 +53,7 @@ public:
AudioConfig GetAudioConfig();
void SetInputConfig(InputConfig config);
- InputConfig GetInputConfig();
+ InputConfig& GetInputConfig();
void SetEmulationConfig(EmulationConfig config);
EmulationConfig GetEmulationConfig();
diff --git a/Core/Shared/InputHud.cpp b/Core/Shared/InputHud.cpp
index 1b800f24..060a0307 100644
--- a/Core/Shared/InputHud.cpp
+++ b/Core/Shared/InputHud.cpp
@@ -1,180 +1,181 @@
#include "stdafx.h"
-#include "InputHud.h"
+#include "Shared/InputHud.h"
+#include "Shared/Emulator.h"
+#include "Shared/BaseControlManager.h"
+#include "Shared/Interfaces/IControlManager.h"
#include "Shared/BaseControlDevice.h"
#include "Shared/EmuSettings.h"
#include "Shared/Video/DebugHud.h"
static constexpr int color[2] = { 0x00111111, 0x00FFFFFF };
-InputHud::InputHud(Emulator* emu)
+InputHud::InputHud(Emulator* emu, DebugHud* hud)
{
_emu = emu;
+ _hud = hud;
}
-void InputHud::DrawController(int port, ControlDeviceState state, int x, int y, int frameNumber)
+void InputHud::DrawButton(int x, int y, int width, int height, bool pressed)
{
- //TODO
- /*SnesController controller(_console, 0, KeyMappingSet());
- controller.SetRawState(state);
-
- shared_ptr hud = _console->GetDebugHud();
- hud->DrawRectangle(0 + x, 0 + y, 35, 14, 0x80CCCCCC, true, 1, frameNumber);
- hud->DrawRectangle(0 + x, 0 + y, 35, 14, color[0], false, 1, frameNumber);
- hud->DrawRectangle(5 + x, 3 + y, 3, 3, color[controller.IsPressed(SnesController::Buttons::Up)], true, 1, frameNumber);
- hud->DrawRectangle(5 + x, 9 + y, 3, 3, color[controller.IsPressed(SnesController::Buttons::Down)], true, 1, frameNumber);
- hud->DrawRectangle(2 + x, 6 + y, 3, 3, color[controller.IsPressed(SnesController::Buttons::Left)], true, 1, frameNumber);
- hud->DrawRectangle(8 + x, 6 + y, 3, 3, color[controller.IsPressed(SnesController::Buttons::Right)], true, 1, frameNumber);
- hud->DrawRectangle(5 + x, 6 + y, 3, 3, color[0], true, 1, frameNumber);
-
- hud->DrawRectangle(27 + x, 3 + y, 3, 3, color[controller.IsPressed(SnesController::Buttons::X)], true, 1, frameNumber);
- hud->DrawRectangle(27 + x, 9 + y, 3, 3, color[controller.IsPressed(SnesController::Buttons::B)], true, 1, frameNumber);
- hud->DrawRectangle(30 + x, 6 + y, 3, 3, color[controller.IsPressed(SnesController::Buttons::A)], true, 1, frameNumber);
- hud->DrawRectangle(24 + x, 6 + y, 3, 3, color[controller.IsPressed(SnesController::Buttons::Y)], true, 1, frameNumber);
-
- hud->DrawRectangle(4 + x, 0 + y, 5, 2, color[controller.IsPressed(SnesController::Buttons::L)], true, 1, frameNumber);
- hud->DrawRectangle(26 + x, 0 + y, 5, 2, color[controller.IsPressed(SnesController::Buttons::R)], true, 1, frameNumber);
-
- hud->DrawRectangle(13 + x, 9 + y, 4, 2, color[controller.IsPressed(SnesController::Buttons::Select)], true, 1, frameNumber);
- hud->DrawRectangle(18 + x, 9 + y, 4, 2, color[controller.IsPressed(SnesController::Buttons::Start)], true, 1, frameNumber);
-
- switch(port) {
- case 0:
- //1
- hud->DrawLine(17 + x, 2 + y, 17 + x, 6 + y, color[0], 1, frameNumber);
- hud->DrawLine(16 + x, 6 + y, 18 + x, 6 + y, color[0], 1, frameNumber);
- hud->DrawPixel(16 + x, 3 + y, color[0], 1, frameNumber);
- break;
+ _hud->DrawRectangle(_xOffset + x, _yOffset + y, width, height, color[pressed], true, 1);
+}
+void InputHud::DrawNumber(int number, int x, int y)
+{
+ switch(number) {
case 1:
- //2
- hud->DrawLine(16 + x, 2 + y, 18 + x, 2 + y, color[0], 1, frameNumber);
- hud->DrawPixel(18 + x, 3 + y, color[0], 1, frameNumber);
- hud->DrawLine(16 + x, 4 + y, 18 + x, 4 + y, color[0], 1, frameNumber);
- hud->DrawPixel(16 + x, 5 + y, color[0], 1, frameNumber);
- hud->DrawLine(16 + x, 6 + y, 18 + x, 6 + y, color[0], 1, frameNumber);
+ _hud->DrawLine(x+1 + _xOffset, y + _yOffset, x+1 + _xOffset, 4 + y + _yOffset, color[0], 1);
+ _hud->DrawLine(x + _xOffset, 4 + y + _yOffset, x+2 + _xOffset, 4 + y + _yOffset, color[0], 1);
+ _hud->DrawPixel(x + _xOffset, 1 + y + _yOffset, color[0], 1);
break;
case 2:
- //3
- hud->DrawLine(16 + x, 2 + y, 18 + x, 2 + y, color[0], 1, frameNumber);
- hud->DrawPixel(18 + x, 3 + y, color[0], 1, frameNumber);
- hud->DrawLine(16 + x, 4 + y, 18 + x, 4 + y, color[0], 1, frameNumber);
- hud->DrawPixel(18 + x, 5 + y, color[0], 1, frameNumber);
- hud->DrawLine(16 + x, 6 + y, 18 + x, 6 + y, color[0], 1, frameNumber);
+ _hud->DrawLine(x + _xOffset, y + _yOffset, x+2 + _xOffset, y + _yOffset, color[0], 1);
+ _hud->DrawPixel(x+2 + _xOffset, 1 + y + _yOffset, color[0], 1);
+ _hud->DrawLine(x + _xOffset, 2 + y + _yOffset, x+2 + _xOffset, 2 + y + _yOffset, color[0], 1);
+ _hud->DrawPixel(x + _xOffset, 3 + y + _yOffset, color[0], 1);
+ _hud->DrawLine(x + _xOffset, 4 + y + _yOffset, x+2 + _xOffset, 4 + y + _yOffset, color[0], 1);
break;
case 3:
- //4
- hud->DrawLine(16 + x, 2 + y, 16 + x, 4 + y, color[0], 1, frameNumber);
- hud->DrawLine(18 + x, 2 + y, 18 + x, 6 + y, color[0], 1, frameNumber);
- hud->DrawLine(16 + x, 4 + y, 18 + x, 4 + y, color[0], 1, frameNumber);
+ _hud->DrawLine(x + _xOffset, y + _yOffset, x+2 + _xOffset, y + _yOffset, color[0], 1);
+ _hud->DrawPixel(x+2 + _xOffset, 1 + y + _yOffset, color[0], 1);
+ _hud->DrawLine(x + _xOffset, 2 + y + _yOffset, x+2 + _xOffset, 2 + y + _yOffset, color[0], 1);
+ _hud->DrawPixel(x+2 + _xOffset, 3 + y + _yOffset, color[0], 1);
+ _hud->DrawLine(x + _xOffset, 4 + y + _yOffset, x+2 + _xOffset, 4 + y + _yOffset, color[0], 1);
break;
case 4:
- //5
- hud->DrawLine(16 + x, 2 + y, 18 + x, 2 + y, color[0], 1, frameNumber);
- hud->DrawPixel(16 + x, 3 + y, color[0], 1, frameNumber);
- hud->DrawLine(16 + x, 4 + y, 18 + x, 4 + y, color[0], 1, frameNumber);
- hud->DrawPixel(18 + x, 5 + y, color[0], 1, frameNumber);
- hud->DrawLine(16 + x, 6 + y, 18 + x, 6 + y, color[0], 1, frameNumber);
+ _hud->DrawLine(x + _xOffset, y + _yOffset, x + _xOffset, 2 + y + _yOffset, color[0], 1);
+ _hud->DrawLine(x+2 + _xOffset, y + _yOffset, x+2 + _xOffset, 4 + y + _yOffset, color[0], 1);
+ _hud->DrawLine(x + _xOffset, 2 + y + _yOffset, x+2 + _xOffset, 2 + y + _yOffset, color[0], 1);
break;
- }*/
+
+ case 5:
+ _hud->DrawLine(x + _xOffset, y + _yOffset, x+2 + _xOffset, y + _yOffset, color[0], 1);
+ _hud->DrawPixel(x + _xOffset, 1 + y + _yOffset, color[0], 1);
+ _hud->DrawLine(x + _xOffset, 2 + y + _yOffset, x+2 + _xOffset, 2 + y + _yOffset, color[0], 1);
+ _hud->DrawPixel(x+2 + _xOffset, 3 + y + _yOffset, color[0], 1);
+ _hud->DrawLine(x + _xOffset, 4 + y + _yOffset, x+2 + _xOffset, 4 + y + _yOffset, color[0], 1);
+ break;
+
+ default:
+ break;
+ }
}
-void InputHud::DrawControllers(OverscanDimensions overscan, int frameNumber)
+void InputHud::DrawOutline(int width, int height)
{
- //TODO
- /*
- vector controllerData = _console->GetControlManager()->GetPortStates();
- InputConfig cfg = _console->GetSettings()->GetInputConfig();
-
- int xStart;
- int yStart;
- int xOffset = cfg.DisplayInputHorizontally ? 38 : 0;
- int yOffset = cfg.DisplayInputHorizontally ? 0 : 16;
+ InputConfig& cfg = _emu->GetSettings()->GetInputConfig();
switch(cfg.DisplayInputPosition) {
default:
case InputDisplayPosition::TopLeft:
- xStart = overscan.Left + 3;
- yStart = overscan.Top + 3;
break;
+
case InputDisplayPosition::TopRight:
- xStart = 256 - overscan.Right - 38;
- yStart = overscan.Top + 3;
- xOffset = -xOffset;
+ _xOffset -= width + 1;
break;
+
case InputDisplayPosition::BottomLeft:
- xStart = overscan.Left + 3;
- yStart = 240 - overscan.Bottom - 18;
- yOffset = -yOffset;
+ _yOffset -= height + 1;
break;
+
case InputDisplayPosition::BottomRight:
- xStart = 256 - overscan.Right - 38;
- yStart = 240 - overscan.Bottom - 18;
- xOffset = -xOffset;
- yOffset = -yOffset;
+ _yOffset -= height + 1;
+ _xOffset -= width + 1;
break;
}
- for(int i = 0; i < (int)controllerData.size(); i++) {
- if(controllerData[i].Type == ControllerType::SnesController) {
- if(cfg.DisplayInputPort[i]) {
- DrawController(i, controllerData[i].State, xStart, yStart, frameNumber);
- xStart += xOffset;
- yStart += yOffset;
- }
- } else if(controllerData[i].Type == ControllerType::Multitap) {
- uint64_t rawData = 0;
- for(int j = (int)controllerData[i].State.State.size() - 1; j >= 0; j--) {
- rawData <<= 8;
- rawData |= controllerData[i].State.State[j];
- }
-
- ControlDeviceState controllers[4] = {};
- for(int j = 0; j < 4; j++) {
- controllers[j].State.push_back(rawData & 0xFF);
- controllers[j].State.push_back((rawData >> 8) & 0x0F);
- rawData >>= 12;
- }
-
- if(cfg.DisplayInputPort[i]) {
- DrawController(i, controllers[0], xStart, yStart, frameNumber);
- xStart += xOffset;
- yStart += yOffset;
- }
-
- for(int j = 1; j < 4; j++) {
- if(cfg.DisplayInputPort[j + 1]) {
- DrawController(j + 1, controllers[j], xStart, yStart, frameNumber);
- xStart += xOffset;
- yStart += yOffset;
- }
- }
- } else if(controllerData[i].Type == ControllerType::SuperScope) {
- if(cfg.DisplayInputPort[i]) {
- SuperScope scope(_console, 0, KeyMappingSet());
- scope.SetRawState(controllerData[i].State);
- MousePosition pos = scope.GetCoordinates();
-
- shared_ptr hud = _console->GetDebugHud();
- hud->DrawRectangle(pos.X - 1, pos.Y - 1, 3, 3, 0x00111111, true, 1, frameNumber);
- hud->DrawRectangle(pos.X - 1, pos.Y - 1, 3, 3, 0x80CCCCCC, false, 1, frameNumber);
- }
- } else if(controllerData[i].Type == ControllerType::SnesMouse) {
- if(cfg.DisplayInputPort[i]) {
- SnesMouse mouse(_console, 0);
- mouse.SetRawState(controllerData[i].State);
-
- shared_ptr hud = _console->GetDebugHud();
- hud->DrawRectangle(xStart + 12, yStart, 11, 14, 0x00AAAAAA, true, 1, frameNumber);
- hud->DrawRectangle(xStart + 12, yStart, 11, 14, color[0], false, 1, frameNumber);
- hud->DrawRectangle(xStart + 13, yStart + 1, 4, 5, color[mouse.IsPressed(SnesMouse::Buttons::Left)], true, 1, frameNumber);
- hud->DrawRectangle(xStart + 18, yStart + 1, 4, 5, color[mouse.IsPressed(SnesMouse::Buttons::Right)], true, 1, frameNumber);
-
- xStart += xOffset;
- yStart += yOffset;
- }
- }
- }*/
+ _hud->DrawRectangle(_xOffset, _yOffset, width, height, 0x80CCCCCC, true, 1);
+ _hud->DrawRectangle(_xOffset, _yOffset, width, height, color[0], false, 1);
+
+ _outlineWidth = width;
+ _outlineHeight = height;
+}
+
+void InputHud::DrawController(ControllerType controllerType, int port, ControlDeviceState state)
+{
+ shared_ptr controller = ((BaseControlManager*)_emu->GetControlManager())->CreateControllerDevice(controllerType, port);
+ if(!controller) {
+ return;
+ }
+
+ controller->SetRawState(state);
+ controller->DrawController(*this);
+ EndDrawController();
+}
+
+void InputHud::EndDrawController()
+{
+ if(_outlineHeight > 0 && _outlineWidth > 0) {
+ InputConfig& cfg = _emu->GetSettings()->GetInputConfig();
+
+ switch(cfg.DisplayInputPosition) {
+ default:
+ case InputDisplayPosition::TopLeft:
+ if(cfg.DisplayInputHorizontally) {
+ _xOffset += _outlineWidth + 1;
+ } else {
+ _yOffset += _outlineHeight + 1;
+ }
+ break;
+
+ case InputDisplayPosition::TopRight:
+ if(!cfg.DisplayInputHorizontally) {
+ _xOffset += _outlineWidth + 1;
+ _yOffset += _outlineHeight + 1;
+ }
+ break;
+
+ case InputDisplayPosition::BottomLeft:
+ if(cfg.DisplayInputHorizontally) {
+ _xOffset += _outlineWidth + 1;
+ _yOffset += _outlineHeight + 1;
+ }
+ break;
+
+ case InputDisplayPosition::BottomRight:
+ if(cfg.DisplayInputHorizontally) {
+ _yOffset += _outlineHeight + 1;
+ } else {
+ _xOffset += _outlineWidth + 1;
+ }
+ break;
+ }
+
+ _outlineWidth = 0;
+ _outlineHeight = 0;
+ }
+}
+
+void InputHud::DrawControllers(FrameInfo size, vector controllerData)
+{
+ InputConfig& cfg = _emu->GetSettings()->GetInputConfig();
+
+ switch(cfg.DisplayInputPosition) {
+ default:
+ case InputDisplayPosition::TopLeft:
+ _xOffset = 2;
+ _yOffset = 2;
+ break;
+ case InputDisplayPosition::TopRight:
+ _xOffset = size.Width - 1;
+ _yOffset = 2;
+ break;
+ case InputDisplayPosition::BottomLeft:
+ _xOffset = 2;
+ _yOffset = size.Height - 1;
+ break;
+ case InputDisplayPosition::BottomRight:
+ _xOffset = size.Width - 1;
+ _yOffset = size.Height - 1;
+ break;
+ }
+
+ for(int i = 0; i < (int)controllerData.size(); i++) {
+ if(controllerData[i].Type != ControllerType::None) {
+ DrawController(controllerData[i].Type, i, controllerData[i].State);
+ }
+ }
}
diff --git a/Core/Shared/InputHud.h b/Core/Shared/InputHud.h
index 3b2874e1..7a678958 100644
--- a/Core/Shared/InputHud.h
+++ b/Core/Shared/InputHud.h
@@ -4,16 +4,28 @@
#include "ControlDeviceState.h"
class Emulator;
+class DebugHud;
class InputHud
{
private:
Emulator* _emu;
+ DebugHud* _hud;
- void DrawController(int port, ControlDeviceState state, int x, int y, int frameNumber);
+ int _xOffset = 0;
+ int _yOffset = 0;
+ int _outlineWidth = 0;
+ int _outlineHeight = 0;
+
+ void DrawController(ControllerType type, int port, ControlDeviceState state);
public:
- InputHud(Emulator *emu);
+ InputHud(Emulator *emu, DebugHud* hud);
- void DrawControllers(OverscanDimensions overscan, int frameNumber);
+ void DrawOutline(int width, int height);
+ void DrawButton(int x, int y, int width, int height, bool pressed);
+ void DrawNumber(int number, int x, int y);
+ void EndDrawController();
+
+ void DrawControllers(FrameInfo size, vector controllerData);
};
\ No newline at end of file
diff --git a/Core/Shared/Interfaces/IControlManager.h b/Core/Shared/Interfaces/IControlManager.h
index 9ace94b4..0195a6bb 100644
--- a/Core/Shared/Interfaces/IControlManager.h
+++ b/Core/Shared/Interfaces/IControlManager.h
@@ -4,6 +4,7 @@
#include "IInputProvider.h"
enum class ControllerType;
+struct ControllerData;
class IControlManager
{
@@ -20,6 +21,8 @@ public:
virtual shared_ptr CreateControllerDevice(ControllerType type, uint8_t port) = 0;
virtual bool HasControlDevice(ControllerType type) = 0;
+
+ virtual vector GetPortStates() = 0;
virtual void SetPollCounter(uint32_t pollCounter) = 0;
virtual uint32_t GetPollCounter() = 0;
diff --git a/Core/Shared/Interfaces/IRenderingDevice.h b/Core/Shared/Interfaces/IRenderingDevice.h
index 27b56914..fef37799 100644
--- a/Core/Shared/Interfaces/IRenderingDevice.h
+++ b/Core/Shared/Interfaces/IRenderingDevice.h
@@ -3,11 +3,13 @@
#include "stdafx.h"
#include "Shared/SettingTypes.h"
+struct RenderedFrame;
+
class IRenderingDevice
{
public:
virtual ~IRenderingDevice() {}
- virtual void UpdateFrame(RenderedFrame frame) = 0;
+ virtual void UpdateFrame(RenderedFrame& frame) = 0;
virtual void Render(uint32_t* hudBuffer, uint32_t width, uint32_t height) = 0;
virtual void Reset() = 0;
virtual void SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight) = 0;
diff --git a/Core/Shared/RenderedFrame.h b/Core/Shared/RenderedFrame.h
new file mode 100644
index 00000000..39d7f6c2
--- /dev/null
+++ b/Core/Shared/RenderedFrame.h
@@ -0,0 +1,38 @@
+#pragma once
+#include "stdafx.h"
+#include "Shared/SettingTypes.h"
+#include "Shared/ControlDeviceState.h"
+
+struct RenderedFrame
+{
+ void* FrameBuffer = nullptr;
+ void* Data = nullptr; //Used by HD packs
+ uint32_t Width = 256;
+ uint32_t Height = 240;
+ double Scale = 1.0;
+ uint32_t FrameNumber = 0;
+ vector InputData;
+
+ RenderedFrame()
+ {}
+
+ RenderedFrame(void* buffer, uint32_t width, uint32_t height, double scale = 1.0, uint32_t frameNumber = 0) :
+ FrameBuffer(buffer),
+ Width(width),
+ Height(height),
+ Scale(scale),
+ FrameNumber(frameNumber),
+ Data(nullptr),
+ InputData({})
+ {}
+
+ RenderedFrame(void* buffer, uint32_t width, uint32_t height, double scale, uint32_t frameNumber, vector inputData) :
+ FrameBuffer(buffer),
+ Width(width),
+ Height(height),
+ Scale(scale),
+ FrameNumber(frameNumber),
+ Data(nullptr),
+ InputData(inputData)
+ {}
+};
diff --git a/Core/Shared/RewindManager.cpp b/Core/Shared/RewindManager.cpp
index e3af75c3..b949a7ad 100644
--- a/Core/Shared/RewindManager.cpp
+++ b/Core/Shared/RewindManager.cpp
@@ -6,6 +6,7 @@
#include "Shared/Video/VideoRenderer.h"
#include "Shared/Audio/SoundMixer.h"
#include "Shared/BaseControlDevice.h"
+#include "Shared/RenderedFrame.h"
#include "Shared/Interfaces/IControlManager.h"
RewindManager::RewindManager(Emulator* emu)
@@ -220,7 +221,7 @@ void RewindManager::ProcessEndOfFrame()
}
}
-void RewindManager::ProcessFrame(RenderedFrame frame, bool forRewind)
+void RewindManager::ProcessFrame(RenderedFrame& frame, bool forRewind)
{
if(_rewindState == RewindState::Starting || _rewindState == RewindState::Started) {
if(!forRewind) {
@@ -354,7 +355,7 @@ bool RewindManager::HasHistory()
return _hasHistory;
}
-void RewindManager::SendFrame(RenderedFrame frame, bool forRewind)
+void RewindManager::SendFrame(RenderedFrame& frame, bool forRewind)
{
ProcessFrame(frame, forRewind);
}
diff --git a/Core/Shared/RewindManager.h b/Core/Shared/RewindManager.h
index 463fe079..17cc6ef0 100644
--- a/Core/Shared/RewindManager.h
+++ b/Core/Shared/RewindManager.h
@@ -8,6 +8,7 @@
class Emulator;
class EmuSettings;
+struct RenderedFrame;
enum class RewindState
{
@@ -55,7 +56,7 @@ private:
void Stop();
void ForceStop();
- void ProcessFrame(RenderedFrame frame, bool forRewind);
+ void ProcessFrame(RenderedFrame& frame, bool forRewind);
bool ProcessAudio(int16_t* soundBuffer, uint32_t sampleCount);
void ClearBuffer();
@@ -78,6 +79,6 @@ public:
bool HasHistory();
- void SendFrame(RenderedFrame frame, bool forRewind);
+ void SendFrame(RenderedFrame& frame, bool forRewind);
bool SendAudio(int16_t *soundBuffer, uint32_t sampleCount);
};
\ No newline at end of file
diff --git a/Core/Shared/SaveStateManager.cpp b/Core/Shared/SaveStateManager.cpp
index 9a2d6704..d20294ea 100644
--- a/Core/Shared/SaveStateManager.cpp
+++ b/Core/Shared/SaveStateManager.cpp
@@ -8,6 +8,7 @@
#include "Shared/Emulator.h"
#include "Shared/EmuSettings.h"
#include "Shared/Movies/MovieManager.h"
+#include "Shared/RenderedFrame.h"
#include "EventType.h"
#include "Debugger/Debugger.h"
#include "Netplay/GameClient.h"
diff --git a/Core/Shared/SettingTypes.h b/Core/Shared/SettingTypes.h
index 79413f1b..05445a10 100644
--- a/Core/Shared/SettingTypes.h
+++ b/Core/Shared/SettingTypes.h
@@ -505,30 +505,6 @@ struct OverscanDimensions
uint32_t Bottom = 0;
};
-struct RenderedFrame
-{
- void* FrameBuffer = nullptr;
- void* Data = nullptr; //Used by HD packs
- uint32_t Width = 256;
- uint32_t Height = 240;
- double Scale = 1.0;
- uint32_t FrameNumber = 0;
-
- RenderedFrame()
- {
- }
-
- RenderedFrame(void* buffer, uint32_t width, uint32_t height, double scale = 1.0, uint32_t frameNumber = 0) :
- FrameBuffer(buffer),
- Width(width),
- Height(height),
- Scale(scale),
- FrameNumber(frameNumber),
- Data(nullptr)
- {
- }
-};
-
struct FrameInfo
{
uint32_t Width;
diff --git a/Core/Shared/Video/DrawCommand.h b/Core/Shared/Video/DrawCommand.h
index 6ef5dcc7..442d2fd7 100644
--- a/Core/Shared/Video/DrawCommand.h
+++ b/Core/Shared/Video/DrawCommand.h
@@ -17,6 +17,22 @@ protected:
int _yScale = 1;
virtual void InternalDraw() = 0;
+
+ void InternalDrawPixel(int32_t offset, int color, uint32_t alpha)
+ {
+ if(alpha != 0xFF000000) {
+ if(_argbBuffer[offset] == 0) {
+ //When drawing on an empty background, premultiply channels & preserve alpha value
+ //This is needed for hardware blending between the HUD and the game screen
+ BlendColors((uint8_t*)&_argbBuffer[offset], (uint8_t*)&color, true);
+ } else {
+ BlendColors((uint8_t*)&_argbBuffer[offset], (uint8_t*)&color);
+ }
+ } else {
+ _argbBuffer[offset] = color;
+ }
+ }
+
void DrawPixel(uint32_t x, uint32_t y, int color)
{
uint32_t alpha = (color & 0xFF000000);
@@ -30,11 +46,7 @@ protected:
return;
}
- if(alpha != 0xFF000000) {
- BlendColors((uint8_t*)&_argbBuffer[offset], (uint8_t*)&color);
- } else {
- _argbBuffer[offset] = color;
- }
+ InternalDrawPixel(offset, color, alpha);
} else {
int xPixelCount = _useIntegerScaling ? (int)std::floor(_xScale): (int)((x + 1)*_xScale) - (int)(x*_xScale);
x = (int)(x * (_useIntegerScaling ? (int)std::floor(_xScale) : _xScale));
@@ -48,25 +60,25 @@ protected:
continue;
}
- if(alpha != 0xFF000000) {
- BlendColors((uint8_t*)&_argbBuffer[offset], (uint8_t*)&color);
- } else {
- _argbBuffer[offset] = color;
- }
+ InternalDrawPixel(offset, color, alpha);
}
}
}
}
}
- __forceinline void BlendColors(uint8_t output[4], uint8_t input[4])
+ __forceinline void BlendColors(uint8_t output[4], uint8_t input[4], bool keepAlpha = false)
{
uint8_t alpha = input[3] + 1;
uint8_t invertedAlpha = 256 - input[3];
output[0] = (uint8_t)((alpha * input[0] + invertedAlpha * output[0]) >> 8);
output[1] = (uint8_t)((alpha * input[1] + invertedAlpha * output[1]) >> 8);
output[2] = (uint8_t)((alpha * input[2] + invertedAlpha * output[2]) >> 8);
- output[3] = 0xFF;
+ if(keepAlpha) {
+ output[3] = input[3];
+ } else {
+ output[3] = 0xFF;
+ }
}
public:
diff --git a/Core/Shared/Video/VideoDecoder.cpp b/Core/Shared/Video/VideoDecoder.cpp
index 0540dbfc..1fc6616b 100644
--- a/Core/Shared/Video/VideoDecoder.cpp
+++ b/Core/Shared/Video/VideoDecoder.cpp
@@ -11,6 +11,7 @@
#include "Shared/Video/ScaleFilter.h"
#include "Shared/Video/DebugHud.h"
#include "Shared/InputHud.h"
+#include "Shared/RenderedFrame.h"
#include "Shared/Video/SystemHud.h"
#include "SNES/CartTypes.h"
@@ -97,7 +98,7 @@ void VideoDecoder::DecodeFrame(bool forRewind)
overscan.Bottom *= _scaleFilter->GetScale();
}
- RenderedFrame convertedFrame((void*)outputBuffer, frameSize.Width, frameSize.Height, _frame.Scale, _frame.FrameNumber);
+ RenderedFrame convertedFrame((void*)outputBuffer, frameSize.Width, frameSize.Height, _frame.Scale, _frame.FrameNumber, _frame.InputData);
_emu->GetDebugHud()->Draw(outputBuffer, frameSize, overscan, _frame.FrameNumber, true);
diff --git a/Core/Shared/Video/VideoDecoder.h b/Core/Shared/Video/VideoDecoder.h
index 606e1f71..993e20e0 100644
--- a/Core/Shared/Video/VideoDecoder.h
+++ b/Core/Shared/Video/VideoDecoder.h
@@ -3,6 +3,7 @@
#include "Utilities/SimpleLock.h"
#include "Utilities/AutoResetEvent.h"
#include "Shared/SettingTypes.h"
+#include "Shared/RenderedFrame.h"
class BaseVideoFilter;
class ScaleFilter;
diff --git a/Core/Shared/Video/VideoRenderer.cpp b/Core/Shared/Video/VideoRenderer.cpp
index 7762f95b..e9ed5b09 100644
--- a/Core/Shared/Video/VideoRenderer.cpp
+++ b/Core/Shared/Video/VideoRenderer.cpp
@@ -19,6 +19,7 @@ VideoRenderer::VideoRenderer(Emulator* emu)
_rendererHud.reset(new DebugHud());
_systemHud.reset(new SystemHud(_emu, _rendererHud.get()));
+ _inputHud.reset(new InputHud(emu, _rendererHud.get()));
_hudSurface = new uint32_t[256*240];
_hudSize.Width = 256;
@@ -89,7 +90,14 @@ void VideoRenderer::RenderThread()
_hudSize = size;
}
+ RenderedFrame frame;
+ {
+ _frameLock.AcquireSafe();
+ frame = _lastFrame;
+ }
+
memset(_hudSurface, 0, _hudSize.Width * _hudSize.Height * sizeof(uint32_t));
+ _inputHud->DrawControllers(_hudSize, frame.InputData);
_systemHud->Draw(_hudSize.Width, _hudSize.Height);
_rendererHud->Draw(_hudSurface, _hudSize, {}, 0, false);
_renderer->Render(_hudSurface, _hudSize.Width, _hudSize.Height);
@@ -97,13 +105,18 @@ void VideoRenderer::RenderThread()
}
}
-void VideoRenderer::UpdateFrame(RenderedFrame frame)
+void VideoRenderer::UpdateFrame(RenderedFrame& frame)
{
shared_ptr recorder = _recorder;
if(recorder) {
recorder->AddFrame(frame.FrameBuffer, frame.Width, frame.Height, _emu->GetFps());
}
+ {
+ _frameLock.AcquireSafe();
+ _lastFrame = frame;
+ }
+
if(_renderer) {
_renderer->UpdateFrame(frame);
_waitForRender.Signal();
diff --git a/Core/Shared/Video/VideoRenderer.h b/Core/Shared/Video/VideoRenderer.h
index 619182f9..937e19f9 100644
--- a/Core/Shared/Video/VideoRenderer.h
+++ b/Core/Shared/Video/VideoRenderer.h
@@ -2,6 +2,7 @@
#include "stdafx.h"
#include
#include "Shared/SettingTypes.h"
+#include "Shared/RenderedFrame.h"
#include "Utilities/AutoResetEvent.h"
#include "Utilities/SimpleLock.h"
@@ -9,6 +10,7 @@ class IRenderingDevice;
class Emulator;
class SystemHud;
class DebugHud;
+class InputHud;
class IVideoRecorder;
enum class VideoCodec;
@@ -29,9 +31,13 @@ private:
unique_ptr _rendererHud;
unique_ptr _systemHud;
+ unique_ptr _inputHud;
uint32_t* _hudSurface = nullptr;
FrameInfo _hudSize = {};
+ RenderedFrame _lastFrame;
+ SimpleLock _frameLock;
+
shared_ptr _recorder;
void RenderThread();
@@ -46,7 +52,7 @@ public:
void StartThread();
void StopThread();
- void UpdateFrame(RenderedFrame frame);
+ void UpdateFrame(RenderedFrame& frame);
void RegisterRenderingDevice(IRenderingDevice *renderer);
void UnregisterRenderingDevice(IRenderingDevice *renderer);
diff --git a/NewUI/Debugger/Utilities/ContextMenuAction.cs b/NewUI/Debugger/Utilities/ContextMenuAction.cs
index a56d918c..c44a49d9 100644
--- a/NewUI/Debugger/Utilities/ContextMenuAction.cs
+++ b/NewUI/Debugger/Utilities/ContextMenuAction.cs
@@ -527,6 +527,8 @@ namespace Mesen.Debugger.Utilities
Audio,
[IconFile("DipSwitches")]
Emulation,
+ [IconFile("Controller")]
+ Input,
[IconFile("VideoOptions")]
Video,
[IconFile("NesIcon")]
diff --git a/NewUI/Localization/resources.en.xml b/NewUI/Localization/resources.en.xml
index 637f62f2..195f295e 100644
--- a/NewUI/Localization/resources.en.xml
+++ b/NewUI/Localization/resources.en.xml
@@ -98,24 +98,29 @@
Setup
Setup
Setup
+ Warning: Your current configuration contains conflicting key bindings - some physical buttons on your keyboard or gamepad are mapped to multiple buttons on the NES controller. If this is not intentional, please review and correct your key bindings.
+
+