mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
UI: Added global input options (deadzone, display inputs on screen, etc.)
This commit is contained in:
parent
9f6841eea5
commit
aa6a9699fb
44 changed files with 601 additions and 285 deletions
|
@ -122,6 +122,7 @@
|
|||
<ClInclude Include="Shared\Interfaces\stdafx.h" />
|
||||
<ClInclude Include="Shared\KeyDefinitions.h" />
|
||||
<ClInclude Include="Shared\Movies\stdafx.h" />
|
||||
<ClInclude Include="Shared\RenderedFrame.h" />
|
||||
<ClInclude Include="Shared\RomInfo.h" />
|
||||
<ClInclude Include="Shared\stdafx.h" />
|
||||
<ClInclude Include="NES\NesDefaultVideoFilter.h" />
|
||||
|
|
|
@ -819,6 +819,7 @@
|
|||
<ClInclude Include="NES\Debugger\DummyNesCpu.h" />
|
||||
<ClInclude Include="Gameboy\Debugger\DummyGbCpu.h" />
|
||||
<ClInclude Include="Debugger\DebuggerFeatures.h" />
|
||||
<ClInclude Include="Shared\RenderedFrame.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="SNES\SnesCpu.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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
};
|
|
@ -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<class T> void NesPpu<T>::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<class T> void NesPpu<T>::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<class T> void NesPpu<T>::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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ vector<ControllerData> BaseControlManager::GetPortStates()
|
|||
auto lock = _deviceLock.AcquireSafe();
|
||||
|
||||
vector<ControllerData> states;
|
||||
for(int i = 0; i < 2; i++) {
|
||||
for(int i = 0; i < BaseControlDevice::PortCount; i++) {
|
||||
shared_ptr<BaseControlDevice> device = GetControlDevice(i);
|
||||
if(device) {
|
||||
states.push_back({ device->GetControllerType(), device->GetRawState() });
|
||||
|
|
|
@ -82,7 +82,7 @@ void EmuSettings::SetInputConfig(InputConfig config)
|
|||
}*/
|
||||
}
|
||||
|
||||
InputConfig EmuSettings::GetInputConfig()
|
||||
InputConfig& EmuSettings::GetInputConfig()
|
||||
{
|
||||
return _input;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
AudioConfig GetAudioConfig();
|
||||
|
||||
void SetInputConfig(InputConfig config);
|
||||
InputConfig GetInputConfig();
|
||||
InputConfig& GetInputConfig();
|
||||
|
||||
void SetEmulationConfig(EmulationConfig config);
|
||||
EmulationConfig GetEmulationConfig();
|
||||
|
|
|
@ -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<DebugHud> 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> 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<DebugHud> 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<DebugHud> 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<BaseControlDevice> 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> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> controllerData);
|
||||
};
|
|
@ -4,6 +4,7 @@
|
|||
#include "IInputProvider.h"
|
||||
|
||||
enum class ControllerType;
|
||||
struct ControllerData;
|
||||
|
||||
class IControlManager
|
||||
{
|
||||
|
@ -20,6 +21,8 @@ public:
|
|||
virtual shared_ptr<BaseControlDevice> CreateControllerDevice(ControllerType type, uint8_t port) = 0;
|
||||
|
||||
virtual bool HasControlDevice(ControllerType type) = 0;
|
||||
|
||||
virtual vector<ControllerData> GetPortStates() = 0;
|
||||
|
||||
virtual void SetPollCounter(uint32_t pollCounter) = 0;
|
||||
virtual uint32_t GetPollCounter() = 0;
|
||||
|
|
|
@ -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;
|
||||
|
|
38
Core/Shared/RenderedFrame.h
Normal file
38
Core/Shared/RenderedFrame.h
Normal file
|
@ -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<ControllerData> 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<ControllerData> inputData) :
|
||||
FrameBuffer(buffer),
|
||||
Width(width),
|
||||
Height(height),
|
||||
Scale(scale),
|
||||
FrameNumber(frameNumber),
|
||||
Data(nullptr),
|
||||
InputData(inputData)
|
||||
{}
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "Utilities/SimpleLock.h"
|
||||
#include "Utilities/AutoResetEvent.h"
|
||||
#include "Shared/SettingTypes.h"
|
||||
#include "Shared/RenderedFrame.h"
|
||||
|
||||
class BaseVideoFilter;
|
||||
class ScaleFilter;
|
||||
|
|
|
@ -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<IVideoRecorder> 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();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "stdafx.h"
|
||||
#include <thread>
|
||||
#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<DebugHud> _rendererHud;
|
||||
unique_ptr<SystemHud> _systemHud;
|
||||
unique_ptr<InputHud> _inputHud;
|
||||
uint32_t* _hudSurface = nullptr;
|
||||
FrameInfo _hudSize = {};
|
||||
|
||||
RenderedFrame _lastFrame;
|
||||
SimpleLock _frameLock;
|
||||
|
||||
shared_ptr<IVideoRecorder> _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);
|
||||
|
||||
|
|
|
@ -527,6 +527,8 @@ namespace Mesen.Debugger.Utilities
|
|||
Audio,
|
||||
[IconFile("DipSwitches")]
|
||||
Emulation,
|
||||
[IconFile("Controller")]
|
||||
Input,
|
||||
[IconFile("VideoOptions")]
|
||||
Video,
|
||||
[IconFile("NesIcon")]
|
||||
|
|
|
@ -98,24 +98,29 @@
|
|||
<Control ID="btnSetupMultitap2">Setup</Control>
|
||||
<Control ID="btnSetupMultitap3">Setup</Control>
|
||||
<Control ID="btnSetupMultitap4">Setup</Control>
|
||||
<Control ID="lblKeyBinding">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.</Control>
|
||||
</Form>
|
||||
<Form ID="InputConfigView">
|
||||
<Control ID="tpgGeneral">General</Control>
|
||||
<Control ID="lblSmall">Small</Control>
|
||||
<Control ID="lblLarge">Large</Control>
|
||||
<Control ID="lblDeadzone">Controller axis deadzone size:</Control>
|
||||
|
||||
<Control ID="tpgAdvanced">Advanced</Control>
|
||||
<Control ID="grpDisplayInput">Display Controller Input</Control>
|
||||
<Control ID="lblSensitivity">Mouse speed:</Control>
|
||||
<Control ID="lblLow">Slow</Control>
|
||||
<Control ID="lblHigh">Fast</Control>
|
||||
|
||||
<Control ID="tpgDisplay">Display</Control>
|
||||
<Control ID="lblDisplayInputPorts">Display ports: </Control>
|
||||
<Control ID="chkDisplayPort1">Port 1</Control>
|
||||
<Control ID="chkDisplayPort2">Port 2</Control>
|
||||
<Control ID="chkDisplayPort3">Port 3</Control>
|
||||
<Control ID="chkDisplayPort4">Port 4</Control>
|
||||
<Control ID="chkDisplayPort5">Port 5</Control>
|
||||
<Control ID="lblDisplayPosition">Display Position:</Control>
|
||||
<Control ID="chkDisplayInputHorizontally">Display horizontally</Control>
|
||||
|
||||
<Control ID="lblSmall">Small</Control>
|
||||
<Control ID="lblLarge">Large</Control>
|
||||
<Control ID="lblDeadzone">Controller axis deadzone size:</Control>
|
||||
<Control ID="lblDisplayPosition">Display position:</Control>
|
||||
<Control ID="chkDisplayInputHorizontally">Horizontal display</Control>
|
||||
|
||||
<Control ID="chkHideMousePointerForZapper">Hide mouse pointer when using zapper</Control>
|
||||
|
||||
<Control ID="lblKeyBinding">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.</Control>
|
||||
</Form>
|
||||
<Form ID="OverscanConfig">
|
||||
<Control ID="lblLeft">Left</Control>
|
||||
|
@ -359,6 +364,7 @@
|
|||
|
||||
<Control ID="tabAudio">Audio</Control>
|
||||
<Control ID="tabEmulation">Emulation</Control>
|
||||
<Control ID="tabInput">Input</Control>
|
||||
<Control ID="tabVideo">Video</Control>
|
||||
<Control ID="tabNes">NES</Control>
|
||||
<Control ID="tabSnes">SNES</Control>
|
||||
|
@ -2160,6 +2166,7 @@ x == [$150] || y == [10]
|
|||
|
||||
<Value ID="Audio">Audio</Value>
|
||||
<Value ID="Emulation">Emulation</Value>
|
||||
<Value ID="Input">Input</Value>
|
||||
<Value ID="Video">Video</Value>
|
||||
<Value ID="Nes">NES</Value>
|
||||
<Value ID="Snes">SNES</Value>
|
||||
|
|
|
@ -323,6 +323,9 @@
|
|||
<Compile Update="Debugger\Windows\MemoryToolsWindow.axaml.cs">
|
||||
<DependentUpon>MemoryToolsWindow.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Views\InputConfigView.axaml.cs">
|
||||
<DependentUpon>InputConfigView.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Views\MainMenuView.axaml.cs">
|
||||
<DependentUpon>MainMenuView.axaml</DependentUpon>
|
||||
</Compile>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
|
||||
|
@ -12,8 +13,15 @@ namespace Mesen.Utilities
|
|||
{
|
||||
foreach(PropertyInfo prop in target.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) {
|
||||
if(prop.GetCustomAttribute<ReactiveAttribute>() != null) {
|
||||
if(prop.GetValue(target) is ReactiveObject propValue) {
|
||||
object? value = prop.GetValue(target);
|
||||
if(value is ReactiveObject propValue) {
|
||||
ReactiveHelper.RegisterRecursiveObserver(propValue, handler);
|
||||
} else if(value is IList list) {
|
||||
foreach(object listValue in list) {
|
||||
if(listValue is ReactiveObject) {
|
||||
ReactiveHelper.RegisterRecursiveObserver((ReactiveObject)listValue, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +35,15 @@ namespace Mesen.Utilities
|
|||
{
|
||||
foreach(PropertyInfo prop in target.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) {
|
||||
if(prop.GetCustomAttribute<ReactiveAttribute>() != null) {
|
||||
if(prop.GetValue(target) is ReactiveObject propValue) {
|
||||
object? value = prop.GetValue(target);
|
||||
if(value is ReactiveObject propValue) {
|
||||
ReactiveHelper.UnregisterRecursiveObserver(propValue, handler);
|
||||
} else if(value is IList list) {
|
||||
foreach(object listValue in list) {
|
||||
if(listValue is ReactiveObject) {
|
||||
ReactiveHelper.UnregisterRecursiveObserver((ReactiveObject)listValue, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Mesen.ViewModels
|
|||
public class ConfigViewModel : DisposableViewModel
|
||||
{
|
||||
[Reactive] public AudioConfigViewModel? Audio { get; set; }
|
||||
[Reactive] public InputConfigViewModel? Input { get; set; }
|
||||
[Reactive] public VideoConfigViewModel? Video { get; set; }
|
||||
[Reactive] public PreferencesConfigViewModel? Preferences { get; set; }
|
||||
[Reactive] public EmulationConfigViewModel? Emulation { get; set; }
|
||||
|
@ -38,6 +39,7 @@ namespace Mesen.ViewModels
|
|||
switch(tab) {
|
||||
case ConfigWindowTab.Audio: Audio ??= AddDisposable(new AudioConfigViewModel()); break;
|
||||
case ConfigWindowTab.Emulation: Emulation ??= AddDisposable(new EmulationConfigViewModel()); break;
|
||||
case ConfigWindowTab.Input: Input ??= AddDisposable(new InputConfigViewModel()); break;
|
||||
case ConfigWindowTab.Video: Video ??= AddDisposable(new VideoConfigViewModel()); break;
|
||||
|
||||
case ConfigWindowTab.Nes:
|
||||
|
@ -63,6 +65,7 @@ namespace Mesen.ViewModels
|
|||
}
|
||||
|
||||
ConfigManager.Config.Audio = Audio?.Config.Clone() ?? ConfigManager.Config.Audio;
|
||||
ConfigManager.Config.Input = Input?.Config.Clone() ?? ConfigManager.Config.Input;
|
||||
ConfigManager.Config.Video = Video?.Config.Clone() ?? ConfigManager.Config.Video;
|
||||
ConfigManager.Config.Preferences = Preferences?.Config.Clone() ?? ConfigManager.Config.Preferences;
|
||||
ConfigManager.Config.Emulation = Emulation?.Config.Clone() ?? ConfigManager.Config.Emulation;
|
||||
|
@ -80,12 +83,13 @@ namespace Mesen.ViewModels
|
|||
{
|
||||
Audio = 0,
|
||||
Emulation = 1,
|
||||
Video = 2,
|
||||
|
||||
Nes = 4,
|
||||
Snes = 5,
|
||||
Gameboy = 6,
|
||||
|
||||
Preferences = 8
|
||||
Input = 2,
|
||||
Video = 3,
|
||||
//separator
|
||||
Nes = 5,
|
||||
Snes = 6,
|
||||
Gameboy = 7,
|
||||
//separator
|
||||
Preferences = 9
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace Mesen.ViewModels
|
|||
public class EmulationConfigViewModel : DisposableViewModel
|
||||
{
|
||||
[Reactive] public EmulationConfig Config { get; set; }
|
||||
|
||||
|
||||
public EmulationConfigViewModel()
|
||||
{
|
||||
Config = ConfigManager.Config.Emulation.Clone();
|
||||
|
@ -19,5 +19,5 @@ namespace Mesen.ViewModels
|
|||
|
||||
AddDisposable(ReactiveHelper.RegisterRecursiveObserver(Config, (s, e) => { Config.ApplyConfig(); }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
23
NewUI/ViewModels/InputConfigViewModel.cs
Normal file
23
NewUI/ViewModels/InputConfigViewModel.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using Avalonia.Controls;
|
||||
using Mesen.Config;
|
||||
using Mesen.Utilities;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
|
||||
namespace Mesen.ViewModels
|
||||
{
|
||||
public class InputConfigViewModel : DisposableViewModel
|
||||
{
|
||||
[Reactive] public InputConfig Config { get; set; }
|
||||
|
||||
public InputConfigViewModel()
|
||||
{
|
||||
Config = ConfigManager.Config.Input.Clone();
|
||||
|
||||
if(Design.IsDesignMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddDisposable(ReactiveHelper.RegisterRecursiveObserver(Config, (s, e) => { Config.ApplyConfig(); }));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -374,6 +374,10 @@ namespace Mesen.ViewModels
|
|||
ActionType = ActionType.Emulation,
|
||||
OnClick = () => OpenConfig(wnd, ConfigWindowTab.Emulation)
|
||||
},
|
||||
new MainMenuAction() {
|
||||
ActionType = ActionType.Input,
|
||||
OnClick = () => OpenConfig(wnd, ConfigWindowTab.Input)
|
||||
},
|
||||
new MainMenuAction() {
|
||||
ActionType = ActionType.Video,
|
||||
OnClick = () => OpenConfig(wnd, ConfigWindowTab.Video)
|
||||
|
|
|
@ -22,15 +22,15 @@
|
|||
<StackPanel>
|
||||
<Grid ColumnDefinitions="Auto,Auto,Auto" RowDefinitions="Auto,Auto,Auto,Auto,Auto">
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Text="{l:Translate lblEmulationSpeed}" />
|
||||
<NumericUpDown Grid.Column="1" Grid.Row="0" Value="{CompiledBinding Config.EmulationSpeed}" Maximum="5000" Minimum="0" Width="80" />
|
||||
<NumericUpDown Grid.Column="1" Grid.Row="0" Value="{CompiledBinding Config.EmulationSpeed}" Maximum="5000" Minimum="0" />
|
||||
<TextBlock Grid.Column="2" Grid.Row="0" Text="{l:Translate lblEmuSpeedHint}" />
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Text="{l:Translate lblTurboSpeed}" />
|
||||
<NumericUpDown Grid.Column="1" Grid.Row="1" Value="{CompiledBinding Config.TurboSpeed}" Maximum="5000" Minimum="0" Width="80" />
|
||||
<NumericUpDown Grid.Column="1" Grid.Row="1" Value="{CompiledBinding Config.TurboSpeed}" Maximum="5000" Minimum="0" />
|
||||
<TextBlock Grid.Column="2" Grid.Row="1" Text="{l:Translate lblTurboSpeedHint}" />
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="2" Text="{l:Translate lblRewindSpeed}" />
|
||||
<NumericUpDown Grid.Column="1" Grid.Row="2" Value="{CompiledBinding Config.RewindSpeed}" Maximum="5000" Minimum="0" Width="80" />
|
||||
<NumericUpDown Grid.Column="1" Grid.Row="2" Value="{CompiledBinding Config.RewindSpeed}" Maximum="5000" Minimum="0" />
|
||||
<TextBlock Grid.Column="2" Grid.Row="2" Text="{l:Translate lblRewindSpeedHint}" />
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="4" Text="{l:Translate lblRunAhead}" />
|
||||
|
|
89
NewUI/Views/InputConfigView.axaml
Normal file
89
NewUI/Views/InputConfigView.axaml
Normal file
|
@ -0,0 +1,89 @@
|
|||
<UserControl
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:Mesen.ViewModels"
|
||||
xmlns:c="using:Mesen.Controls"
|
||||
xmlns:cfg="using:Mesen.Config"
|
||||
xmlns:l="using:Mesen.Localization"
|
||||
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
x:DataType="vm:InputConfigViewModel"
|
||||
x:Class="Mesen.Views.InputConfigView"
|
||||
>
|
||||
<Design.DataContext>
|
||||
<vm:InputConfigViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<TabControl TabStripPlacement="Top" SelectedIndex="0">
|
||||
<TabItem Header="{l:Translate tpgGeneral}">
|
||||
<StackPanel>
|
||||
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto,Auto,Auto">
|
||||
<TextBlock Grid.Row="0" Text="{l:Translate lblDeadzone}" VerticalAlignment="Top" Margin="0 15 5 0" />
|
||||
<c:MesenSlider
|
||||
Margin="12 15 10 0"
|
||||
HorizontalAlignment="Left"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Minimum="0"
|
||||
Maximum="4"
|
||||
TickFrequency="1"
|
||||
Width="100"
|
||||
HideValue="True"
|
||||
Value="{CompiledBinding Config.ControllerDeadzoneSize}"
|
||||
/>
|
||||
|
||||
<Grid Grid.Row="1" Grid.Column="1" RowDefinitions="Auto" ColumnDefinitions="Auto,*,Auto" Width="115" HorizontalAlignment="Left" Margin="5 -5 5 0">
|
||||
<TextBlock Text="{l:Translate lblSmall}" />
|
||||
<TextBlock Text="{l:Translate lblLarge}" Grid.Column="2" />
|
||||
</Grid>
|
||||
|
||||
<TextBlock Grid.Row="2" Text="{l:Translate lblSensitivity}" VerticalAlignment="Top" Margin="0 15 5 0" />
|
||||
<c:MesenSlider
|
||||
Margin="12 15 10 0"
|
||||
HorizontalAlignment="Left"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Minimum="0"
|
||||
Maximum="3"
|
||||
TickFrequency="1"
|
||||
Width="100"
|
||||
HideValue="True"
|
||||
Value="{CompiledBinding Config.MouseSensitivity}"
|
||||
/>
|
||||
|
||||
<Grid Grid.Row="3" Grid.Column="1" RowDefinitions="Auto" ColumnDefinitions="Auto,*,Auto" Width="107" HorizontalAlignment="Left" Margin="10 -5 5 0">
|
||||
<TextBlock Text="{l:Translate lblLow}" />
|
||||
<TextBlock Text="{l:Translate lblHigh}" Grid.Column="2" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="{l:Translate tpgDisplay}">
|
||||
<Grid ColumnDefinitions="Auto,Auto" RowDefinitions="Auto,Auto,Auto">
|
||||
<TextBlock Text="{l:Translate lblDisplayInputPorts}" VerticalAlignment="Top" Margin="0 5 0 0" />
|
||||
<Grid Grid.Column="1" ColumnDefinitions="Auto,Auto" RowDefinitions="Auto,Auto,Auto">
|
||||
<Grid.Styles>
|
||||
<Style Selector="CheckBox">
|
||||
<Setter Property="Margin" Value="0 0 5 0" />
|
||||
</Style>
|
||||
</Grid.Styles>
|
||||
|
||||
<CheckBox Content="{l:Translate chkDisplayPort1}" IsChecked="{CompiledBinding Config.DisplayInputPort1}" />
|
||||
<CheckBox Grid.Column="1" Content="{l:Translate chkDisplayPort2}" IsChecked="{CompiledBinding Config.DisplayInputPort2}" />
|
||||
<CheckBox Grid.Row="1" Content="{l:Translate chkDisplayPort3}" IsChecked="{CompiledBinding Config.DisplayInputPort3}" />
|
||||
<CheckBox Grid.Row="1" Grid.Column="1" Content="{l:Translate chkDisplayPort4}" IsChecked="{CompiledBinding Config.DisplayInputPort4}" />
|
||||
<CheckBox Grid.Row="2" Content="{l:Translate chkDisplayPort5}" IsChecked="{CompiledBinding Config.DisplayInputPort5}" />
|
||||
</Grid>
|
||||
|
||||
<TextBlock Grid.Row="1" Text="{l:Translate lblDisplayPosition}" />
|
||||
<c:EnumComboBox Grid.Row="1" Grid.Column="1" SelectedItem="{CompiledBinding Config.DisplayInputPosition}" />
|
||||
|
||||
<CheckBox Grid.Row="2" Grid.ColumnSpan="2" IsChecked="{CompiledBinding Config.DisplayInputHorizontally}" Content="{l:Translate chkDisplayInputHorizontally}" />
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
</TabControl>
|
||||
</UserControl>
|
21
NewUI/Views/InputConfigView.axaml.cs
Normal file
21
NewUI/Views/InputConfigView.axaml.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Mesen.Utilities;
|
||||
using Mesen.Config;
|
||||
|
||||
namespace Mesen.Views
|
||||
{
|
||||
public class InputConfigView : UserControl
|
||||
{
|
||||
public InputConfigView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,6 +26,9 @@
|
|||
<DataTemplate DataType="{x:Type vm:EmulationConfigViewModel}">
|
||||
<v:EmulationConfigView />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type vm:InputConfigViewModel}">
|
||||
<v:InputConfigView />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type vm:VideoConfigViewModel}">
|
||||
<v:VideoConfigView />
|
||||
</DataTemplate>
|
||||
|
@ -71,6 +74,14 @@
|
|||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
</TabItem>
|
||||
<TabItem Content="{CompiledBinding Input}">
|
||||
<TabItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="/Assets/Controller.png" Margin="0 0 10 0" />
|
||||
<TextBlock VerticalAlignment="Center" Text="{l:Translate tabInput}" />
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
</TabItem>
|
||||
<TabItem Content="{CompiledBinding Video}">
|
||||
<TabItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
|
|
|
@ -120,14 +120,6 @@ void Renderer::CleanupDevice()
|
|||
{
|
||||
ResetNesBuffers();
|
||||
ReleaseRenderTargetView();
|
||||
if(_pAlphaEnableBlendingState) {
|
||||
_pAlphaEnableBlendingState->Release();
|
||||
_pAlphaEnableBlendingState = nullptr;
|
||||
}
|
||||
if(_pDepthDisabledStencilState) {
|
||||
_pDepthDisabledStencilState->Release();
|
||||
_pDepthDisabledStencilState = nullptr;
|
||||
}
|
||||
if(_pSwapChain) {
|
||||
_pSwapChain->SetFullscreenState(false, nullptr);
|
||||
_pSwapChain->Release();
|
||||
|
@ -318,61 +310,6 @@ HRESULT Renderer::InitDevice()
|
|||
if(FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc;
|
||||
ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc));
|
||||
depthDisabledStencilDesc.DepthEnable = false;
|
||||
depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||
depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
|
||||
depthDisabledStencilDesc.StencilEnable = true;
|
||||
depthDisabledStencilDesc.StencilReadMask = 0xFF;
|
||||
depthDisabledStencilDesc.StencilWriteMask = 0xFF;
|
||||
depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
|
||||
depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||
depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||
depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
|
||||
depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||
depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||
|
||||
// Create the state using the device.
|
||||
hr = _pd3dDevice->CreateDepthStencilState(&depthDisabledStencilDesc, &_pDepthDisabledStencilState);
|
||||
if(FAILED(hr)) {
|
||||
MessageManager::Log("D3DDevice::CreateDepthStencilState() failed - Error:" + std::to_string(hr));
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Clear the blend state description.
|
||||
D3D11_BLEND_DESC blendStateDescription;
|
||||
ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC));
|
||||
|
||||
// Create an alpha enabled blend state description.
|
||||
blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
|
||||
blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
|
||||
blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||
blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||
blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||
blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||
blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f;
|
||||
|
||||
// Create the blend state using the description.
|
||||
hr = _pd3dDevice->CreateBlendState(&blendStateDescription, &_pAlphaEnableBlendingState);
|
||||
if(FAILED(hr)) {
|
||||
MessageManager::Log("D3DDevice::CreateBlendState() failed - Error:" + std::to_string(hr));
|
||||
return hr;
|
||||
}
|
||||
|
||||
float blendFactor[4];
|
||||
blendFactor[0] = 0.0f;
|
||||
blendFactor[1] = 0.0f;
|
||||
blendFactor[2] = 0.0f;
|
||||
blendFactor[3] = 0.0f;
|
||||
|
||||
_pDeviceContext->OMSetBlendState(_pAlphaEnableBlendingState, blendFactor, 0xffffffff);
|
||||
_pDeviceContext->OMSetDepthStencilState(_pDepthDisabledStencilState, 1);
|
||||
|
||||
hr = CreateEmuTextureBuffers();
|
||||
if(FAILED(hr)) {
|
||||
return hr;
|
||||
|
@ -420,7 +357,7 @@ ID3D11ShaderResourceView* Renderer::GetShaderResourceView(ID3D11Texture2D* textu
|
|||
return shaderResourceView;
|
||||
}
|
||||
|
||||
void Renderer::UpdateFrame(RenderedFrame frame)
|
||||
void Renderer::UpdateFrame(RenderedFrame& frame)
|
||||
{
|
||||
SetScreenSize(frame.Width, frame.Height);
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@ private:
|
|||
ID3D11DeviceContext* _pDeviceContext = nullptr;
|
||||
IDXGISwapChain* _pSwapChain = nullptr;
|
||||
ID3D11RenderTargetView* _pRenderTargetView = nullptr;
|
||||
ID3D11DepthStencilState* _pDepthDisabledStencilState = nullptr;
|
||||
ID3D11BlendState* _pAlphaEnableBlendingState = nullptr;
|
||||
|
||||
atomic<bool> _needFlip = false;
|
||||
uint8_t* _textureBuffer[2] = { nullptr, nullptr };
|
||||
|
@ -86,5 +84,5 @@ public:
|
|||
void Reset();
|
||||
void Render(uint32_t* hudBuffer, uint32_t hudWidth, uint32_t hudHeight);
|
||||
|
||||
void UpdateFrame(RenderedFrame frame);
|
||||
void UpdateFrame(RenderedFrame& frame);
|
||||
};
|
Loading…
Add table
Reference in a new issue