Mesen/Core/FdsSystemActionManager.h

146 lines
3.3 KiB
C++

#pragma once
#include "stdafx.h"
#include "SystemActionManager.h"
#include "MessageManager.h"
#include "FDS.h"
class FdsSystemActionManager : public SystemActionManager
{
private:
const uint8_t ReinsertDiskFrameDelay = 120;
std::weak_ptr<FDS> _mapper;
bool _needEjectDisk = false;
uint8_t _insertDiskNumber = 0;
uint8_t _insertDiskDelay = 0;
uint32_t _sideCount;
protected:
string GetKeyNames() override
{
return string("RPE0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ").substr(0, _sideCount + 3);
}
void StreamState(bool saving) override
{
SystemActionManager::StreamState(saving);
Stream(_needEjectDisk, _insertDiskNumber, _insertDiskDelay);
}
public:
enum FdsButtons { EjectDiskButton = 2, InsertDisk1 };
FdsSystemActionManager(shared_ptr<Console> console, shared_ptr<BaseMapper> mapper) : SystemActionManager(console)
{
_mapper = std::dynamic_pointer_cast<FDS>(mapper);
_sideCount = std::dynamic_pointer_cast<FDS>(mapper)->GetSideCount();
if(console->GetSettings()->CheckFlag(EmulationFlags::FdsAutoLoadDisk)) {
InsertDisk(0);
}
}
void OnAfterSetState() override
{
SystemActionManager::OnAfterSetState();
if(_needEjectDisk) {
SetBit(FdsSystemActionManager::FdsButtons::EjectDiskButton);
_needEjectDisk = false;
}
if(_insertDiskDelay > 0) {
_insertDiskDelay--;
if(_insertDiskDelay == 0) {
SetBit(FdsSystemActionManager::FdsButtons::InsertDisk1 + _insertDiskNumber);
}
}
bool needEject = IsPressed(FdsSystemActionManager::FdsButtons::EjectDiskButton);
int diskToInsert = -1;
for(int i = 0; i < 16; i++) {
if(IsPressed(FdsSystemActionManager::FdsButtons::InsertDisk1 + i)) {
diskToInsert = i;
break;
}
}
if(needEject || diskToInsert >= 0) {
shared_ptr<FDS> mapper = _mapper.lock();
if(needEject) {
mapper->EjectDisk();
}
if(diskToInsert >= 0) {
mapper->InsertDisk(diskToInsert);
}
}
}
void EjectDisk()
{
_needEjectDisk = true;
}
void InsertDisk(uint8_t diskNumber)
{
shared_ptr<FDS> mapper = _mapper.lock();
if(mapper) {
if(mapper->IsDiskInserted()) {
//Eject disk on next frame, then insert new disk 2 seconds later
_needEjectDisk = true;
_insertDiskNumber = diskNumber;
_insertDiskDelay = FdsSystemActionManager::ReinsertDiskFrameDelay;
} else {
//Insert disk on next frame
_insertDiskNumber = diskNumber;
_insertDiskDelay = 1;
}
MessageManager::DisplayMessage("FDS", "FdsDiskInserted", std::to_string(diskNumber / 2 + 1), diskNumber & 0x01 ? "B" : "A");
}
}
void SwitchDiskSide()
{
if(!IsAutoInsertDiskEnabled()) {
shared_ptr<FDS> mapper = _mapper.lock();
if(mapper && mapper->IsDiskInserted()) {
_console->Pause();
InsertDisk((mapper->GetCurrentDisk() ^ 0x01) % mapper->GetSideCount());
_console->Resume();
}
}
}
void InsertNextDisk()
{
if(!IsAutoInsertDiskEnabled()) {
shared_ptr<FDS> mapper = _mapper.lock();
if(mapper) {
_console->Pause();
InsertDisk(((mapper->GetCurrentDisk() & 0xFE) + 2) % mapper->GetSideCount());
_console->Resume();
}
}
}
uint32_t GetSideCount()
{
shared_ptr<FDS> mapper = _mapper.lock();
if(mapper) {
return mapper->GetSideCount();
} else {
return 0;
}
}
bool IsAutoInsertDiskEnabled()
{
shared_ptr<FDS> mapper = _mapper.lock();
if(mapper) {
return mapper->IsAutoInsertDiskEnabled();
} else {
return false;
}
}
};