make cross-instance pause work without being a shitshow

This commit is contained in:
Arisotura 2023-03-11 13:46:29 +01:00
parent ea951d092e
commit d296ce3f5e
4 changed files with 68 additions and 16 deletions

View File

@ -61,6 +61,8 @@ const u32 kMaxCommandSize = 0x800;
const u32 kCommandStart = sizeof(BufferHeader);
const u32 kCommandEnd = kBufferSize;
bool CmdRecvFlags[Cmd_MAX];
void Init()
{
@ -109,6 +111,8 @@ void Init()
}
Buffer->unlock();
memset(CmdRecvFlags, 0, sizeof(CmdRecvFlags));
printf("IPC: instance ID %d\n", InstanceID);
}
@ -185,6 +189,8 @@ void FIFOWrite(void* buf, int len)
void Process()
{
memset(CmdRecvFlags, 0, sizeof(CmdRecvFlags));
Buffer->lock();
u8* data = (u8*)Buffer->data();
BufferHeader* header = (BufferHeader*)&data[0];
@ -211,13 +217,18 @@ void Process()
if (!(cmdheader.Recipients & (1<<InstanceID)))
continue;
if (cmdheader.Command >= Cmd_MAX)
continue;
// handle this command
switch (cmdheader.Command)
/*switch (cmdheader.Command)
{
case Cmd_Pause:
Input::ExtHotkeyPress(HK_Pause);
break;
}
}*/
CmdRecvFlags[cmdheader.Command] = true;
// TODO: store the command data, for future commands that will need it
}
Buffer->unlock();
@ -225,6 +236,22 @@ void Process()
bool SendCommand(u16 recipients, u16 command, u16 len, void* cmddata)
{
if (command >= Cmd_MAX)
{
printf("IPC: invalid command %d\n", command);
return false;
}
if (len && cmddata==nullptr)
{
printf("IPC: ????? sending command with NULL buffer\n");
return false;
}
if (len > kMaxCommandSize)
{
printf("IPC: command too long\n");
return false;
}
Buffer->lock();
u8* data = (u8*)Buffer->data();
BufferHeader* header = (BufferHeader*)&data[0];
@ -237,19 +264,6 @@ bool SendCommand(u16 recipients, u16 command, u16 len, void* cmddata)
return false;
}
if (len && cmddata==nullptr)
{
printf("IPC: ????? sending command with NULL buffer\n");
Buffer->unlock();
return false;
}
if (len > kMaxCommandSize)
{
printf("IPC: command too long\n");
Buffer->unlock();
return false;
}
CommandHeader cmdheader;
cmdheader.Magic = 0x4D434C4D;
cmdheader.SenderID = InstanceID;
@ -264,4 +278,10 @@ bool SendCommand(u16 recipients, u16 command, u16 len, void* cmddata)
return true;
}
bool CommandReceived(u16 command)
{
if (command >= Cmd_MAX) return false;
return CmdRecvFlags[command];
}
}

View File

@ -27,6 +27,8 @@ namespace IPC
enum
{
Cmd_Pause = 1,
Cmd_MAX
};
extern int InstanceID;
@ -37,6 +39,7 @@ void DeInit();
void Process();
bool SendCommand(u16 recipients, u16 command, u16 len, void* data);
bool CommandReceived(u16 command);
}

View File

@ -198,6 +198,8 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent)
connect(this, SIGNAL(swapScreensToggle()), mainWindow->actScreenSwap, SLOT(trigger()));
connect(this, SIGNAL(screenEmphasisToggle()), mainWindow, SLOT(onScreenEmphasisToggled()));
connect(this, SIGNAL(windowIPCPause()), mainWindow, SLOT(onIPCPause()));
static_cast<ScreenPanelGL*>(mainWindow->panel)->transferLayout(this);
}
@ -359,6 +361,8 @@ void EmuThread::run()
{
IPC::Process();
if (IPC::CommandReceived(IPC::Cmd_Pause)) emit windowIPCPause();
Input::Process();
if (Input::HotkeyPressed(HK_FastForwardToggle)) emit windowLimitFPSChange();
@ -2707,10 +2711,32 @@ void MainWindow::onPause(bool checked)
pausedManually = false;
}
if (Platform::InstanceID()==0) // HAX
IPC::SendCommand(0xFFFF, IPC::Cmd_Pause, 0, nullptr);
}
void MainWindow::onIPCPause()
{
// for IPC, using the normal way to trigger a pause (actPause->trigger())
// isn't viable, because it would lead to broadcasting more IPC 'pause' messages
// so we have to replicate it this way
actPause->toggle(); // changes visual state, without triggering onPause()
bool checked = actPause->isChecked();
if (checked)
{
emuThread->emuPause();
OSD::AddMessage(0, "Paused");
pausedManually = true;
}
else
{
emuThread->emuUnpause();
OSD::AddMessage(0, "Resumed");
pausedManually = false;
}
}
void MainWindow::onReset()
{
if (!RunningSomething) return;

View File

@ -78,6 +78,8 @@ signals:
void windowEmuReset();
void windowEmuFrameStep();
void windowIPCPause();
void windowLimitFPSChange();
void screenLayoutChange();
@ -296,6 +298,7 @@ private slots:
void onQuit();
void onPause(bool checked);
void onIPCPause();
void onReset();
void onStop();
void onFrameStep();