mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
Config UI, 6-button controller, turbo tap
This commit is contained in:
parent
979e055209
commit
66c8e281dd
49 changed files with 1117 additions and 100 deletions
|
@ -19,6 +19,8 @@
|
|||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="PCE\Input\PceAvenuePad6.h" />
|
||||
<ClInclude Include="PCE\Input\PceTurboTap.h" />
|
||||
<ClInclude Include="PCE\Debugger\DummyPceCpu.h" />
|
||||
<ClInclude Include="PCE\Debugger\PceEventManager.h" />
|
||||
<ClInclude Include="PCE\Input\PceController.h" />
|
||||
|
@ -442,6 +444,7 @@
|
|||
<ClCompile Include="NES\Mappers\NsfMapper.cpp" />
|
||||
<ClCompile Include="NES\Mappers\VsSystem\VsControlManager.cpp" />
|
||||
<ClCompile Include="NES\NesNtscFilter.cpp" />
|
||||
<ClCompile Include="PCE\Input\PceTurboTap.cpp" />
|
||||
<ClCompile Include="PCE\Debugger\DummyPceCpu.cpp" />
|
||||
<ClCompile Include="PCE\Debugger\PceDebugger.cpp" />
|
||||
<ClCompile Include="PCE\Debugger\PceDisUtils.cpp" />
|
||||
|
|
|
@ -1760,9 +1760,6 @@
|
|||
<ClInclude Include="PCE\PcePpu.h">
|
||||
<Filter>PCE</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PCE\Input\PceController.h">
|
||||
<Filter>PCE</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PCE\PceTimer.h">
|
||||
<Filter>PCE</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1799,6 +1796,15 @@
|
|||
<ClInclude Include="PCE\PceCdAudioPlayer.h">
|
||||
<Filter>PCE</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PCE\Input\PceController.h">
|
||||
<Filter>PCE\Input</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PCE\Input\PceTurboTap.h">
|
||||
<Filter>PCE\Input</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PCE\Input\PceAvenuePad6.h">
|
||||
<Filter>PCE\Input</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Shared\Video\RotateFilter.cpp">
|
||||
|
@ -1870,6 +1876,9 @@
|
|||
<ClCompile Include="PCE\PceCdAudioPlayer.cpp">
|
||||
<Filter>PCE</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PCE\Input\PceTurboTap.cpp">
|
||||
<Filter>PCE\Input</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="PCE">
|
||||
|
@ -1878,5 +1887,8 @@
|
|||
<Filter Include="PCE\Debugger">
|
||||
<UniqueIdentifier>{71cd23d2-e1b9-4a25-a92a-34b2f64f8086}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="PCE\Input">
|
||||
<UniqueIdentifier>{a2cd79a6-585b-408d-b6af-c273b94092a7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
130
Core/PCE/Input/PceAvenuePad6.h
Normal file
130
Core/PCE/Input/PceAvenuePad6.h
Normal file
|
@ -0,0 +1,130 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "Shared/BaseControlDevice.h"
|
||||
#include "Shared/Emulator.h"
|
||||
#include "Shared/EmuSettings.h"
|
||||
#include "Shared/InputHud.h"
|
||||
#include "Utilities/Serializer.h"
|
||||
|
||||
class PceAvenuePad6 : public BaseControlDevice
|
||||
{
|
||||
private:
|
||||
uint32_t _turboSpeed = 0;
|
||||
bool _disableInput = false;
|
||||
bool _selectDPad = false;
|
||||
bool _selectExtraButtons = false;
|
||||
|
||||
protected:
|
||||
string GetKeyNames() override
|
||||
{
|
||||
return "UDLRSr123456";
|
||||
}
|
||||
|
||||
void InternalSetStateFromInput() override
|
||||
{
|
||||
for(KeyMapping& keyMapping : _keyMappings) {
|
||||
SetPressedState(Buttons::I, keyMapping.A);
|
||||
SetPressedState(Buttons::II, keyMapping.B);
|
||||
SetPressedState(Buttons::III, keyMapping.X);
|
||||
SetPressedState(Buttons::IV, keyMapping.Y);
|
||||
SetPressedState(Buttons::V, keyMapping.L);
|
||||
SetPressedState(Buttons::VI, keyMapping.R);
|
||||
SetPressedState(Buttons::Run, keyMapping.Start);
|
||||
SetPressedState(Buttons::Select, keyMapping.Select);
|
||||
SetPressedState(Buttons::Up, keyMapping.Up);
|
||||
SetPressedState(Buttons::Down, keyMapping.Down);
|
||||
SetPressedState(Buttons::Left, keyMapping.Left);
|
||||
SetPressedState(Buttons::Right, keyMapping.Right);
|
||||
|
||||
uint8_t turboFreq = 1 << (4 - _turboSpeed);
|
||||
bool turboOn = (uint8_t)(_emu->GetFrameCount() % turboFreq) < turboFreq / 2;
|
||||
if(turboOn) {
|
||||
SetPressedState(Buttons::I, keyMapping.TurboA);
|
||||
SetPressedState(Buttons::II, keyMapping.TurboB);
|
||||
SetPressedState(Buttons::III, keyMapping.TurboX);
|
||||
SetPressedState(Buttons::IV, keyMapping.TurboY);
|
||||
SetPressedState(Buttons::V, keyMapping.TurboL);
|
||||
SetPressedState(Buttons::VI, keyMapping.TurboR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshStateBuffer() override
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
enum Buttons { Up = 0, Down, Left, Right, Select, Run, I, II, III, IV, V, VI };
|
||||
|
||||
PceAvenuePad6(Emulator* emu, uint8_t port, KeyMappingSet keyMappings) : BaseControlDevice(emu, ControllerType::PceAvenuePad6, port, keyMappings)
|
||||
{
|
||||
_turboSpeed = keyMappings.TurboSpeed;
|
||||
}
|
||||
|
||||
uint8_t ReadRam(uint16_t addr) override
|
||||
{
|
||||
if(_disableInput) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t result = 0x0F;
|
||||
if(_selectExtraButtons) {
|
||||
if(_selectDPad) {
|
||||
result = 0;
|
||||
} else {
|
||||
result &= ~(IsPressed(PceAvenuePad6::III) ? 0x01 : 0);
|
||||
result &= ~(IsPressed(PceAvenuePad6::IV) ? 0x02 : 0);
|
||||
result &= ~(IsPressed(PceAvenuePad6::V) ? 0x04 : 0);
|
||||
result &= ~(IsPressed(PceAvenuePad6::VI) ? 0x08 : 0);
|
||||
}
|
||||
} else {
|
||||
if(_selectDPad) {
|
||||
result &= ~(IsPressed(PceAvenuePad6::Up) ? 0x01 : 0);
|
||||
result &= ~(IsPressed(PceAvenuePad6::Right) ? 0x02 : 0);
|
||||
result &= ~(IsPressed(PceAvenuePad6::Down) ? 0x04 : 0);
|
||||
result &= ~(IsPressed(PceAvenuePad6::Left) ? 0x08 : 0);
|
||||
} else {
|
||||
result &= ~(IsPressed(PceAvenuePad6::I) ? 0x01 : 0);
|
||||
result &= ~(IsPressed(PceAvenuePad6::II) ? 0x02 : 0);
|
||||
result &= ~(IsPressed(PceAvenuePad6::Select) ? 0x04 : 0);
|
||||
result &= ~(IsPressed(PceAvenuePad6::Run) ? 0x08 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void WriteRam(uint16_t addr, uint8_t value) override
|
||||
{
|
||||
bool disableInput = (value & 0x02) != 0;
|
||||
if(disableInput && !_disableInput) {
|
||||
_selectExtraButtons = !_selectExtraButtons;
|
||||
}
|
||||
_disableInput = disableInput;
|
||||
_selectDPad = (value & 0x01) != 0;
|
||||
}
|
||||
|
||||
void InternalDrawController(InputHud& hud) override
|
||||
{
|
||||
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(22, 8, 3, 3, IsPressed(Buttons::III));
|
||||
hud.DrawButton(26, 8, 3, 3, IsPressed(Buttons::II));
|
||||
hud.DrawButton(30, 8, 3, 3, IsPressed(Buttons::I));
|
||||
|
||||
hud.DrawButton(22, 3, 3, 3, IsPressed(Buttons::IV));
|
||||
hud.DrawButton(26, 3, 3, 3, IsPressed(Buttons::V));
|
||||
hud.DrawButton(30, 3, 3, 3, IsPressed(Buttons::VI));
|
||||
|
||||
hud.DrawButton(12, 9, 4, 2, IsPressed(Buttons::Select));
|
||||
hud.DrawButton(17, 9, 4, 2, IsPressed(Buttons::Run));
|
||||
|
||||
hud.DrawNumber(hud.GetControllerIndex() + 1, 15, 2);
|
||||
}
|
||||
};
|
|
@ -16,15 +16,15 @@ private:
|
|||
protected:
|
||||
string GetKeyNames() override
|
||||
{
|
||||
return "UDLRSsBA";
|
||||
return "UDLRSr12";
|
||||
}
|
||||
|
||||
void InternalSetStateFromInput() override
|
||||
{
|
||||
for(KeyMapping& keyMapping : _keyMappings) {
|
||||
SetPressedState(Buttons::A, keyMapping.A);
|
||||
SetPressedState(Buttons::B, keyMapping.B);
|
||||
SetPressedState(Buttons::Start, keyMapping.Start);
|
||||
SetPressedState(Buttons::I, keyMapping.A);
|
||||
SetPressedState(Buttons::II, keyMapping.B);
|
||||
SetPressedState(Buttons::Run, keyMapping.Start);
|
||||
SetPressedState(Buttons::Select, keyMapping.Select);
|
||||
SetPressedState(Buttons::Up, keyMapping.Up);
|
||||
SetPressedState(Buttons::Down, keyMapping.Down);
|
||||
|
@ -34,8 +34,8 @@ protected:
|
|||
uint8_t turboFreq = 1 << (4 - _turboSpeed);
|
||||
bool turboOn = (uint8_t)(_emu->GetFrameCount() % turboFreq) < turboFreq / 2;
|
||||
if(turboOn) {
|
||||
SetPressedState(Buttons::A, keyMapping.TurboA);
|
||||
SetPressedState(Buttons::B, keyMapping.TurboB);
|
||||
SetPressedState(Buttons::I, keyMapping.TurboA);
|
||||
SetPressedState(Buttons::II, keyMapping.TurboB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,9 +45,9 @@ protected:
|
|||
}
|
||||
|
||||
public:
|
||||
enum Buttons { Up = 0, Down, Left, Right, Start, Select, B, A };
|
||||
enum Buttons { Up = 0, Down, Left, Right, Select, Run, I, II };
|
||||
|
||||
PceController(Emulator* emu, uint8_t port, KeyMappingSet keyMappings) : BaseControlDevice(emu, ControllerType::GameboyController, port, keyMappings)
|
||||
PceController(Emulator* emu, uint8_t port, KeyMappingSet keyMappings) : BaseControlDevice(emu, ControllerType::PceController, port, keyMappings)
|
||||
{
|
||||
_turboSpeed = keyMappings.TurboSpeed;
|
||||
}
|
||||
|
@ -65,10 +65,10 @@ public:
|
|||
result &= ~(IsPressed(PceController::Down) ? 0x04 : 0);
|
||||
result &= ~(IsPressed(PceController::Left) ? 0x08 : 0);
|
||||
} else {
|
||||
result &= ~(IsPressed(PceController::A) ? 0x01 : 0);
|
||||
result &= ~(IsPressed(PceController::B) ? 0x02 : 0);
|
||||
result &= ~(IsPressed(PceController::I) ? 0x01 : 0);
|
||||
result &= ~(IsPressed(PceController::II) ? 0x02 : 0);
|
||||
result &= ~(IsPressed(PceController::Select) ? 0x04 : 0);
|
||||
result &= ~(IsPressed(PceController::Start) ? 0x08 : 0);
|
||||
result &= ~(IsPressed(PceController::Run) ? 0x08 : 0);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -90,12 +90,12 @@ public:
|
|||
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(30, 7, 3, 3, IsPressed(Buttons::I));
|
||||
hud.DrawButton(25, 7, 3, 3, IsPressed(Buttons::II));
|
||||
|
||||
hud.DrawButton(13, 9, 4, 2, IsPressed(Buttons::Select));
|
||||
hud.DrawButton(18, 9, 4, 2, IsPressed(Buttons::Start));
|
||||
hud.DrawButton(18, 9, 4, 2, IsPressed(Buttons::Run));
|
||||
|
||||
hud.DrawNumber(_port + 1, 16, 2);
|
||||
hud.DrawNumber(hud.GetControllerIndex() + 1, 16, 2);
|
||||
}
|
||||
};
|
30
Core/PCE/Input/PceTurboTap.cpp
Normal file
30
Core/PCE/Input/PceTurboTap.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include "stdafx.h"
|
||||
#include "PceTurboTap.h"
|
||||
|
||||
PceTurboTap::PceTurboTap(Emulator* emu, uint8_t port, ControllerConfig controllers[]) : ControllerHub(emu, ControllerType::PceTurboTap, port, controllers)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t PceTurboTap::ReadRam(uint16_t addr)
|
||||
{
|
||||
return _ports[_index] ? ReadPort(_index) : 0x0F;
|
||||
}
|
||||
|
||||
void PceTurboTap::WriteRam(uint16_t addr, uint8_t value)
|
||||
{
|
||||
ControllerHub::WriteRam(addr, value);
|
||||
bool sel = (value & 0x01) != 0;
|
||||
bool prevSel = (_prevValue & 0x01) != 0;
|
||||
bool clr = (value & 0x02) != 0;
|
||||
bool prevClr = (_prevValue & 0x02) != 0;
|
||||
|
||||
if(!clr && !prevSel && sel) {
|
||||
_index = (_index + 1) % 5;
|
||||
}
|
||||
|
||||
if(sel && !prevClr && clr) {
|
||||
_index = 0;
|
||||
}
|
||||
|
||||
_prevValue = value;
|
||||
}
|
19
Core/PCE/Input/PceTurboTap.h
Normal file
19
Core/PCE/Input/PceTurboTap.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "Shared/BaseControlDevice.h"
|
||||
#include "Shared/ControllerHub.h"
|
||||
|
||||
class Emulator;
|
||||
|
||||
class PceTurboTap : public ControllerHub<5>
|
||||
{
|
||||
private:
|
||||
uint8_t _index = 0;
|
||||
uint8_t _prevValue = 0;
|
||||
|
||||
public:
|
||||
PceTurboTap(Emulator* emu, uint8_t port, ControllerConfig controllers[]);
|
||||
|
||||
uint8_t ReadRam(uint16_t addr) override;
|
||||
void WriteRam(uint16_t addr, uint8_t value) override;
|
||||
};
|
|
@ -1,6 +1,8 @@
|
|||
#include "stdafx.h"
|
||||
#include "PCE/PceControlManager.h"
|
||||
#include "PCE/Input/PceController.h"
|
||||
#include "PCE/Input/PceTurboTap.h"
|
||||
#include "PCE/Input/PceAvenuePad6.h"
|
||||
#include "Shared/EmuSettings.h"
|
||||
#include "Shared/BaseControlDevice.h"
|
||||
#include "Shared/Emulator.h"
|
||||
|
@ -16,9 +18,24 @@ PceControlManagerState& PceControlManager::GetState()
|
|||
|
||||
shared_ptr<BaseControlDevice> PceControlManager::CreateControllerDevice(ControllerType type, uint8_t port)
|
||||
{
|
||||
//TODO
|
||||
GameboyConfig cfg = _emu->GetSettings()->GetGameboyConfig();
|
||||
shared_ptr<BaseControlDevice> device(new PceController(_emu, port, cfg.Controller.Keys));
|
||||
PcEngineConfig& cfg = _emu->GetSettings()->GetPcEngineConfig();
|
||||
shared_ptr<BaseControlDevice> device;
|
||||
|
||||
switch(type) {
|
||||
default:
|
||||
case ControllerType::None: break;
|
||||
|
||||
case ControllerType::PceController: device.reset(new PceController(_emu, port, cfg.Port1.Keys)); break;
|
||||
case ControllerType::PceAvenuePad6: device.reset(new PceAvenuePad6(_emu, port, cfg.Port1.Keys)); break;
|
||||
|
||||
case ControllerType::PceTurboTap: {
|
||||
ControllerConfig controllers[5];
|
||||
std::copy(cfg.Port1SubPorts, cfg.Port1SubPorts + 5, controllers);
|
||||
controllers[0].Keys = cfg.Port1.Keys;
|
||||
device.reset(new PceTurboTap(_emu, port, controllers));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
@ -45,7 +62,7 @@ void PceControlManager::WriteInputPort(uint8_t value)
|
|||
|
||||
void PceControlManager::UpdateControlDevices()
|
||||
{
|
||||
GameboyConfig cfg = _emu->GetSettings()->GetGameboyConfig();
|
||||
PcEngineConfig& cfg = _emu->GetSettings()->GetPcEngineConfig();
|
||||
if(_emu->GetSettings()->IsEqual(_prevConfig, cfg) && _controlDevices.size() > 0) {
|
||||
//Do nothing if configuration is unchanged
|
||||
return;
|
||||
|
@ -55,7 +72,7 @@ void PceControlManager::UpdateControlDevices()
|
|||
|
||||
ClearDevices();
|
||||
|
||||
shared_ptr<BaseControlDevice> device(CreateControllerDevice(ControllerType::GameboyController, 0));
|
||||
shared_ptr<BaseControlDevice> device(CreateControllerDevice(cfg.Port1.Type, 0));
|
||||
if(device) {
|
||||
RegisterControlDevice(device);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class PceControlManager : public BaseControlManager
|
|||
{
|
||||
private:
|
||||
PceControlManagerState _state = {};
|
||||
GameboyConfig _prevConfig = {};
|
||||
PcEngineConfig _prevConfig = {};
|
||||
|
||||
public:
|
||||
PceControlManager(Emulator* emu);
|
||||
|
|
|
@ -69,22 +69,20 @@ public:
|
|||
|
||||
memcpy(_prgRom, romData.data(), _prgRomSize);
|
||||
|
||||
//TODO random
|
||||
memset(_workRam, 0, _workRamSize);
|
||||
_emu->GetSettings()->InitializeRam(_workRam, _workRamSize);
|
||||
|
||||
if(_cdrom) {
|
||||
_saveRam = new uint8_t[_saveRamSize];
|
||||
_cdromRam = new uint8_t[_cdromRamSize];
|
||||
_cardRam = new uint8_t[_cardRamSize];
|
||||
//TODO random
|
||||
memset(_saveRam, 0, _saveRamSize);
|
||||
memset(_cdromRam, 0, _cdromRamSize);
|
||||
memset(_cardRam, 0, _cardRamSize);
|
||||
_emu->GetSettings()->InitializeRam(_saveRam, _saveRamSize);
|
||||
_emu->GetSettings()->InitializeRam(_cdromRam, _cdromRamSize);
|
||||
_emu->GetSettings()->InitializeRam(_cardRam, _cardRamSize);
|
||||
_emu->RegisterMemory(MemoryType::PceSaveRam, _saveRam, _saveRamSize);
|
||||
_emu->RegisterMemory(MemoryType::PceCdromRam, _cdromRam, _cdromRamSize);
|
||||
_emu->RegisterMemory(MemoryType::PceCardRam, _cardRam, _cardRamSize);
|
||||
|
||||
//TODO improve this
|
||||
_saveRam[0] = 0x48;
|
||||
_saveRam[1] = 0x55;
|
||||
_saveRam[2] = 0x42;
|
||||
|
|
|
@ -40,7 +40,6 @@ PcePpu::PcePpu(Emulator* emu, PceConsole* console)
|
|||
_state.HorizDisplayWidth = 0x1F;
|
||||
_state.VertDisplayWidth = 239;
|
||||
_state.VceScanlineCount = 262;
|
||||
UpdateFrameTimings();
|
||||
|
||||
_emu->RegisterMemory(MemoryType::PceVideoRam, _vram, 0x8000 * sizeof(uint16_t));
|
||||
_emu->RegisterMemory(MemoryType::PcePaletteRam, _paletteRam, 0x200 * sizeof(uint16_t));
|
||||
|
@ -703,7 +702,6 @@ void PcePpu::DrawScanline()
|
|||
|
||||
if(_state.HClock == 1365) {
|
||||
uint16_t row = _state.Scanline - 14;
|
||||
uint32_t width = PceConstants::GetRowWidth(_state.VceClockDivider);
|
||||
|
||||
if(row == 0) {
|
||||
_currentOutBuffer = _currentOutBuffer == _outBuffer[0] ? _outBuffer[1] : _outBuffer[0];
|
||||
|
@ -732,15 +730,7 @@ void PcePpu::SendFrame()
|
|||
_emu->ProcessEndOfFrame();
|
||||
|
||||
_console->GetControlManager()->UpdateInputState();
|
||||
}
|
||||
|
||||
void PcePpu::UpdateFrameTimings()
|
||||
{
|
||||
_state.DisplayStart = _state.VertDisplayStart + _state.VertSyncWidth;
|
||||
_state.VerticalBlankScanline = _state.DisplayStart + _state.VertDisplayWidth + 1;
|
||||
if(_state.VerticalBlankScanline > 261) {
|
||||
_state.VerticalBlankScanline = 261;
|
||||
}
|
||||
_console->GetControlManager()->UpdateControlDevices();
|
||||
}
|
||||
|
||||
void PcePpu::LoadReadBuffer()
|
||||
|
@ -927,7 +917,6 @@ void PcePpu::WriteVdc(uint16_t addr, uint8_t value)
|
|||
_state.HorizDisplayEnd = value & 0x7F;
|
||||
} else {
|
||||
_state.HorizDisplayWidth = value & 0x7F;
|
||||
UpdateFrameTimings();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -937,12 +926,10 @@ void PcePpu::WriteVdc(uint16_t addr, uint8_t value)
|
|||
} else {
|
||||
_state.VertSyncWidth = value & 0x1F;
|
||||
}
|
||||
UpdateFrameTimings();
|
||||
break;
|
||||
|
||||
case 0x0D:
|
||||
UpdateReg<0x1FF>(_state.VertDisplayWidth, value, msb);
|
||||
UpdateFrameTimings();
|
||||
break;
|
||||
|
||||
case 0x0E:
|
||||
|
@ -1036,7 +1023,6 @@ void PcePpu::WriteVce(uint16_t addr, uint8_t value)
|
|||
case 1: _state.VceClockDivider = 3; break;
|
||||
case 2: case 3: _state.VceClockDivider = 2; break;
|
||||
}
|
||||
UpdateFrameTimings();
|
||||
//LogDebug("[Debug] VCE Clock divider: " + HexUtilities::ToHex(_state.VceClockDivider) + " SL: " + std::to_string(_state.Scanline));
|
||||
break;
|
||||
|
||||
|
|
|
@ -120,13 +120,11 @@ private:
|
|||
void DrawScanline();
|
||||
void SendFrame();
|
||||
|
||||
void UpdateFrameTimings();
|
||||
|
||||
uint16_t DotsToClocks(int dots);
|
||||
void TriggerHdsIrqs();
|
||||
|
||||
__declspec(noinline) void IncrementRcrCounter();
|
||||
void IncScrollY();
|
||||
__declspec(noinline) void IncScrollY();
|
||||
__declspec(noinline) void ProcessEndOfScanline();
|
||||
__declspec(noinline) void ProcessEndOfVisibleFrame();
|
||||
__declspec(noinline) void ProcessSatbTransfer();
|
||||
|
@ -135,14 +133,14 @@ private:
|
|||
__declspec(noinline) void ProcessVdcEvents();
|
||||
__declspec(noinline) void ProcessEvent();
|
||||
|
||||
void ProcessHorizontalSyncStart();
|
||||
__declspec(noinline) void ProcessHorizontalSyncStart();
|
||||
|
||||
__forceinline uint8_t GetTilePixelColor(const uint16_t chrData[2], const uint8_t shift);
|
||||
__forceinline uint8_t GetSpritePixelColor(const uint16_t chrData[4], const uint8_t shift);
|
||||
|
||||
void ProcessSpriteEvaluation();
|
||||
void LoadBackgroundTiles();
|
||||
void LoadSpriteTiles();
|
||||
__declspec(noinline) void ProcessSpriteEvaluation();
|
||||
__declspec(noinline) void LoadBackgroundTiles();
|
||||
__declspec(noinline) void LoadSpriteTiles();
|
||||
|
||||
void WaitForVramAccess();
|
||||
bool IsVramAccessBlocked();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "PCE/PcePsg.h"
|
||||
#include "Shared/Emulator.h"
|
||||
#include "Shared/EmuSettings.h"
|
||||
#include "Shared/MessageManager.h"
|
||||
#include "Shared/Audio/SoundMixer.h"
|
||||
#include "Utilities/Audio/blip_buf.h"
|
||||
|
@ -66,6 +67,7 @@ void PcePsg::Run()
|
|||
{
|
||||
uint64_t clock = _emu->GetMasterClock();
|
||||
uint32_t clocksToRun = clock - _lastClock;
|
||||
PcEngineConfig& cfg = _emu->GetSettings()->GetPcEngineConfig();
|
||||
while(clocksToRun >= 6) {
|
||||
uint32_t minTimer = clocksToRun / 6;
|
||||
for(int i = 0; i < 6; i++) {
|
||||
|
@ -80,8 +82,8 @@ void PcePsg::Run()
|
|||
for(int i = 0; i < 6; i++) {
|
||||
PcePsgChannel& ch = _channels[i];
|
||||
ch.Run(minTimer);
|
||||
leftOutput += ch.GetOutput(true, _state.LeftVolume);
|
||||
rightOutput += ch.GetOutput(false, _state.RightVolume);
|
||||
leftOutput += (int32_t)ch.GetOutput(true, _state.LeftVolume) * (int32_t)cfg.ChannelVol[i] / 100;
|
||||
rightOutput += (int32_t)ch.GetOutput(false, _state.RightVolume) * (int32_t)cfg.ChannelVol[i] / 100;
|
||||
}
|
||||
|
||||
if(_prevLeftOutput != leftOutput) {
|
||||
|
|
|
@ -62,12 +62,7 @@ struct PcePpuState : public BaseState
|
|||
|
||||
uint16_t HClock;
|
||||
uint16_t Scanline;
|
||||
uint16_t DisplayCounter;
|
||||
uint16_t VceScanlineCount;
|
||||
uint16_t DisplayStart;
|
||||
uint16_t VerticalBlankScanline;
|
||||
uint16_t LatchScrollCycle;
|
||||
uint16_t RcrTriggerCycle;
|
||||
uint16_t RcrCounter;
|
||||
|
||||
uint8_t CurrentReg;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "SNES/Input/SnesController.h"
|
||||
#include "SNES/Input/SnesMouse.h"
|
||||
#include "NES/Input/NesController.h"
|
||||
#include "PCE/Input/PceController.h"
|
||||
#include "Utilities/Serializer.h"
|
||||
#include "Utilities/StringUtilities.h"
|
||||
|
||||
|
@ -60,6 +61,10 @@ public:
|
|||
case ControllerType::SnesMouse:
|
||||
_ports[i].reset(new SnesMouse(emu, 0));
|
||||
break;
|
||||
|
||||
case ControllerType::PceController:
|
||||
_ports[i].reset(new PceController(emu, 0, controllers[i].Keys));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,9 +131,13 @@ public:
|
|||
int pos = 0;
|
||||
|
||||
for(int i = 0; i < HubPortCount; i++) {
|
||||
if(_ports[i]) {
|
||||
if(_ports[i] && pos < data.size()) {
|
||||
int length = data[pos++];
|
||||
|
||||
if(pos + length > data.size()) {
|
||||
break;
|
||||
}
|
||||
|
||||
ControlDeviceState portState;
|
||||
portState.State.insert(portState.State.begin(), data.begin() + pos, data.begin() + pos + length);
|
||||
_ports[i]->SetRawState(portState);
|
||||
|
|
|
@ -169,6 +169,16 @@ GameboyConfig& EmuSettings::GetGameboyConfig()
|
|||
return _gameboy;
|
||||
}
|
||||
|
||||
void EmuSettings::SetPcEngineConfig(PcEngineConfig& config)
|
||||
{
|
||||
_pce = config;
|
||||
}
|
||||
|
||||
PcEngineConfig& EmuSettings::GetPcEngineConfig()
|
||||
{
|
||||
return _pce;
|
||||
}
|
||||
|
||||
void EmuSettings::SetPreferences(PreferencesConfig& config)
|
||||
{
|
||||
ProcessString(_saveFolder, &config.SaveFolderOverride);
|
||||
|
@ -397,6 +407,8 @@ void EmuSettings::InitializeRam(void* data, uint32_t length)
|
|||
case ConsoleType::GameboyColor:
|
||||
state = _gameboy.RamPowerOnState;
|
||||
break;
|
||||
|
||||
case ConsoleType::PcEngine: state = _pce.RamPowerOnState; break;
|
||||
}
|
||||
|
||||
switch(state) {
|
||||
|
|
|
@ -22,6 +22,7 @@ private:
|
|||
AudioPlayerConfig _audioPlayer;
|
||||
SnesConfig _snes;
|
||||
NesConfig _nes;
|
||||
PcEngineConfig _pce;
|
||||
|
||||
atomic<uint32_t> _flags;
|
||||
atomic<uint64_t> _debuggerFlags;
|
||||
|
@ -70,6 +71,9 @@ public:
|
|||
void SetGameboyConfig(GameboyConfig& config);
|
||||
GameboyConfig& GetGameboyConfig();
|
||||
|
||||
void SetPcEngineConfig(PcEngineConfig& config);
|
||||
PcEngineConfig& GetPcEngineConfig();
|
||||
|
||||
void SetPreferences(PreferencesConfig& config);
|
||||
PreferencesConfig& GetPreferences();
|
||||
|
||||
|
|
|
@ -206,6 +206,11 @@ enum class ControllerType
|
|||
|
||||
//Game Boy
|
||||
GameboyController,
|
||||
|
||||
//PC Engine
|
||||
PceController,
|
||||
PceTurboTap,
|
||||
PceAvenuePad6,
|
||||
};
|
||||
|
||||
struct KeyMapping
|
||||
|
@ -364,6 +369,16 @@ struct GameboyConfig
|
|||
uint32_t WaveVol = 100;
|
||||
};
|
||||
|
||||
struct PcEngineConfig
|
||||
{
|
||||
ControllerConfig Port1;
|
||||
ControllerConfig Port1SubPorts[5];
|
||||
|
||||
RamState RamPowerOnState = RamState::Random;
|
||||
|
||||
uint32_t ChannelVol[6] = { 100, 100, 100, 100, 100, 100 };
|
||||
};
|
||||
|
||||
struct SnesConfig
|
||||
{
|
||||
ControllerConfig Port1;
|
||||
|
|
|
@ -36,6 +36,11 @@ extern "C" {
|
|||
_emu->GetSettings()->SetGameboyConfig(config);
|
||||
}
|
||||
|
||||
DllExport void __stdcall SetPcEngineConfig(PcEngineConfig config)
|
||||
{
|
||||
_emu->GetSettings()->SetPcEngineConfig(config);
|
||||
}
|
||||
|
||||
DllExport void __stdcall SetNesConfig(NesConfig config)
|
||||
{
|
||||
_emu->GetSettings()->SetNesConfig(config);
|
||||
|
|
BIN
NewUI/Assets/PceIcon.png
Normal file
BIN
NewUI/Assets/PceIcon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 255 B |
|
@ -26,6 +26,7 @@ namespace Mesen.Config
|
|||
[Reactive] public SnesConfig Snes { get; set; } = new();
|
||||
[Reactive] public NesConfig Nes { get; set; } = new();
|
||||
[Reactive] public GameboyConfig Gameboy { get; set; } = new();
|
||||
[Reactive] public PcEngineConfig PcEngine { get; set; } = new();
|
||||
[Reactive] public PreferencesConfig Preferences { get; set; } = new();
|
||||
[Reactive] public AudioPlayerConfig AudioPlayer { get; set; } = new();
|
||||
[Reactive] public DebugConfig Debug { get; set; } = new();
|
||||
|
@ -61,6 +62,7 @@ namespace Mesen.Config
|
|||
Input.ApplyConfig();
|
||||
Emulation.ApplyConfig();
|
||||
Gameboy.ApplyConfig();
|
||||
PcEngine.ApplyConfig();
|
||||
Nes.ApplyConfig();
|
||||
Snes.ApplyConfig();
|
||||
Preferences.ApplyConfig();
|
||||
|
|
|
@ -108,23 +108,15 @@ namespace Mesen.Config
|
|||
|
||||
public virtual void SetDefaultKeys(ControllerType type, KeyPresetType? preset = null)
|
||||
{
|
||||
switch(type) {
|
||||
case ControllerType.NesController:
|
||||
case ControllerType.FamicomController:
|
||||
case ControllerType.FamicomControllerP2:
|
||||
case ControllerType.HoriTrack:
|
||||
case ControllerType.BandaiHyperShot:
|
||||
case ControllerType.SnesController:
|
||||
case ControllerType.GameboyController:
|
||||
switch(preset) {
|
||||
case KeyPresetType.WasdKeys: KeyPresets.ApplyWasdLayout(this, type); break;
|
||||
case KeyPresetType.ArrowKeys: KeyPresets.ApplyArrowLayout(this, type); break;
|
||||
case KeyPresetType.XboxP1: KeyPresets.ApplyXboxLayout(this, 0, type); break;
|
||||
case KeyPresetType.XboxP2: KeyPresets.ApplyXboxLayout(this, 1, type); break;
|
||||
case KeyPresetType.Ps4P1: KeyPresets.ApplyPs4Layout(this, 0, type); break;
|
||||
case KeyPresetType.Ps4P2: KeyPresets.ApplyPs4Layout(this, 1, type); break;
|
||||
}
|
||||
break;
|
||||
if(type.HasPresets()) {
|
||||
switch(preset) {
|
||||
case KeyPresetType.WasdKeys: KeyPresets.ApplyWasdLayout(this, type); break;
|
||||
case KeyPresetType.ArrowKeys: KeyPresets.ApplyArrowLayout(this, type); break;
|
||||
case KeyPresetType.XboxP1: KeyPresets.ApplyXboxLayout(this, 0, type); break;
|
||||
case KeyPresetType.XboxP2: KeyPresets.ApplyXboxLayout(this, 1, type); break;
|
||||
case KeyPresetType.Ps4P1: KeyPresets.ApplyPs4Layout(this, 0, type); break;
|
||||
case KeyPresetType.Ps4P2: KeyPresets.ApplyPs4Layout(this, 1, type); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,6 +293,11 @@ namespace Mesen.Config
|
|||
|
||||
//Game Boy
|
||||
GameboyController,
|
||||
|
||||
//PC Engine
|
||||
PceController,
|
||||
PceTurboTap,
|
||||
PceAvenuePad6
|
||||
}
|
||||
|
||||
public static class ControllerTypeExtensions
|
||||
|
@ -313,6 +310,8 @@ namespace Mesen.Config
|
|||
case ControllerType.FamicomController:
|
||||
case ControllerType.FamicomControllerP2:
|
||||
case ControllerType.GameboyController:
|
||||
case ControllerType.PceController:
|
||||
case ControllerType.PceAvenuePad6:
|
||||
case ControllerType.HoriTrack:
|
||||
case ControllerType.BandaiHyperShot:
|
||||
return true;
|
||||
|
@ -329,6 +328,8 @@ namespace Mesen.Config
|
|||
case ControllerType.FamicomController:
|
||||
case ControllerType.FamicomControllerP2:
|
||||
case ControllerType.GameboyController:
|
||||
case ControllerType.PceController:
|
||||
case ControllerType.PceAvenuePad6:
|
||||
case ControllerType.Pachinko:
|
||||
case ControllerType.HoriTrack:
|
||||
case ControllerType.BandaiHyperShot:
|
||||
|
@ -357,6 +358,8 @@ namespace Mesen.Config
|
|||
case ControllerType.JissenMahjong:
|
||||
case ControllerType.ExcitingBoxing:
|
||||
case ControllerType.GameboyController:
|
||||
case ControllerType.PceController:
|
||||
case ControllerType.PceAvenuePad6:
|
||||
case ControllerType.HoriTrack:
|
||||
case ControllerType.KonamiHyperShot:
|
||||
case ControllerType.BandaiHyperShot:
|
||||
|
|
|
@ -18,6 +18,13 @@ namespace Mesen.Config
|
|||
m.R = InputApi.GetKeyCode("I");
|
||||
m.Select = InputApi.GetKeyCode("O");
|
||||
m.Start = InputApi.GetKeyCode("L");
|
||||
} else if(type == ControllerType.PceAvenuePad6) {
|
||||
m.X = InputApi.GetKeyCode("H");
|
||||
m.Y = InputApi.GetKeyCode("Y");
|
||||
m.L = InputApi.GetKeyCode("U");
|
||||
m.R = InputApi.GetKeyCode("I");
|
||||
m.Select = InputApi.GetKeyCode("N");
|
||||
m.Start = InputApi.GetKeyCode("M");
|
||||
} else {
|
||||
m.TurboA = InputApi.GetKeyCode(";");
|
||||
m.TurboB = InputApi.GetKeyCode("M");
|
||||
|
@ -42,6 +49,15 @@ namespace Mesen.Config
|
|||
m.R = InputApi.GetKeyCode("W");
|
||||
m.Select = InputApi.GetKeyCode("E");
|
||||
m.Start = InputApi.GetKeyCode("D");
|
||||
} else if(type == ControllerType.PceAvenuePad6) {
|
||||
m.Y = InputApi.GetKeyCode("A");
|
||||
m.L = InputApi.GetKeyCode("S");
|
||||
m.R = InputApi.GetKeyCode("D");
|
||||
m.A = InputApi.GetKeyCode("Z");
|
||||
m.B = InputApi.GetKeyCode("X");
|
||||
m.X = InputApi.GetKeyCode("C");
|
||||
m.Select = InputApi.GetKeyCode("Q");
|
||||
m.Start = InputApi.GetKeyCode("W");
|
||||
} else {
|
||||
m.TurboA = InputApi.GetKeyCode("X");
|
||||
m.TurboB = InputApi.GetKeyCode("Z");
|
||||
|
@ -59,7 +75,7 @@ namespace Mesen.Config
|
|||
string prefix = "Pad" + (player + 1).ToString() + " ";
|
||||
m.A = InputApi.GetKeyCode(prefix + "B");
|
||||
m.B = InputApi.GetKeyCode(prefix + "A");
|
||||
if(type == ControllerType.SnesController) {
|
||||
if(type == ControllerType.SnesController || type == ControllerType.PceAvenuePad6) {
|
||||
m.X = InputApi.GetKeyCode(prefix + "Y");
|
||||
m.Y = InputApi.GetKeyCode(prefix + "X");
|
||||
m.L = InputApi.GetKeyCode(prefix + "L1");
|
||||
|
@ -81,7 +97,7 @@ namespace Mesen.Config
|
|||
string prefix = "Joy" + (player + 1).ToString() + " ";
|
||||
m.A = InputApi.GetKeyCode(prefix + "But3");
|
||||
m.B = InputApi.GetKeyCode(prefix + "But2");
|
||||
if(type == ControllerType.SnesController) {
|
||||
if(type == ControllerType.SnesController || type == ControllerType.PceAvenuePad6) {
|
||||
m.X = InputApi.GetKeyCode(prefix + "But4");
|
||||
m.Y = InputApi.GetKeyCode(prefix + "But1");
|
||||
m.L = InputApi.GetKeyCode(prefix + "But5");
|
||||
|
|
113
NewUI/Config/PcEngineConfig.cs
Normal file
113
NewUI/Config/PcEngineConfig.cs
Normal file
|
@ -0,0 +1,113 @@
|
|||
using Mesen.Interop;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Mesen.Config
|
||||
{
|
||||
public class PcEngineConfig : BaseConfig<PcEngineConfig>
|
||||
{
|
||||
[Reactive] public ControllerConfig Port1 { get; set; } = new();
|
||||
|
||||
[Reactive] public ControllerConfig Port1A { get; set; } = new();
|
||||
[Reactive] public ControllerConfig Port1B { get; set; } = new();
|
||||
[Reactive] public ControllerConfig Port1C { get; set; } = new();
|
||||
[Reactive] public ControllerConfig Port1D { get; set; } = new();
|
||||
[Reactive] public ControllerConfig Port1E { get; set; } = new();
|
||||
|
||||
[Reactive] public RamState RamPowerOnState { get; set; } = RamState.Random;
|
||||
|
||||
[Reactive] public UInt32 Channel1Vol { get; set; } = 100;
|
||||
[Reactive] public UInt32 Channel2Vol { get; set; } = 100;
|
||||
[Reactive] public UInt32 Channel3Vol { get; set; } = 100;
|
||||
[Reactive] public UInt32 Channel4Vol { get; set; } = 100;
|
||||
[Reactive] public UInt32 Channel5Vol { get; set; } = 100;
|
||||
[Reactive] public UInt32 Channel6Vol { get; set; } = 100;
|
||||
|
||||
public void ApplyConfig()
|
||||
{
|
||||
ConfigApi.SetPcEngineConfig(new InteropPcEngineConfig() {
|
||||
Port1 = Port1.ToInterop(),
|
||||
Port1A = Port1A.ToInterop(),
|
||||
Port1B = Port1B.ToInterop(),
|
||||
Port1C = Port1C.ToInterop(),
|
||||
Port1D = Port1D.ToInterop(),
|
||||
Port1E = Port1E.ToInterop(),
|
||||
|
||||
RamPowerOnState = RamPowerOnState,
|
||||
|
||||
Channel1Vol = Channel1Vol,
|
||||
Channel2Vol = Channel2Vol,
|
||||
Channel3Vol = Channel3Vol,
|
||||
Channel4Vol = Channel4Vol,
|
||||
Channel5Vol = Channel5Vol,
|
||||
Channel6Vol = Channel6Vol,
|
||||
});
|
||||
}
|
||||
|
||||
internal void InitializeDefaults(DefaultKeyMappingType defaultMappings)
|
||||
{
|
||||
List<KeyMapping> mappings = new List<KeyMapping>();
|
||||
if(defaultMappings.HasFlag(DefaultKeyMappingType.Xbox)) {
|
||||
KeyMapping mapping = new();
|
||||
KeyPresets.ApplyXboxLayout(mapping, 0, ControllerType.PceController);
|
||||
mappings.Add(mapping);
|
||||
}
|
||||
if(defaultMappings.HasFlag(DefaultKeyMappingType.Ps4)) {
|
||||
KeyMapping mapping = new();
|
||||
KeyPresets.ApplyPs4Layout(mapping, 0, ControllerType.PceController);
|
||||
mappings.Add(mapping);
|
||||
}
|
||||
if(defaultMappings.HasFlag(DefaultKeyMappingType.WasdKeys)) {
|
||||
KeyMapping mapping = new();
|
||||
KeyPresets.ApplyWasdLayout(mapping, ControllerType.PceController);
|
||||
mappings.Add(mapping);
|
||||
}
|
||||
if(defaultMappings.HasFlag(DefaultKeyMappingType.ArrowKeys)) {
|
||||
KeyMapping mapping = new();
|
||||
KeyPresets.ApplyArrowLayout(mapping, ControllerType.PceController);
|
||||
mappings.Add(mapping);
|
||||
}
|
||||
|
||||
Port1.Type = ControllerType.PceController;
|
||||
Port1.TurboSpeed = 2;
|
||||
if(mappings.Count > 0) {
|
||||
Port1.Mapping1 = mappings[0];
|
||||
if(mappings.Count > 1) {
|
||||
Port1.Mapping2 = mappings[1];
|
||||
if(mappings.Count > 2) {
|
||||
Port1.Mapping3 = mappings[2];
|
||||
if(mappings.Count > 3) {
|
||||
Port1.Mapping4 = mappings[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct InteropPcEngineConfig
|
||||
{
|
||||
public InteropControllerConfig Port1;
|
||||
|
||||
public InteropControllerConfig Port1A;
|
||||
public InteropControllerConfig Port1B;
|
||||
public InteropControllerConfig Port1C;
|
||||
public InteropControllerConfig Port1D;
|
||||
public InteropControllerConfig Port1E;
|
||||
|
||||
public RamState RamPowerOnState;
|
||||
|
||||
public UInt32 Channel1Vol;
|
||||
public UInt32 Channel2Vol;
|
||||
public UInt32 Channel3Vol;
|
||||
public UInt32 Channel4Vol;
|
||||
public UInt32 Channel5Vol;
|
||||
public UInt32 Channel6Vol;
|
||||
}
|
||||
}
|
23
NewUI/Controls/ControllerButton.axaml
Normal file
23
NewUI/Controls/ControllerButton.axaml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<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:l="using:Mesen.Localization"
|
||||
xmlns:c="using:Mesen.Controls"
|
||||
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="50"
|
||||
x:Name="root"
|
||||
HorizontalAlignment="Stretch"
|
||||
x:Class="Mesen.Controls.ControllerButton"
|
||||
>
|
||||
<DockPanel VerticalAlignment="Stretch" DataContext="{Binding ElementName=root}">
|
||||
<TextBlock DockPanel.Dock="Top" Text="{Binding Label}" FontSize="18" HorizontalAlignment="Center" Margin="0 0 0 0" />
|
||||
<c:KeyBindingButton DockPanel.Dock="Top" KeyBinding="{Binding KeyBinding}" Height="40" />
|
||||
|
||||
<c:KeyBindingButton DockPanel.Dock="Top" KeyBinding="{Binding TurboKeyBinding}" Height="20" IsVisible="{Binding HasTurbo}" />
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" IsVisible="{Binding HasTurbo}" VerticalAlignment="Top">
|
||||
<TextBlock Text="Turbo" FontSize="14" HorizontalAlignment="Center" Margin="0 0 3 0" />
|
||||
<TextBlock Text="{Binding Label}" FontSize="14" HorizontalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</UserControl>
|
50
NewUI/Controls/ControllerButton.axaml.cs
Normal file
50
NewUI/Controls/ControllerButton.axaml.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Media;
|
||||
using System;
|
||||
|
||||
namespace Mesen.Controls
|
||||
{
|
||||
public class ControllerButton : UserControl
|
||||
{
|
||||
public static readonly StyledProperty<UInt32> KeyBindingProperty = AvaloniaProperty.Register<ControllerButton, UInt32>(nameof(KeyBinding), 0, false, Avalonia.Data.BindingMode.TwoWay);
|
||||
public static readonly StyledProperty<UInt32> TurboKeyBindingProperty = AvaloniaProperty.Register<ControllerButton, UInt32>(nameof(TurboKeyBinding), 0, false, Avalonia.Data.BindingMode.TwoWay);
|
||||
public static readonly StyledProperty<string> LabelProperty = AvaloniaProperty.Register<ControllerButton, string>(nameof(Label));
|
||||
public static readonly StyledProperty<bool> HasTurboProperty = AvaloniaProperty.Register<ControllerButton, bool>(nameof(HasTurbo), true);
|
||||
|
||||
public UInt32 KeyBinding
|
||||
{
|
||||
get { return GetValue(KeyBindingProperty); }
|
||||
set { SetValue(KeyBindingProperty, value); }
|
||||
}
|
||||
|
||||
public UInt32 TurboKeyBinding
|
||||
{
|
||||
get { return GetValue(TurboKeyBindingProperty); }
|
||||
set { SetValue(TurboKeyBindingProperty, value); }
|
||||
}
|
||||
|
||||
public string Label
|
||||
{
|
||||
get { return GetValue(LabelProperty); }
|
||||
set { SetValue(LabelProperty, value); }
|
||||
}
|
||||
|
||||
public bool HasTurbo
|
||||
{
|
||||
get { return GetValue(HasTurboProperty); }
|
||||
set { SetValue(HasTurboProperty, value); }
|
||||
}
|
||||
|
||||
public ControllerButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
<c:ButtonWithIcon Icon="Assets/NesIcon.png" Text="NES" MinWidth="90" Click="OnClickNes" />
|
||||
<c:ButtonWithIcon Icon="Assets/SnesIcon.png" Text="SNES" MinWidth="90" Click="OnClickSnes" />
|
||||
<c:ButtonWithIcon Icon="Assets/GameboyIcon.png" Text="Game Boy" MinWidth="90" Click="OnClickGameboy" />
|
||||
<c:ButtonWithIcon Icon="Assets/PceIcon.png" Text="PC Engine" MinWidth="90" Click="OnClickPcEngine" />
|
||||
</StackPanel>
|
||||
</c:OptionSection>
|
||||
</UserControl>
|
|
@ -49,6 +49,11 @@ namespace Mesen.Controls
|
|||
NavigateTo(ConfigWindowTab.Gameboy);
|
||||
}
|
||||
|
||||
private void OnClickPcEngine(object sender, RoutedEventArgs e)
|
||||
{
|
||||
NavigateTo(ConfigWindowTab.PcEngine);
|
||||
}
|
||||
|
||||
private void NavigateTo(ConfigWindowTab console)
|
||||
{
|
||||
if(VisualRoot is ConfigWindow wnd && wnd.DataContext is ConfigViewModel cfg) {
|
||||
|
@ -87,6 +92,17 @@ namespace Mesen.Controls
|
|||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case ConfigWindowTab.PcEngine:
|
||||
if(cfg.PcEngine != null) {
|
||||
cfg.PcEngine.SelectedTab = ConfigType switch {
|
||||
ConfigType.Audio => PceConfigTab.Audio,
|
||||
ConfigType.Emulation => PceConfigTab.Emulation,
|
||||
ConfigType.Input => PceConfigTab.Input,
|
||||
_ or ConfigType.Video => PceConfigTab.Video,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace Mesen.Debugger.StatusViews
|
|||
}
|
||||
StackPreview = sb.ToString();
|
||||
|
||||
Cycle = ppu.Cycle;
|
||||
Cycle = ppu.HClock;
|
||||
Scanline = ppu.Scanline;
|
||||
FrameCount = ppu.FrameCount;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ namespace Mesen.Debugger.StatusViews
|
|||
cpu.PC = RegPC;
|
||||
cpu.PS = RegPS;
|
||||
|
||||
ppu.Cycle = Cycle;
|
||||
ppu.HClock = Cycle;
|
||||
ppu.Scanline = Scanline;
|
||||
|
||||
DebugApi.SetCpuState(cpu, CpuType.Pce);
|
||||
|
|
|
@ -550,6 +550,8 @@ namespace Mesen.Debugger.Utilities
|
|||
Snes,
|
||||
[IconFile("GameboyIcon")]
|
||||
Gameboy,
|
||||
[IconFile("PceIcon")]
|
||||
PcEngine,
|
||||
[IconFile("MediaPause")]
|
||||
Pause,
|
||||
[IconFile("MediaStop")]
|
||||
|
|
|
@ -1139,7 +1139,7 @@ namespace Mesen.Debugger.ViewModels
|
|||
|
||||
List<RegEntry> entries = new List<RegEntry>() {
|
||||
new RegEntry("", "State", null),
|
||||
new RegEntry("", "Cycle (H)", ppu.Cycle, Format.X16),
|
||||
new RegEntry("", "HClock (H)", ppu.HClock, Format.X16),
|
||||
new RegEntry("", "Scanline (V)", ppu.Scanline, Format.X16),
|
||||
new RegEntry("", "Frame Number", ppu.FrameCount),
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace Mesen.Interop
|
|||
[DllImport(DllPath)] public static extern void SetInputConfig(InteropInputConfig config);
|
||||
[DllImport(DllPath)] public static extern void SetEmulationConfig(InteropEmulationConfig config);
|
||||
[DllImport(DllPath)] public static extern void SetGameboyConfig(InteropGameboyConfig config);
|
||||
[DllImport(DllPath)] public static extern void SetPcEngineConfig(InteropPcEngineConfig config);
|
||||
[DllImport(DllPath)] public static extern void SetNesConfig(InteropNesConfig config);
|
||||
[DllImport(DllPath)] public static extern void SetSnesConfig(InteropSnesConfig config);
|
||||
|
||||
|
|
|
@ -1305,14 +1305,10 @@ namespace Mesen.Interop
|
|||
public struct PcePpuState : BaseState
|
||||
{
|
||||
public UInt32 FrameCount;
|
||||
public UInt16 Cycle;
|
||||
|
||||
public UInt16 HClock;
|
||||
public UInt16 Scanline;
|
||||
public UInt16 DisplayCounter;
|
||||
public UInt16 VceScanlineCount;
|
||||
public UInt16 DisplayStart;
|
||||
public UInt16 VerticalBlankScanline;
|
||||
public UInt16 LatchScrollCycle;
|
||||
public UInt16 RcrTriggerCycle;
|
||||
public UInt16 RcrCounter;
|
||||
|
||||
public byte CurrentReg;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<Form ID="frmLogWindow" Title="Log Window">
|
||||
<Control ID="btnClose">Close</Control>
|
||||
</Form>
|
||||
<Form ID="AudioConfigView" Title="Audio Options">
|
||||
<Form ID="AudioConfigView">
|
||||
<Control ID="tpgGeneral">General</Control>
|
||||
|
||||
<Control ID="chkMuteSoundInBackground">Mute sound when in background</Control>
|
||||
|
@ -58,7 +58,7 @@
|
|||
<Control ID="tpgEqualizer">Equalizer</Control>
|
||||
<Control ID="chkEnableEqualizer">Enable Equalizer</Control>
|
||||
</Form>
|
||||
<Form ID="NesInputConfigView" Title="Input Settings">
|
||||
<Form ID="NesInputConfigView">
|
||||
<Control ID="grpControllers">Controllers</Control>
|
||||
<Control ID="grpGeneral">General</Control>
|
||||
<Control ID="lblLightDetectionRadius">Light detection radius for light guns:</Control>
|
||||
|
@ -87,7 +87,7 @@
|
|||
|
||||
<Control ID="lblExpansionDevice">Expansion device:</Control>
|
||||
</Form>
|
||||
<Form ID="SnesInputConfigView" Title="Input Settings">
|
||||
<Form ID="SnesInputConfigView">
|
||||
<Control ID="lblPort1">Port 1:</Control>
|
||||
<Control ID="lblPort2">Port 2:</Control>
|
||||
<Control ID="lblMultitap1A">Port 1:</Control>
|
||||
|
@ -135,7 +135,7 @@
|
|||
<Control ID="lblBottom">Bottom</Control>
|
||||
<Control ID="lblRight">Right</Control>
|
||||
</Form>
|
||||
<Form ID="VideoConfigView" Title="Video Options">
|
||||
<Form ID="VideoConfigView">
|
||||
<Control ID="tpgGeneral">General</Control>
|
||||
<Control ID="chkIntegerFpsMode">Enable integer FPS mode (e.g: run at 60 fps instead of 60.1)</Control>
|
||||
<Control ID="chkVerticalSync">Enable vertical sync</Control>
|
||||
|
@ -188,7 +188,7 @@
|
|||
<Control ID="tpgAdvanced">Advanced</Control>
|
||||
<Control ID="lblScreenRotation">Screen Rotation:</Control>
|
||||
</Form>
|
||||
<Form ID="EmulationConfigView" Title="Emulation Settings">
|
||||
<Form ID="EmulationConfigView">
|
||||
<Control ID="tpgGeneral">General</Control>
|
||||
<Control ID="lblEmuSpeedHint">% (0 = Maximum speed)</Control>
|
||||
<Control ID="lblEmulationSpeed">Emulation Speed:</Control>
|
||||
|
@ -331,7 +331,7 @@
|
|||
<Control ID="lblConsoleType">Console model:</Control>
|
||||
<Control ID="chkAllowInvalidInput">Allow invalid input (e.g Down + Up or Left + Right at the same time)</Control>
|
||||
</Form>
|
||||
<Form ID="GameboyConfigView" Title="Game Boy Config">
|
||||
<Form ID="GameboyConfigView">
|
||||
<Control ID="tpgGeneral">General</Control>
|
||||
<Control ID="lblModel">Model</Control>
|
||||
<Control ID="chkUseSgb2">Use Super Game Boy 2 timings and behavior</Control>
|
||||
|
@ -360,6 +360,34 @@
|
|||
<Control ID="lblPlayer1">Player 1</Control>
|
||||
<Control ID="btnSetup">Setup</Control>
|
||||
</Form>
|
||||
|
||||
<Form ID="PceConfigView">
|
||||
<Control ID="tpgGeneral">General</Control>
|
||||
<Control ID="tpgVideo">Video</Control>
|
||||
|
||||
<Control ID="tpgEmulation">Emulation</Control>
|
||||
<Control ID="lblDeveloperSettings">Recommended settings for developers (homebrew / ROM hacking)</Control>
|
||||
<Control ID="lblRamPowerOnState">Default power on state for RAM: </Control>
|
||||
|
||||
<Control ID="tpgInput">Input</Control>
|
||||
|
||||
<Control ID="tpgAudio">Audio</Control>
|
||||
<Control ID="grpVolume">Volume</Control>
|
||||
</Form>
|
||||
|
||||
<Form ID="PceInputConfigView">
|
||||
<Control ID="grpControllers">Controllers</Control>
|
||||
<Control ID="lblTurboTapConfig">Turbo Tap Configuration</Control>
|
||||
|
||||
<Control ID="btnSetup">Setup</Control>
|
||||
<Control ID="lblController">Controller:</Control>
|
||||
<Control ID="lblPort1A">Port 1:</Control>
|
||||
<Control ID="lblPort1B">Port 2:</Control>
|
||||
<Control ID="lblPort1C">Port 3:</Control>
|
||||
<Control ID="lblPort1D">Port 4:</Control>
|
||||
<Control ID="lblPort1E">Port 5:</Control>
|
||||
</Form>
|
||||
|
||||
<Form ID="ShortcutKeysTabView">
|
||||
<Control ID="lblShortcutWarning">Warning: Your current configuration contains conflicting key bindings. If this is not intentional, please review and correct your key bindings.</Control>
|
||||
<Control ID="colAction">Action</Control>
|
||||
|
@ -381,6 +409,7 @@
|
|||
<Control ID="tabNes">NES</Control>
|
||||
<Control ID="tabSnes">SNES</Control>
|
||||
<Control ID="tabGameboy">Game Boy</Control>
|
||||
<Control ID="tabPcEngine">PC Engine</Control>
|
||||
<Control ID="tabPreferences">Preferences</Control>
|
||||
|
||||
<Control ID="btnOpenMesenFolder">Open Mesen folder</Control>
|
||||
|
@ -390,7 +419,7 @@
|
|||
<Control ID="btnCancel">Cancel</Control>
|
||||
</Form>
|
||||
|
||||
<Form ID="PreferencesConfigView" Title="Preferences">
|
||||
<Form ID="PreferencesConfigView">
|
||||
<Control ID="tpgGeneral">General</Control>
|
||||
<Control ID="lblDisplayLanguage">Display Language:</Control>
|
||||
<Control ID="chkSingleInstance">Only allow one instance of Mesen at a time</Control>
|
||||
|
@ -1355,6 +1384,9 @@
|
|||
<Value ID="BattleBox">Battle Box</Value>
|
||||
|
||||
<Value ID="GameboyController">Gameboy Controller</Value>
|
||||
<Value ID="PceController">2-button Controller</Value>
|
||||
<Value ID="PceAvenuePad6">6-button Controller</Value>
|
||||
<Value ID="PceTurboTap">Turbo Tap</Value>
|
||||
</Enum>
|
||||
<Enum ID="NesJissenMahjongButtons">
|
||||
<Value ID="A">A</Value>
|
||||
|
@ -2232,6 +2264,7 @@
|
|||
<Value ID="Nes">NES</Value>
|
||||
<Value ID="Snes">SNES</Value>
|
||||
<Value ID="Gameboy">Game Boy</Value>
|
||||
<Value ID="PcEngine">PC Engine</Value>
|
||||
|
||||
<Value ID="Resume">Resume</Value>
|
||||
<Value ID="Pause">Pause</Value>
|
||||
|
|
|
@ -109,6 +109,7 @@
|
|||
<None Remove="Assets\NudUpArrow.png" />
|
||||
<None Remove="Assets\NudUpArrowDarkTheme.png" />
|
||||
<None Remove="Assets\Paste.png" />
|
||||
<None Remove="Assets\PceIcon.png" />
|
||||
<None Remove="Assets\Pencil.png" />
|
||||
<None Remove="Assets\PerfTracker.png" />
|
||||
<None Remove="Assets\Pipette.png" />
|
||||
|
@ -194,6 +195,9 @@
|
|||
<Compile Update="Controls\ButtonWithIcon.axaml.cs">
|
||||
<DependentUpon>ButtonWithIcon.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Controls\ControllerButton.axaml.cs">
|
||||
<DependentUpon>ControllerButton.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Debugger\Controls\CodeScrollBar.axaml.cs">
|
||||
<DependentUpon>CodeScrollBar.axaml</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -365,6 +369,18 @@
|
|||
<Compile Update="Debugger\Windows\MemoryToolsWindow.axaml.cs">
|
||||
<DependentUpon>MemoryToolsWindow.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Views\PceAvenuePad6View.axaml.cs">
|
||||
<DependentUpon>PceAvenuePad6View.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Views\PceControllerView.axaml.cs">
|
||||
<DependentUpon>PceControllerView.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Views\PceInputConfigView.axaml.cs">
|
||||
<DependentUpon>PceInputConfigView.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Views\PceConfigView.axaml.cs">
|
||||
<DependentUpon>PceConfigView.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Views\InputConfigView.axaml.cs">
|
||||
<DependentUpon>InputConfigView.axaml</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -559,6 +575,7 @@
|
|||
<AvaloniaResource Include="Assets\NudUpArrow.png" />
|
||||
<AvaloniaResource Include="Assets\NudUpArrowDarkTheme.png" />
|
||||
<AvaloniaResource Include="Assets\Paste.png" />
|
||||
<AvaloniaResource Include="Assets\PceIcon.png" />
|
||||
<AvaloniaResource Include="Assets\Pencil.png" />
|
||||
<AvaloniaResource Include="Assets\PerfTracker.png" />
|
||||
<AvaloniaResource Include="Assets\Pipette.png" />
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Mesen.ViewModels
|
|||
[Reactive] public SnesConfigViewModel? Snes { get; set; }
|
||||
[Reactive] public NesConfigViewModel? Nes { get; set; }
|
||||
[Reactive] public GameboyConfigViewModel? Gameboy { get; set; }
|
||||
[Reactive] public PceConfigViewModel? PcEngine { get; set; }
|
||||
|
||||
[Reactive] public ConfigWindowTab SelectedIndex { get; set; }
|
||||
|
||||
|
@ -50,6 +51,7 @@ namespace Mesen.ViewModels
|
|||
|
||||
case ConfigWindowTab.Snes: Snes ??= AddDisposable(new SnesConfigViewModel()); break;
|
||||
case ConfigWindowTab.Gameboy: Gameboy ??= AddDisposable(new GameboyConfigViewModel()); break;
|
||||
case ConfigWindowTab.PcEngine: PcEngine ??= AddDisposable(new PceConfigViewModel()); break;
|
||||
|
||||
case ConfigWindowTab.Preferences: Preferences ??= AddDisposable(new PreferencesConfigViewModel()); break;
|
||||
}
|
||||
|
@ -72,6 +74,7 @@ namespace Mesen.ViewModels
|
|||
ConfigManager.Config.Nes = Nes?.Config.Clone() ?? ConfigManager.Config.Nes;
|
||||
ConfigManager.Config.Snes = Snes?.Config.Clone() ?? ConfigManager.Config.Snes;
|
||||
ConfigManager.Config.Gameboy = Gameboy?.Config.Clone() ?? ConfigManager.Config.Gameboy;
|
||||
ConfigManager.Config.PcEngine = PcEngine?.Config.Clone() ?? ConfigManager.Config.PcEngine;
|
||||
ConfigManager.Config.ApplyConfig();
|
||||
ConfigManager.Config.Save();
|
||||
|
||||
|
@ -89,7 +92,8 @@ namespace Mesen.ViewModels
|
|||
Nes = 5,
|
||||
Snes = 6,
|
||||
Gameboy = 7,
|
||||
PcEngine = 8,
|
||||
//separator
|
||||
Preferences = 9
|
||||
Preferences = 10
|
||||
}
|
||||
}
|
||||
|
|
|
@ -407,6 +407,10 @@ namespace Mesen.ViewModels
|
|||
ActionType = ActionType.Gameboy,
|
||||
OnClick = () => OpenConfig(wnd, ConfigWindowTab.Gameboy)
|
||||
},
|
||||
new MainMenuAction() {
|
||||
ActionType = ActionType.PcEngine,
|
||||
OnClick = () => OpenConfig(wnd, ConfigWindowTab.PcEngine)
|
||||
},
|
||||
|
||||
new ContextMenuSeparator(),
|
||||
|
||||
|
|
43
NewUI/ViewModels/PceConfigViewModel.cs
Normal file
43
NewUI/ViewModels/PceConfigViewModel.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using Avalonia.Controls;
|
||||
using Mesen.Config;
|
||||
using Mesen.Utilities;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
|
||||
namespace Mesen.ViewModels
|
||||
{
|
||||
public class PceConfigViewModel : DisposableViewModel
|
||||
{
|
||||
[Reactive] public PcEngineConfig Config { get; set; }
|
||||
[Reactive] public PceConfigTab SelectedTab { get; set; } = 0;
|
||||
|
||||
public PceInputConfigViewModel Input { get; private set; }
|
||||
|
||||
public PceConfigViewModel()
|
||||
{
|
||||
Config = ConfigManager.Config.PcEngine.Clone();
|
||||
Input = new PceInputConfigViewModel(Config);
|
||||
|
||||
if(Design.IsDesignMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddDisposable(Input);
|
||||
AddDisposable(ReactiveHelper.RegisterRecursiveObserver(Config, (s, e) => { Config.ApplyConfig(); }));
|
||||
}
|
||||
}
|
||||
|
||||
public enum PceConfigTab
|
||||
{
|
||||
General,
|
||||
Audio,
|
||||
Emulation,
|
||||
Input,
|
||||
Video
|
||||
}
|
||||
}
|
41
NewUI/ViewModels/PceInputConfigViewModel.cs
Normal file
41
NewUI/ViewModels/PceInputConfigViewModel.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using Avalonia.Threading;
|
||||
using Mesen.Config;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using System;
|
||||
using System.Reactive.Linq;
|
||||
|
||||
namespace Mesen.ViewModels
|
||||
{
|
||||
public class PceInputConfigViewModel : DisposableViewModel
|
||||
{
|
||||
[Reactive] public PcEngineConfig Config { get; set; }
|
||||
[Reactive] public bool HasTurboTap { get; private set; }
|
||||
|
||||
public Enum[] AvailableControllerTypesP1 => new Enum[] {
|
||||
ControllerType.None,
|
||||
ControllerType.PceController,
|
||||
ControllerType.PceAvenuePad6,
|
||||
ControllerType.PceTurboTap,
|
||||
};
|
||||
|
||||
public Enum[] AvailableControllerTypesTurboTap => new Enum[] {
|
||||
ControllerType.None,
|
||||
ControllerType.PceController,
|
||||
};
|
||||
|
||||
[Obsolete("For designer only")]
|
||||
public PceInputConfigViewModel() : this(new PcEngineConfig()) { }
|
||||
|
||||
public PceInputConfigViewModel(PcEngineConfig config)
|
||||
{
|
||||
Config = config;
|
||||
|
||||
AddDisposable(this.WhenAnyValue(x => x.Config.Port1.Type).Subscribe(t => {
|
||||
Dispatcher.UIThread.Post(() => {
|
||||
HasTurboTap = Config.Port1.Type == ControllerType.PceTurboTap;
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,6 +25,8 @@ namespace Mesen.Views
|
|||
ControllerType.BandaiHyperShot => new NesControllerView(),
|
||||
ControllerType.HoriTrack => new NesControllerView(),
|
||||
ControllerType.GameboyController => new NesControllerView(),
|
||||
ControllerType.PceController => new PceControllerView(),
|
||||
ControllerType.PceAvenuePad6 => new PceAvenuePad6View(),
|
||||
_ => new DefaultControllerView()
|
||||
};
|
||||
}
|
||||
|
|
|
@ -41,10 +41,19 @@
|
|||
<StackPanel>
|
||||
<c:GroupBox Header="Volume" HorizontalAlignment="Left">
|
||||
<StackPanel Orientation="Horizontal" Height="150">
|
||||
<c:MesenSlider Text="Square 1" Minimum="0" Maximum="100" Orientation="Vertical" Value="{CompiledBinding Config.Square1Vol}" />
|
||||
<c:MesenSlider Text="Square 2" Minimum="0" Maximum="100" Orientation="Vertical" Value="{CompiledBinding Config.Square2Vol}" />
|
||||
<c:MesenSlider Text="Wave" Minimum="0" Maximum="100" Orientation="Vertical" Value="{CompiledBinding Config.WaveVol}" />
|
||||
<c:MesenSlider Text="Noise" Minimum="0" Maximum="100" Orientation="Vertical" Value="{CompiledBinding Config.NoiseVol}" />
|
||||
<StackPanel.Styles>
|
||||
<Style Selector="c|MesenSlider">
|
||||
<Setter Property="Minimum" Value="0" />
|
||||
<Setter Property="Maximum" Value="100" />
|
||||
<Setter Property="Orientation" Value="Vertical" />
|
||||
<Setter Property="Margin" Value="5 0" />
|
||||
</Style>
|
||||
</StackPanel.Styles>
|
||||
|
||||
<c:MesenSlider Text="Square 1" Value="{CompiledBinding Config.Square1Vol}" />
|
||||
<c:MesenSlider Text="Square 2" Value="{CompiledBinding Config.Square2Vol}" />
|
||||
<c:MesenSlider Text="Wave" Value="{CompiledBinding Config.WaveVol}" />
|
||||
<c:MesenSlider Text="Noise" Value="{CompiledBinding Config.NoiseVol}" />
|
||||
</StackPanel>
|
||||
</c:GroupBox>
|
||||
</StackPanel>
|
||||
|
|
86
NewUI/Views/PceAvenuePad6View.axaml
Normal file
86
NewUI/Views/PceAvenuePad6View.axaml
Normal file
|
@ -0,0 +1,86 @@
|
|||
<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:l="using:Mesen.Localization"
|
||||
xmlns:c="using:Mesen.Controls"
|
||||
xmlns:cfg="using:Mesen.Config"
|
||||
mc:Ignorable="d" d:DesignWidth="610" d:DesignHeight="230"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
x:Name="root"
|
||||
x:DataType="vm:KeyMappingViewModel"
|
||||
x:Class="Mesen.Views.PceAvenuePad6View"
|
||||
>
|
||||
<Design.DataContext>
|
||||
<vm:KeyMappingViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<Border BorderBrush="LightGray" BorderThickness="2" Padding="3" Width="610" Height="230" HorizontalAlignment="Left" VerticalAlignment="Top">
|
||||
<Canvas>
|
||||
<Panel Canvas.Top="10" >
|
||||
<Ellipse Width="200" Height="200" Stroke="LightGray" StrokeThickness="2" />
|
||||
<Grid ColumnDefinitions="*,*" RowDefinitions="*,*,*" Width="200" Height="200">
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Up}" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Width="80" Height="40" HorizontalAlignment="Center" />
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Left}" Grid.Row="1" Grid.Column="0" Width="80" Height="40" HorizontalAlignment="Center" />
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Right}" Grid.Row="1" Grid.Column="1" Width="80" Height="40" HorizontalAlignment="Center" />
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Down}" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Width="80" Height="40" HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</Panel>
|
||||
|
||||
<Panel Canvas.Top="0" Canvas.Right="5" Width="205" Height="220">
|
||||
<Rectangle Fill="#F2F2F2" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<c:ControllerButton
|
||||
Margin="5 0 0 0"
|
||||
Label="IV"
|
||||
KeyBinding="{CompiledBinding Mapping.Y}"
|
||||
TurboKeyBinding="{CompiledBinding Mapping.TurboY}"
|
||||
/>
|
||||
<c:ControllerButton
|
||||
Margin="5 0 0 0"
|
||||
Label="V"
|
||||
KeyBinding="{CompiledBinding Mapping.L}"
|
||||
TurboKeyBinding="{CompiledBinding Mapping.TurboL}"
|
||||
/>
|
||||
<c:ControllerButton
|
||||
Margin="5 0 0 0"
|
||||
Label="VI"
|
||||
KeyBinding="{CompiledBinding Mapping.R}"
|
||||
TurboKeyBinding="{CompiledBinding Mapping.TurboR}"
|
||||
/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0 110 0 0">
|
||||
<c:ControllerButton
|
||||
Margin="5 0 0 0"
|
||||
Label="III"
|
||||
KeyBinding="{CompiledBinding Mapping.X}"
|
||||
TurboKeyBinding="{CompiledBinding Mapping.TurboX}"
|
||||
/>
|
||||
<c:ControllerButton
|
||||
Margin="5 0 0 0"
|
||||
Label="II"
|
||||
KeyBinding="{CompiledBinding Mapping.B}"
|
||||
TurboKeyBinding="{CompiledBinding Mapping.TurboB}"
|
||||
/>
|
||||
<c:ControllerButton
|
||||
Margin="5 0 0 0"
|
||||
Label="I"
|
||||
KeyBinding="{CompiledBinding Mapping.A}"
|
||||
TurboKeyBinding="{CompiledBinding Mapping.TurboA}"
|
||||
/>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
|
||||
<Grid ColumnDefinitions="*,Auto,Auto,*" RowDefinitions="Auto,Auto" Width="580" Canvas.Bottom="30">
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Select}" Grid.Column="1" Width="80" />
|
||||
<TextBlock Grid.Column="1" Grid.Row="1" Text="Select" FontSize="14" HorizontalAlignment="Center" />
|
||||
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Start}" Grid.Column="2" Width="80" />
|
||||
<TextBlock Grid.Column="2" Grid.Row="1" Text="Run" FontSize="14" HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</Canvas>
|
||||
</Border>
|
||||
</UserControl>
|
18
NewUI/Views/PceAvenuePad6View.axaml.cs
Normal file
18
NewUI/Views/PceAvenuePad6View.axaml.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Mesen.Views
|
||||
{
|
||||
public class PceAvenuePad6View : UserControl
|
||||
{
|
||||
public PceAvenuePad6View()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
76
NewUI/Views/PceConfigView.axaml
Normal file
76
NewUI/Views/PceConfigView.axaml
Normal file
|
@ -0,0 +1,76 @@
|
|||
<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:dc="using:Mesen.Debugger.Controls"
|
||||
xmlns:cfg="using:Mesen.Config"
|
||||
xmlns:v="using:Mesen.Views"
|
||||
xmlns:l="using:Mesen.Localization"
|
||||
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="350"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
x:DataType="vm:PceConfigViewModel"
|
||||
x:Class="Mesen.Views.PceConfigView"
|
||||
>
|
||||
<Design.DataContext>
|
||||
<vm:PceConfigViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<UserControl.Styles>
|
||||
<Style Selector="dc|PaletteSelector">
|
||||
<Setter Property="SelectionMode" Value="None" />
|
||||
<Setter Property="ColumnCount" Value="4" />
|
||||
<Setter Property="Width" Value="80" />
|
||||
<Setter Property="Height" Value="20" />
|
||||
</Style>
|
||||
</UserControl.Styles>
|
||||
|
||||
<TabControl TabStripPlacement="Top" SelectedIndex="{CompiledBinding SelectedTab}">
|
||||
<TabItem Header="{l:Translate tpgGeneral}">
|
||||
<StackPanel>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="{l:Translate tpgAudio}">
|
||||
<StackPanel>
|
||||
<c:GroupBox Header="Volume" HorizontalAlignment="Left">
|
||||
<StackPanel Orientation="Horizontal" Height="150">
|
||||
<StackPanel.Styles>
|
||||
<Style Selector="c|MesenSlider">
|
||||
<Setter Property="Minimum" Value="0" />
|
||||
<Setter Property="Maximum" Value="100" />
|
||||
<Setter Property="Orientation" Value="Vertical" />
|
||||
<Setter Property="Margin" Value="5 0" />
|
||||
</Style>
|
||||
</StackPanel.Styles>
|
||||
|
||||
<c:MesenSlider Text="Channel 1" Value="{CompiledBinding Config.Channel1Vol}" />
|
||||
<c:MesenSlider Text="Channel 2" Value="{CompiledBinding Config.Channel2Vol}" />
|
||||
<c:MesenSlider Text="Channel 3" Value="{CompiledBinding Config.Channel3Vol}" />
|
||||
<c:MesenSlider Text="Channel 4" Value="{CompiledBinding Config.Channel4Vol}" />
|
||||
<c:MesenSlider Text="Channel 5" Value="{CompiledBinding Config.Channel5Vol}" />
|
||||
<c:MesenSlider Text="Channel 6" Value="{CompiledBinding Config.Channel6Vol}" />
|
||||
</StackPanel>
|
||||
</c:GroupBox>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="{l:Translate tpgEmulation}">
|
||||
<c:OptionSection Header="{l:Translate lblDeveloperSettings}" Margin="0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{l:Translate lblRamPowerOnState}" />
|
||||
<c:EnumComboBox SelectedItem="{CompiledBinding Config.RamPowerOnState}" Width="200" />
|
||||
</StackPanel>
|
||||
</c:OptionSection>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="{l:Translate tpgInput}">
|
||||
<v:PceInputConfigView DataContext="{CompiledBinding Input}" />
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="{l:Translate tpgVideo}">
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</UserControl>
|
30
NewUI/Views/PceConfigView.axaml.cs
Normal file
30
NewUI/Views/PceConfigView.axaml.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Mesen.Utilities;
|
||||
using Mesen.Config;
|
||||
using Mesen.Debugger.Controls;
|
||||
using Mesen.ViewModels;
|
||||
using Mesen.Windows;
|
||||
using System;
|
||||
using Avalonia.Media;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace Mesen.Views
|
||||
{
|
||||
public class PceConfigView : UserControl
|
||||
{
|
||||
public PceConfigView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
60
NewUI/Views/PceControllerView.axaml
Normal file
60
NewUI/Views/PceControllerView.axaml
Normal file
|
@ -0,0 +1,60 @@
|
|||
<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:l="using:Mesen.Localization"
|
||||
xmlns:c="using:Mesen.Controls"
|
||||
xmlns:cfg="using:Mesen.Config"
|
||||
mc:Ignorable="d" d:DesignWidth="610" d:DesignHeight="230"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
x:Name="root"
|
||||
x:DataType="vm:KeyMappingViewModel"
|
||||
x:Class="Mesen.Views.PceControllerView"
|
||||
>
|
||||
<Design.DataContext>
|
||||
<vm:KeyMappingViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<Border BorderBrush="LightGray" BorderThickness="2" Padding="3" Width="610" Height="230" HorizontalAlignment="Left" VerticalAlignment="Top">
|
||||
<Canvas>
|
||||
<Panel Canvas.Top="10" >
|
||||
<Ellipse Width="200" Height="200" Stroke="LightGray" StrokeThickness="2" />
|
||||
<Grid ColumnDefinitions="*,*" RowDefinitions="*,*,*" Width="200" Height="200">
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Up}" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Width="80" Height="40" HorizontalAlignment="Center" />
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Left}" Grid.Row="1" Grid.Column="0" Width="80" Height="40" HorizontalAlignment="Center" />
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Right}" Grid.Row="1" Grid.Column="1" Width="80" Height="40" HorizontalAlignment="Center" />
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Down}" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Width="80" Height="40" HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</Panel>
|
||||
|
||||
<Panel Canvas.Top="80" Canvas.Right="5" Width="200" Height="110">
|
||||
<Rectangle Fill="#F2F2F2" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<c:ControllerButton
|
||||
Margin="10 0 0 0"
|
||||
Label="II"
|
||||
KeyBinding="{CompiledBinding Mapping.B}"
|
||||
TurboKeyBinding="{CompiledBinding Mapping.TurboB}"
|
||||
/>
|
||||
<c:ControllerButton
|
||||
Margin="55 0 0 0"
|
||||
Label="I"
|
||||
KeyBinding="{CompiledBinding Mapping.A}"
|
||||
TurboKeyBinding="{CompiledBinding Mapping.TurboA}"
|
||||
/>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
|
||||
<Grid ColumnDefinitions="*,Auto,Auto,*" RowDefinitions="Auto,Auto" Width="580" Canvas.Bottom="30">
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Select}" Grid.Column="1" Width="80" />
|
||||
<TextBlock Grid.Column="1" Grid.Row="1" Text="Select" FontSize="14" HorizontalAlignment="Center" />
|
||||
|
||||
<c:KeyBindingButton KeyBinding="{CompiledBinding Mapping.Start}" Grid.Column="2" Width="80" />
|
||||
<TextBlock Grid.Column="2" Grid.Row="1" Text="Run" FontSize="14" HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</Canvas>
|
||||
</Border>
|
||||
</UserControl>
|
18
NewUI/Views/PceControllerView.axaml.cs
Normal file
18
NewUI/Views/PceControllerView.axaml.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Mesen.Views
|
||||
{
|
||||
public class PceControllerView : UserControl
|
||||
{
|
||||
public PceControllerView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
88
NewUI/Views/PceInputConfigView.axaml
Normal file
88
NewUI/Views/PceInputConfigView.axaml
Normal file
|
@ -0,0 +1,88 @@
|
|||
<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:l="using:Mesen.Localization"
|
||||
xmlns:c="using:Mesen.Controls"
|
||||
xmlns:v="using:Mesen.Views"
|
||||
xmlns:cfg="using:Mesen.Config"
|
||||
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
x:DataType="vm:PceInputConfigViewModel"
|
||||
x:Class="Mesen.Views.PceInputConfigView"
|
||||
>
|
||||
<Design.DataContext>
|
||||
<vm:PceInputConfigViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<ScrollViewer AllowAutoHide="False">
|
||||
<StackPanel>
|
||||
<c:OptionSection Header="{l:Translate grpControllers}" Margin="0">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto,Auto,Auto,Auto,Auto" HorizontalAlignment="Left">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="{l:Translate lblController}" />
|
||||
<c:InputComboBox
|
||||
Grid.Row="0" Grid.Column="1"
|
||||
Config="{CompiledBinding Config.Port1}"
|
||||
ControllerType="{CompiledBinding Config.Port1.Type}"
|
||||
AvailableValues="{CompiledBinding AvailableControllerTypesP1}"
|
||||
/>
|
||||
|
||||
<c:GroupBox
|
||||
Header="{l:Translate lblTurboTapConfig}"
|
||||
IsVisible="{CompiledBinding HasTurboTap}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0 5 -6 5"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3"
|
||||
>
|
||||
<Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto,Auto,Auto,Auto,Auto">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="{l:Translate lblPort1A}" />
|
||||
<c:InputComboBox
|
||||
Grid.Row="0" Grid.Column="1"
|
||||
Config="{CompiledBinding Config.Port1}"
|
||||
ControllerType="{CompiledBinding Config.Port1A.Type}"
|
||||
AvailableValues="{CompiledBinding AvailableControllerTypesTurboTap}"
|
||||
/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="{l:Translate lblPort1B}" />
|
||||
<c:InputComboBox
|
||||
Grid.Row="1" Grid.Column="1"
|
||||
Config="{CompiledBinding Config.Port1B}"
|
||||
ControllerType="{CompiledBinding Config.Port1B.Type}"
|
||||
AvailableValues="{CompiledBinding AvailableControllerTypesTurboTap}"
|
||||
/>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="{l:Translate lblPort1C}" />
|
||||
<c:InputComboBox
|
||||
Grid.Row="2" Grid.Column="1"
|
||||
Config="{CompiledBinding Config.Port1C}"
|
||||
ControllerType="{CompiledBinding Config.Port1C.Type}"
|
||||
AvailableValues="{CompiledBinding AvailableControllerTypesTurboTap}"
|
||||
/>
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Text="{l:Translate lblPort1D}" />
|
||||
<c:InputComboBox
|
||||
Grid.Row="3" Grid.Column="1"
|
||||
Config="{CompiledBinding Config.Port1D}"
|
||||
ControllerType="{CompiledBinding Config.Port1D.Type}"
|
||||
AvailableValues="{CompiledBinding AvailableControllerTypesTurboTap}"
|
||||
/>
|
||||
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" Text="{l:Translate lblPort1E}" />
|
||||
<c:InputComboBox
|
||||
Grid.Row="4" Grid.Column="1"
|
||||
Config="{CompiledBinding Config.Port1E}"
|
||||
ControllerType="{CompiledBinding Config.Port1E.Type}"
|
||||
AvailableValues="{CompiledBinding AvailableControllerTypesTurboTap}"
|
||||
/>
|
||||
</Grid>
|
||||
</c:GroupBox>
|
||||
</Grid>
|
||||
</c:OptionSection>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
18
NewUI/Views/PceInputConfigView.axaml.cs
Normal file
18
NewUI/Views/PceInputConfigView.axaml.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Mesen.Views
|
||||
{
|
||||
public class PceInputConfigView : UserControl
|
||||
{
|
||||
public PceInputConfigView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,6 +41,9 @@
|
|||
<DataTemplate DataType="{x:Type vm:GameboyConfigViewModel}">
|
||||
<v:GameboyConfigView />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type vm:PceConfigViewModel}">
|
||||
<v:PceConfigView />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type vm:PreferencesConfigViewModel}">
|
||||
<v:PreferencesConfigView />
|
||||
</DataTemplate>
|
||||
|
@ -124,6 +127,15 @@
|
|||
</TabItem.Header>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Content="{CompiledBinding PcEngine}">
|
||||
<TabItem.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="/Assets/PceIcon.png" Margin="0 0 10 0" />
|
||||
<TextBlock VerticalAlignment="Center" Text="{l:Translate tabPcEngine}" />
|
||||
</StackPanel>
|
||||
</TabItem.Header>
|
||||
</TabItem>
|
||||
|
||||
<TabItem IsEnabled="False" MinHeight="10">
|
||||
<TabItem.Header>
|
||||
<Rectangle Fill="LightGray" Height="1" />
|
||||
|
|
Loading…
Add table
Reference in a new issue