GSP: add basic event handling system
This commit is contained in:
parent
66523edaae
commit
0d3ed55b88
@ -27,9 +27,33 @@ typedef struct
|
|||||||
GSP_CaptureInfoEntry screencapture[2];
|
GSP_CaptureInfoEntry screencapture[2];
|
||||||
} GSP_CaptureInfo;
|
} GSP_CaptureInfo;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GSPEVENT_PSC0 = 0,
|
||||||
|
GSPEVENT_PSC1,
|
||||||
|
GSPEVENT_VBlank0,
|
||||||
|
GSPEVENT_VBlank1,
|
||||||
|
GSPEVENT_PPF,
|
||||||
|
GSPEVENT_P3D,
|
||||||
|
GSPEVENT_DMA,
|
||||||
|
GSPEVENT_count, // used to know how many events there are
|
||||||
|
} GSP_Event;
|
||||||
|
|
||||||
Result gspInit();
|
Result gspInit();
|
||||||
void gspExit();
|
void gspExit();
|
||||||
|
|
||||||
|
Result gspInitEventHandler(Handle gspEvent, vu8* gspSharedMem, u8 gspThreadId);
|
||||||
|
void gspExitEventHandler();
|
||||||
|
void gspWaitForEvent(GSP_Event id);
|
||||||
|
#define gspWaitForPSC0() gspWaitForEvent(GSPEVENT_PSC0)
|
||||||
|
#define gspWaitForPSC1() gspWaitForEvent(GSPEVENT_PSC1)
|
||||||
|
#define gspWaitForVBlank() gspWaitForVBlank0()
|
||||||
|
#define gspWaitForVBlank0() gspWaitForEvent(GSPEVENT_VBlank0)
|
||||||
|
#define gspWaitForVBlank1() gspWaitForEvent(GSPEVENT_VBlank1)
|
||||||
|
#define gspWaitForPPF() gspWaitForEvent(GSPEVENT_PPF)
|
||||||
|
#define gspWaitForP3D() gspWaitForEvent(GSPEVENT_P3D)
|
||||||
|
#define gspWaitForDMA() gspWaitForEvent(GSPEVENT_DMA)
|
||||||
|
|
||||||
Result GSPGPU_AcquireRight(Handle *handle, u8 flags);
|
Result GSPGPU_AcquireRight(Handle *handle, u8 flags);
|
||||||
Result GSPGPU_ReleaseRight(Handle *handle);
|
Result GSPGPU_ReleaseRight(Handle *handle);
|
||||||
Result GSPGPU_ImportDisplayCaptureInfo(Handle* handle, GSP_CaptureInfo *captureinfo);
|
Result GSPGPU_ImportDisplayCaptureInfo(Handle* handle, GSP_CaptureInfo *captureinfo);
|
||||||
|
@ -5,7 +5,18 @@
|
|||||||
#include <3ds/svc.h>
|
#include <3ds/svc.h>
|
||||||
#include <3ds/srv.h>
|
#include <3ds/srv.h>
|
||||||
|
|
||||||
|
#define GSP_EVENT_STACK_SIZE 0x1000
|
||||||
|
|
||||||
Handle gspGpuHandle=0;
|
Handle gspGpuHandle=0;
|
||||||
|
Handle gspEvents[GSPEVENT_count];
|
||||||
|
u64 gspEventStack[GSP_EVENT_STACK_SIZE/sizeof(u64)]; //u64 so that it's 8-byte aligned
|
||||||
|
volatile bool gspRunEvents;
|
||||||
|
Handle gspEventThread;
|
||||||
|
|
||||||
|
static Handle gspEvent;
|
||||||
|
static vu8* gspEventData;
|
||||||
|
|
||||||
|
static void gspEventThreadMain(u32 arg);
|
||||||
|
|
||||||
Result gspInit()
|
Result gspInit()
|
||||||
{
|
{
|
||||||
@ -17,6 +28,76 @@ void gspExit()
|
|||||||
if(gspGpuHandle)svcCloseHandle(gspGpuHandle);
|
if(gspGpuHandle)svcCloseHandle(gspGpuHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result gspInitEventHandler(Handle _gspEvent, vu8* _gspSharedMem, u8 gspThreadId)
|
||||||
|
{
|
||||||
|
// Create events
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < GSPEVENT_count; i ++)
|
||||||
|
{
|
||||||
|
Result rc = svcCreateEvent(&gspEvents[i], 0);
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
// Destroy already created events due to failure
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < i; j ++)
|
||||||
|
svcCloseHandle(gspEvents[j]);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start event thread
|
||||||
|
gspEvent = _gspEvent;
|
||||||
|
gspEventData = _gspSharedMem + gspThreadId*0x40;
|
||||||
|
gspRunEvents = true;
|
||||||
|
return svcCreateThread(&gspEventThread, gspEventThreadMain, 0x0, (u32*)((char*)gspEventStack + sizeof(gspEventStack)), 0x31, 0xfffffffe);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gspExitEventHandler()
|
||||||
|
{
|
||||||
|
// Stop event thread
|
||||||
|
gspRunEvents = false;
|
||||||
|
svcWaitSynchronization(gspEventThread, 1000000000);
|
||||||
|
|
||||||
|
// Free events
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < GSPEVENT_count; i ++)
|
||||||
|
svcCloseHandle(gspEvents[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gspWaitForEvent(GSP_Event id)
|
||||||
|
{
|
||||||
|
svcClearEvent(gspEvents[id]);
|
||||||
|
svcWaitSynchronization(gspEvents[id], U64_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gspEventThreadMain(u32 arg)
|
||||||
|
{
|
||||||
|
while (gspRunEvents)
|
||||||
|
{
|
||||||
|
svcWaitSynchronization(gspEvent, U64_MAX);
|
||||||
|
svcClearEvent(gspEvent);
|
||||||
|
|
||||||
|
int count = gspEventData[1];
|
||||||
|
int last = gspEventData[0] + count;
|
||||||
|
while (last >= 0x34) last -= 0x34;
|
||||||
|
int cur = last;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < count; i ++)
|
||||||
|
{
|
||||||
|
int curEvt = gspEventData[0xC + cur];
|
||||||
|
cur --;
|
||||||
|
if (cur < 0) cur += 0x34;
|
||||||
|
if (curEvt >= GSPEVENT_count) continue;
|
||||||
|
svcSignalEvent(gspEvents[curEvt]);
|
||||||
|
}
|
||||||
|
|
||||||
|
gspEventData[0] = last;
|
||||||
|
gspEventData[1] -= count;
|
||||||
|
gspEventData[2] = 0;
|
||||||
|
}
|
||||||
|
svcExitThread();
|
||||||
|
}
|
||||||
|
|
||||||
Result GSPGPU_AcquireRight(Handle* handle, u8 flags)
|
Result GSPGPU_AcquireRight(Handle* handle, u8 flags)
|
||||||
{
|
{
|
||||||
if(!handle)handle=&gspGpuHandle;
|
if(!handle)handle=&gspGpuHandle;
|
||||||
|
Loading…
Reference in New Issue
Block a user