Implement memory cards
This commit is contained in:
parent
314fad27f1
commit
71022e9cca
|
@ -6,6 +6,7 @@
|
|||
#include "imgui_impl_opengl3.h"
|
||||
#include "imgui_impl_sdl.h"
|
||||
#include "pse/digital_controller.h"
|
||||
#include "pse/memory_card.h"
|
||||
#include "pse/system.h"
|
||||
#include <cinttypes>
|
||||
#include <glad.h>
|
||||
|
@ -164,6 +165,7 @@ std::unique_ptr<SDLInterface> SDLInterface::Create()
|
|||
return nullptr;
|
||||
|
||||
intf->m_controller = DigitalController::Create();
|
||||
intf->m_memory_card = MemoryCard::Create();
|
||||
|
||||
return intf;
|
||||
}
|
||||
|
@ -285,18 +287,17 @@ bool SDLInterface::HandleSDLEvent(const SDL_Event* event)
|
|||
case SDL_SCANCODE_F6:
|
||||
case SDL_SCANCODE_F7:
|
||||
case SDL_SCANCODE_F8:
|
||||
{
|
||||
if (!pressed)
|
||||
{
|
||||
if (!pressed)
|
||||
{
|
||||
auto filename = GetSaveStateFilename(event->key.keysym.scancode - SDL_SCANCODE_F1 + 1);
|
||||
if (event->key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))
|
||||
SaveState(filename);
|
||||
else
|
||||
LoadState(filename);
|
||||
}
|
||||
auto filename = GetSaveStateFilename(event->key.keysym.scancode - SDL_SCANCODE_F1 + 1);
|
||||
if (event->key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))
|
||||
SaveState(filename);
|
||||
else
|
||||
LoadState(filename);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_SCANCODE_TAB:
|
||||
SDL_GL_SetSwapInterval(pressed ? 0 : 1);
|
||||
|
@ -593,7 +594,8 @@ void SDLInterface::DoSaveState(u32 index)
|
|||
|
||||
void SDLInterface::Run()
|
||||
{
|
||||
m_system->SetPadDevice(0, m_controller);
|
||||
m_system->SetController(0, m_controller);
|
||||
m_system->SetMemoryCard(0, m_memory_card);
|
||||
|
||||
while (m_running)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
class System;
|
||||
class DigitalController;
|
||||
class MemoryCard;
|
||||
|
||||
class SDLInterface : public HostInterface
|
||||
{
|
||||
|
@ -77,6 +78,7 @@ private:
|
|||
std::mutex m_osd_messages_lock;
|
||||
|
||||
std::shared_ptr<DigitalController> m_controller;
|
||||
std::shared_ptr<MemoryCard> m_memory_card;
|
||||
|
||||
float m_vps = 0.0f;
|
||||
float m_fps = 0.0f;
|
||||
|
|
|
@ -456,8 +456,8 @@ void Core::Execute()
|
|||
{
|
||||
while (m_downcount >= 0)
|
||||
{
|
||||
m_pending_ticks += 2;
|
||||
m_downcount -= 2;
|
||||
m_pending_ticks += 3;
|
||||
m_downcount -= 3;
|
||||
|
||||
// now executing the instruction we previously fetched
|
||||
const Instruction inst = m_next_instruction;
|
||||
|
|
|
@ -14,6 +14,11 @@ void DigitalController::SetButtonState(Button button, bool pressed)
|
|||
m_button_state |= u16(1) << static_cast<u8>(button);
|
||||
}
|
||||
|
||||
void DigitalController::ResetTransferState()
|
||||
{
|
||||
m_transfer_fifo.Clear();
|
||||
}
|
||||
|
||||
bool DigitalController::Transfer(const u8 data_in, u8* data_out)
|
||||
{
|
||||
bool ack;
|
||||
|
@ -75,3 +80,4 @@ std::shared_ptr<DigitalController> DigitalController::Create()
|
|||
{
|
||||
return std::make_shared<DigitalController>();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
|
||||
void SetButtonState(Button button, bool pressed);
|
||||
|
||||
void ResetTransferState() override;
|
||||
bool Transfer(const u8 data_in, u8* data_out) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -84,7 +84,6 @@ u32 DMA::ReadRegister(u32 offset)
|
|||
void DMA::WriteRegister(u32 offset, u32 value)
|
||||
{
|
||||
const u32 channel_index = offset >> 4;
|
||||
Log_DevPrintf("DMA channel %u offset %u", channel_index, offset);
|
||||
if (channel_index < 7)
|
||||
{
|
||||
ChannelState& state = m_state[channel_index];
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
#include "memory_card.h"
|
||||
#include "YBaseLib/Log.h"
|
||||
Log_SetChannel(MemoryCard);
|
||||
|
||||
MemoryCard::MemoryCard()
|
||||
{
|
||||
m_FLAG.no_write_yet = true;
|
||||
}
|
||||
|
||||
MemoryCard::~MemoryCard() = default;
|
||||
|
||||
void MemoryCard::ResetTransferState()
|
||||
{
|
||||
m_state = State::Idle;
|
||||
m_address = 0;
|
||||
m_sector_offset = 0;
|
||||
m_checksum = 0;
|
||||
m_last_byte = 0;
|
||||
}
|
||||
|
||||
bool MemoryCard::Transfer(const u8 data_in, u8* data_out)
|
||||
{
|
||||
bool ack = false;
|
||||
const State old_state = m_state;
|
||||
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
#define FIXED_REPLY_STATE(state, reply, ack_value, next_state) \
|
||||
case state: \
|
||||
{ \
|
||||
*data_out = reply; \
|
||||
ack = ack_value; \
|
||||
m_state = next_state; \
|
||||
} \
|
||||
break;
|
||||
|
||||
#define ADDRESS_STATE_MSB(state, next_state) \
|
||||
case state: \
|
||||
{ \
|
||||
*data_out = 0x00; \
|
||||
ack = true; \
|
||||
m_address = ((m_address & u16(0x00FF)) | (ZeroExtend16(data_in) << 8)) & 0x3FF; \
|
||||
m_state = next_state; \
|
||||
} \
|
||||
break;
|
||||
|
||||
#define ADDRESS_STATE_LSB(state, next_state) \
|
||||
case state: \
|
||||
{ \
|
||||
*data_out = m_last_byte; \
|
||||
ack = true; \
|
||||
m_address = ((m_address & u16(0xFF00)) | ZeroExtend16(data_in)) & 0x3FF; \
|
||||
m_sector_offset = 0; \
|
||||
m_state = next_state; \
|
||||
} \
|
||||
break;
|
||||
|
||||
// read state
|
||||
|
||||
FIXED_REPLY_STATE(State::ReadCardID1, 0x5A, true, State::ReadCardID2);
|
||||
FIXED_REPLY_STATE(State::ReadCardID2, 0x5D, true, State::ReadAddressMSB);
|
||||
ADDRESS_STATE_MSB(State::ReadAddressMSB, State::ReadAddressLSB);
|
||||
ADDRESS_STATE_LSB(State::ReadAddressLSB, State::ReadACK1);
|
||||
FIXED_REPLY_STATE(State::ReadACK1, 0x5C, true, State::ReadACK2);
|
||||
FIXED_REPLY_STATE(State::ReadACK2, 0x5D, true, State::ReadConfirmAddressMSB);
|
||||
FIXED_REPLY_STATE(State::ReadConfirmAddressMSB, Truncate8(m_address >> 8), true, State::ReadConfirmAddressLSB);
|
||||
FIXED_REPLY_STATE(State::ReadConfirmAddressLSB, Truncate8(m_address), true, State::ReadData);
|
||||
|
||||
case State::ReadData:
|
||||
{
|
||||
const u8 bits = m_data[ZeroExtend32(m_address) * SECTOR_SIZE + m_sector_offset];
|
||||
if (m_sector_offset == 0)
|
||||
{
|
||||
Log_DebugPrintf("Reading memory card sector %u", ZeroExtend32(m_address));
|
||||
m_checksum = Truncate8(m_address >> 8) ^ Truncate8(m_address) ^ bits;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_checksum ^= bits;
|
||||
}
|
||||
|
||||
*data_out = bits;
|
||||
ack = true;
|
||||
|
||||
m_sector_offset++;
|
||||
if (m_sector_offset == SECTOR_SIZE)
|
||||
{
|
||||
m_state = State::ReadChecksum;
|
||||
m_sector_offset = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
FIXED_REPLY_STATE(State::ReadChecksum, m_checksum, true, State::ReadEnd);
|
||||
FIXED_REPLY_STATE(State::ReadEnd, 0x47, false, State::Idle);
|
||||
|
||||
// write state
|
||||
|
||||
FIXED_REPLY_STATE(State::WriteCardID1, 0x5A, true, State::WriteCardID2);
|
||||
FIXED_REPLY_STATE(State::WriteCardID2, 0x5D, true, State::WriteAddressMSB);
|
||||
ADDRESS_STATE_MSB(State::WriteAddressMSB, State::WriteAddressLSB);
|
||||
ADDRESS_STATE_LSB(State::WriteAddressLSB, State::WriteData);
|
||||
|
||||
case State::WriteData:
|
||||
{
|
||||
if (m_sector_offset == 0)
|
||||
{
|
||||
Log_DebugPrintf("Writing memory card sector %u", ZeroExtend32(m_address));
|
||||
m_checksum = Truncate8(m_address >> 8) ^ Truncate8(m_address) ^ data_in;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_checksum ^= data_in;
|
||||
}
|
||||
|
||||
m_data[ZeroExtend32(m_address) * SECTOR_SIZE + m_sector_offset] = data_in;
|
||||
*data_out = m_last_byte;
|
||||
ack = true;
|
||||
|
||||
m_sector_offset++;
|
||||
if (m_sector_offset == SECTOR_SIZE)
|
||||
{
|
||||
m_state = State::WriteChecksum;
|
||||
m_sector_offset = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
FIXED_REPLY_STATE(State::WriteChecksum, m_checksum, true, State::WriteACK1);
|
||||
FIXED_REPLY_STATE(State::WriteACK1, 0x5C, true, State::WriteACK2);
|
||||
FIXED_REPLY_STATE(State::WriteACK2, 0x5D, true, State::WriteEnd);
|
||||
FIXED_REPLY_STATE(State::WriteEnd, 0x47, false, State::Idle);
|
||||
|
||||
// new command
|
||||
case State::Idle:
|
||||
{
|
||||
switch (data_in)
|
||||
{
|
||||
case 0x81: // tests if the controller is present
|
||||
{
|
||||
// response is hi-z
|
||||
*data_out = 0xFF;
|
||||
ack = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x52: // read data
|
||||
{
|
||||
*data_out = m_FLAG.bits;
|
||||
ack = true;
|
||||
m_state = State::ReadCardID1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x57: // write data
|
||||
{
|
||||
*data_out = m_FLAG.bits;
|
||||
ack = true;
|
||||
m_state = State::WriteCardID1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x53: // get id
|
||||
{
|
||||
Panic("implement me");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
*data_out = m_FLAG.bits;
|
||||
ack = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
UnreachableCode();
|
||||
break;
|
||||
}
|
||||
|
||||
Log_DebugPrintf("Transfer, old_state=%u, new_state=%u, data_in=0x%02X, data_out=0x%02X, ack=%s",
|
||||
static_cast<u32>(old_state), static_cast<u32>(m_state), data_in, *data_out, ack ? "true" : "false");
|
||||
m_last_byte = data_in;
|
||||
return ack;
|
||||
}
|
||||
|
||||
std::shared_ptr<MemoryCard> MemoryCard::Create()
|
||||
{
|
||||
return std::make_shared<MemoryCard>();
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
#include "common/bitfield.h"
|
||||
#include "pad_device.h"
|
||||
#include <memory>
|
||||
#include <array>
|
||||
|
||||
class MemoryCard final : public PadDevice
|
||||
{
|
||||
public:
|
||||
enum : u32
|
||||
{
|
||||
DATA_SIZE = 128 * 1024, // 1mbit
|
||||
SECTOR_SIZE = 128,
|
||||
NUM_SECTORS = DATA_SIZE / SECTOR_SIZE
|
||||
};
|
||||
|
||||
MemoryCard();
|
||||
~MemoryCard() override;
|
||||
|
||||
static std::shared_ptr<MemoryCard> Create();
|
||||
|
||||
void ResetTransferState() override;
|
||||
bool Transfer(const u8 data_in, u8* data_out) override;
|
||||
|
||||
private:
|
||||
union FLAG
|
||||
{
|
||||
u8 bits;
|
||||
|
||||
BitField<u8, bool, 3, 1> no_write_yet;
|
||||
BitField<u8, bool, 2, 1> write_error;
|
||||
};
|
||||
|
||||
FLAG m_FLAG = {};
|
||||
|
||||
enum class State : u8
|
||||
{
|
||||
Idle,
|
||||
|
||||
ReadCardID1,
|
||||
ReadCardID2,
|
||||
ReadAddressMSB,
|
||||
ReadAddressLSB,
|
||||
ReadACK1,
|
||||
ReadACK2,
|
||||
ReadConfirmAddressMSB,
|
||||
ReadConfirmAddressLSB,
|
||||
ReadData,
|
||||
ReadChecksum,
|
||||
ReadEnd,
|
||||
|
||||
WriteCardID1,
|
||||
WriteCardID2,
|
||||
WriteAddressMSB,
|
||||
WriteAddressLSB,
|
||||
WriteData,
|
||||
WriteChecksum,
|
||||
WriteACK1,
|
||||
WriteACK2,
|
||||
WriteEnd,
|
||||
};
|
||||
|
||||
State m_state = State::Idle;
|
||||
u16 m_address = 0;
|
||||
u8 m_sector_offset = 0;
|
||||
u8 m_checksum = 0;
|
||||
u8 m_last_byte = 0;
|
||||
|
||||
std::array<u8, DATA_SIZE> m_data{};
|
||||
};
|
|
@ -107,6 +107,9 @@ void Pad::WriteRegister(u32 offset, u32 value)
|
|||
m_JOY_STAT.INTR = false;
|
||||
}
|
||||
|
||||
if (!m_JOY_CTRL.SELECT)
|
||||
ResetDeviceTransferState();
|
||||
|
||||
if (!m_JOY_CTRL.SELECT || !m_JOY_CTRL.TXEN)
|
||||
{
|
||||
if (IsTransmitting())
|
||||
|
@ -211,25 +214,62 @@ void Pad::DoTransfer()
|
|||
{
|
||||
Log_DebugPrintf("Transferring slot %d", m_JOY_CTRL.SLOT.GetValue());
|
||||
|
||||
const std::shared_ptr<PadDevice>& dev = m_devices[m_JOY_CTRL.SLOT];
|
||||
if (!dev || !CanTransfer())
|
||||
{
|
||||
// no device present, don't set ACK and read hi-z
|
||||
m_TX_FIFO.Clear();
|
||||
m_RX_FIFO.Clear();
|
||||
m_RX_FIFO.Push(0xFF);
|
||||
UpdateJoyStat();
|
||||
EndTransfer();
|
||||
return;
|
||||
}
|
||||
const std::shared_ptr<PadDevice>& controller = m_controllers[m_JOY_CTRL.SLOT];
|
||||
const std::shared_ptr<PadDevice>& memory_card = m_memory_cards[m_JOY_CTRL.SLOT];
|
||||
|
||||
// set rx?
|
||||
m_JOY_CTRL.RXEN = true;
|
||||
|
||||
const u8 data_out = m_TX_FIFO.Pop();
|
||||
u8 data_in;
|
||||
m_JOY_STAT.ACKINPUT |= dev->Transfer(data_out, &data_in);
|
||||
u8 data_in = 0xFF;
|
||||
bool ack = false;
|
||||
|
||||
switch (m_active_device)
|
||||
{
|
||||
case ActiveDevice::None:
|
||||
{
|
||||
if (!controller || !(ack = controller->Transfer(data_out, &data_in)))
|
||||
{
|
||||
if (!memory_card || !(ack = memory_card->Transfer(data_out, &data_in)))
|
||||
{
|
||||
// nothing connected to this port
|
||||
Log_DebugPrintf("Nothing connected or ACK'ed");
|
||||
}
|
||||
else
|
||||
{
|
||||
// memory card responded, make it the active device until non-ack
|
||||
m_active_device = ActiveDevice::MemoryCard;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// controller responded, make it the active device until non-ack
|
||||
m_active_device = ActiveDevice::Controller;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ActiveDevice::Controller:
|
||||
{
|
||||
if (controller)
|
||||
ack = controller->Transfer(data_out, &data_in);
|
||||
}
|
||||
break;
|
||||
|
||||
case ActiveDevice::MemoryCard:
|
||||
{
|
||||
if (memory_card)
|
||||
ack = memory_card->Transfer(data_out, &data_in);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_RX_FIFO.Push(data_in);
|
||||
m_JOY_STAT.ACKINPUT |= ack;
|
||||
|
||||
// device no longer active?
|
||||
if (!ack)
|
||||
m_active_device = ActiveDevice::None;
|
||||
|
||||
if (m_JOY_STAT.ACKINPUT && m_JOY_CTRL.ACKINTEN)
|
||||
{
|
||||
|
@ -260,3 +300,14 @@ void Pad::EndTransfer()
|
|||
m_state = State::Idle;
|
||||
m_ticks_remaining = 0;
|
||||
}
|
||||
|
||||
void Pad::ResetDeviceTransferState()
|
||||
{
|
||||
for (u32 i = 0; i < NUM_SLOTS; i++)
|
||||
{
|
||||
if (m_controllers[i])
|
||||
m_controllers[i]->ResetTransferState();
|
||||
if (m_memory_cards[i])
|
||||
m_memory_cards[i]->ResetTransferState();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,11 @@ public:
|
|||
void Reset();
|
||||
bool DoState(StateWrapper& sw);
|
||||
|
||||
PadDevice* GetDevice(u32 slot) { return m_devices[slot].get(); }
|
||||
void SetDevice(u32 slot, std::shared_ptr<PadDevice> dev) { m_devices[slot] = dev; }
|
||||
PadDevice* GetController(u32 slot) { return m_controllers[slot].get(); }
|
||||
void SetController(u32 slot, std::shared_ptr<PadDevice> dev) { m_controllers[slot] = dev; }
|
||||
|
||||
PadDevice* GetMemoryCard(u32 slot) { return m_memory_cards[slot].get(); }
|
||||
void SetMemoryCard(u32 slot, std::shared_ptr<PadDevice> dev) { m_memory_cards[slot] = dev; }
|
||||
|
||||
u32 ReadRegister(u32 offset);
|
||||
void WriteRegister(u32 offset, u32 value);
|
||||
|
@ -31,7 +34,7 @@ public:
|
|||
|
||||
private:
|
||||
static constexpr u32 NUM_SLOTS = 2;
|
||||
static constexpr u32 TRANSFER_TICKS = 750;
|
||||
static constexpr u32 TRANSFER_TICKS = 550;
|
||||
|
||||
enum class State : u32
|
||||
{
|
||||
|
@ -39,6 +42,13 @@ private:
|
|||
Transmitting
|
||||
};
|
||||
|
||||
enum class ActiveDevice : u8
|
||||
{
|
||||
None,
|
||||
Controller,
|
||||
MemoryCard
|
||||
};
|
||||
|
||||
union JOY_CTRL
|
||||
{
|
||||
u16 bits;
|
||||
|
@ -89,6 +99,7 @@ private:
|
|||
void BeginTransfer();
|
||||
void DoTransfer();
|
||||
void EndTransfer();
|
||||
void ResetDeviceTransferState();
|
||||
|
||||
System* m_system = nullptr;
|
||||
InterruptController* m_interrupt_controller = nullptr;
|
||||
|
@ -100,8 +111,10 @@ private:
|
|||
JOY_STAT m_JOY_STAT = {};
|
||||
JOY_MODE m_JOY_MODE = {};
|
||||
|
||||
ActiveDevice m_active_device = ActiveDevice::None;
|
||||
InlineFIFOQueue<u8, 8> m_RX_FIFO;
|
||||
InlineFIFOQueue<u8, 2> m_TX_FIFO;
|
||||
|
||||
std::array<std::shared_ptr<PadDevice>, NUM_SLOTS> m_devices;
|
||||
std::array<std::shared_ptr<PadDevice>, NUM_SLOTS> m_controllers;
|
||||
std::array<std::shared_ptr<PadDevice>, NUM_SLOTS> m_memory_cards;
|
||||
};
|
||||
|
|
|
@ -4,6 +4,8 @@ PadDevice::PadDevice() = default;
|
|||
|
||||
PadDevice::~PadDevice() = default;
|
||||
|
||||
void PadDevice::ResetTransferState() {}
|
||||
|
||||
bool PadDevice::Transfer(const u8 data_in, u8* data_out)
|
||||
{
|
||||
*data_out = 0xFF;
|
||||
|
|
|
@ -7,6 +7,9 @@ public:
|
|||
PadDevice();
|
||||
virtual ~PadDevice();
|
||||
|
||||
// Resets all state for the transferring to/from the device.
|
||||
virtual void ResetTransferState();
|
||||
|
||||
// Returns the value of ACK, as well as filling out_data.
|
||||
virtual bool Transfer(const u8 data_in, u8* data_out);
|
||||
};
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
<ClCompile Include="host_interface.cpp" />
|
||||
<ClCompile Include="interrupt_controller.cpp" />
|
||||
<ClCompile Include="mdec.cpp" />
|
||||
<ClCompile Include="memory_card.cpp" />
|
||||
<ClCompile Include="pad.cpp" />
|
||||
<ClCompile Include="pad_device.cpp" />
|
||||
<ClCompile Include="spu.cpp" />
|
||||
|
@ -70,6 +71,7 @@
|
|||
<ClInclude Include="host_interface.h" />
|
||||
<ClInclude Include="interrupt_controller.h" />
|
||||
<ClInclude Include="mdec.h" />
|
||||
<ClInclude Include="memory_card.h" />
|
||||
<ClInclude Include="pad.h" />
|
||||
<ClInclude Include="pad_device.h" />
|
||||
<ClInclude Include="save_state_version.h" />
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
<ClCompile Include="timers.cpp" />
|
||||
<ClCompile Include="spu.cpp" />
|
||||
<ClCompile Include="mdec.cpp" />
|
||||
<ClCompile Include="memory_card.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="types.h" />
|
||||
|
@ -43,6 +44,7 @@
|
|||
<ClInclude Include="timers.h" />
|
||||
<ClInclude Include="spu.h" />
|
||||
<ClInclude Include="mdec.h" />
|
||||
<ClInclude Include="memory_card.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpu_core.inl" />
|
||||
|
|
|
@ -284,9 +284,14 @@ void System::SetDowncount(TickCount downcount)
|
|||
m_cpu->SetDowncount(downcount);
|
||||
}
|
||||
|
||||
void System::SetPadDevice(u32 slot, std::shared_ptr<PadDevice> dev)
|
||||
void System::SetController(u32 slot, std::shared_ptr<PadDevice> dev)
|
||||
{
|
||||
m_pad->SetDevice(slot, std::move(dev));
|
||||
m_pad->SetController(slot, std::move(dev));
|
||||
}
|
||||
|
||||
void System::SetMemoryCard(u32 slot, std::shared_ptr<PadDevice> dev)
|
||||
{
|
||||
m_pad->SetMemoryCard(slot, std::move(dev));
|
||||
}
|
||||
|
||||
bool System::HasMedia() const
|
||||
|
|
|
@ -51,7 +51,8 @@ public:
|
|||
void SetDowncount(TickCount downcount);
|
||||
void Synchronize();
|
||||
|
||||
void SetPadDevice(u32 slot, std::shared_ptr<PadDevice> dev);
|
||||
void SetController(u32 slot, std::shared_ptr<PadDevice> dev);
|
||||
void SetMemoryCard(u32 slot, std::shared_ptr<PadDevice> dev);
|
||||
|
||||
bool HasMedia() const;
|
||||
bool InsertMedia(const char* path);
|
||||
|
|
Loading…
Reference in New Issue