diff --git a/CMakeLists.txt b/CMakeLists.txt
index dd5a4822eb..4694274ce5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -374,6 +374,7 @@ add_library(Common STATIC
Common/StringUtils.h
Common/ThreadPools.cpp
Common/ThreadPools.h
+ Common/ThreadSafeList.h
Common/Timer.cpp
Common/Timer.h)
include_directories(Common)
diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj
index 12214ead77..02df902965 100644
--- a/Common/Common.vcxproj
+++ b/Common/Common.vcxproj
@@ -222,6 +222,7 @@
+
@@ -288,4 +289,4 @@
-
\ No newline at end of file
+
diff --git a/Common/ThreadSafeList.h b/Common/ThreadSafeList.h
new file mode 100644
index 0000000000..5df49b033d
--- /dev/null
+++ b/Common/ThreadSafeList.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2015- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#pragma once
+
+#include
+
+template < typename T, class Alloc = std::allocator >
+class ThreadSafeList {
+public:
+ explicit ThreadSafeList(const Alloc &a = Alloc()) : list(a) {}
+ explicit ThreadSafeList(std::size_t n, const T &v = T(), const Alloc &a = Alloc()) : list(n, v, a) {}
+ ThreadSafeList(const std::list &other) : list(other) {}
+ ThreadSafeList(const ThreadSafeList &other) {
+ lock_guard guard(other.lock);
+ list.assign(other.list);
+ }
+
+ template
+ ThreadSafeList(Iter first, Iter last, const Alloc &a = Alloc()) : list(first, last, a) {}
+
+ inline T front() const {
+ lock_guard guard(lock);
+ return list.front();
+ }
+
+ inline void pop_front() {
+ lock_guard guard(lock);
+ return list.pop_front();
+ }
+
+ inline void push_front(const T &v) {
+ lock_guard guard(lock);
+ return list.push_front(v);
+ }
+
+ inline T back() const {
+ lock_guard guard(lock);
+ return list.back();
+ }
+
+ inline void pop_back() {
+ lock_guard guard(lock);
+ return list.pop_back();
+ }
+
+ inline void push_back(const T &v) {
+ lock_guard guard(lock);
+ return list.push_back(v);
+ }
+
+ bool empty() const {
+ lock_guard guard(lock);
+ return list.empty();
+ }
+
+ inline void clear() {
+ lock_guard guard(lock);
+ return list.clear();
+ }
+
+ void DoState(PointerWrap &p) {
+ lock_guard guard(lock);
+ p.Do(list);
+ }
+
+private:
+ mutable recursive_mutex lock;
+ std::list list;
+};
+
diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp
index 7f9baa0c9f..7770c7a217 100644
--- a/Core/HLE/sceGe.cpp
+++ b/Core/HLE/sceGe.cpp
@@ -20,6 +20,7 @@
#include "base/mutex.h"
#include "Common/ChunkFile.h"
+#include "Common/ThreadSafeList.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/MIPS/MIPS.h"
@@ -36,6 +37,8 @@
#include "GPU/GPUState.h"
#include "GPU/GPUInterface.h"
+static const int LIST_ID_MAGIC = 0x35000000;
+
static PspGeCallbackData ge_callback_data[16];
static bool ge_used_callbacks[16] = {0};
@@ -43,104 +46,35 @@ typedef std::vector WaitingThreadList;
static std::map listWaitingThreads;
static WaitingThreadList drawWaitingThreads;
-struct GeInterruptData
-{
+struct GeInterruptData {
int listid;
u32 pc;
u32 cmd;
};
-template < typename T, class Alloc = std::allocator >
-class ThreadSafeList {
-public:
- explicit ThreadSafeList(const Alloc &a = Alloc()) : list(a) {}
- explicit ThreadSafeList(std::size_t n, const T &v = T(), const Alloc &a = Alloc()) : list(n, v, a) {}
- ThreadSafeList(const std::list &other) : list(other) {}
- ThreadSafeList(const ThreadSafeList &other) {
- lock_guard guard(other.lock);
- list.assign(other.list);
- }
-
- template
- ThreadSafeList(Iter first, Iter last, const Alloc &a = Alloc()) : list(first, last, a) {}
-
- inline T front() const {
- lock_guard guard(lock);
- return list.front();
- }
-
- inline void pop_front() {
- lock_guard guard(lock);
- return list.pop_front();
- }
-
- inline void push_front(const T &v) {
- lock_guard guard(lock);
- return list.push_front(v);
- }
-
- inline T back() const {
- lock_guard guard(lock);
- return list.back();
- }
-
- inline void pop_back() {
- lock_guard guard(lock);
- return list.pop_back();
- }
-
- inline void push_back(const T &v) {
- lock_guard guard(lock);
- return list.push_back(v);
- }
-
- bool empty() const {
- lock_guard guard(lock);
- return list.empty();
- }
-
- inline void clear() {
- lock_guard guard(lock);
- return list.clear();
- }
-
- void DoState(PointerWrap &p) {
- lock_guard guard(lock);
- p.Do(list);
- }
-
-private:
- mutable recursive_mutex lock;
- std::list list;
-};
-
static ThreadSafeList ge_pending_cb;
static int geSyncEvent;
static int geInterruptEvent;
static int geCycleEvent;
-// Let's try updating 10 times per vblank.
+// Let's try updating 10 times per vblank - this is the interval for geCycleEvent.
const int geIntervalUs = 1000000 / (60 * 10);
const int geBehindThresholdUs = 1000000 / (60 * 10);
-class GeIntrHandler : public IntrHandler
-{
+class GeIntrHandler : public IntrHandler {
public:
GeIntrHandler() : IntrHandler(PSP_GE_INTR) {}
- bool run(PendingInterrupt& pend) override
- {
+ bool run(PendingInterrupt& pend) override {
GeInterruptData intrdata = ge_pending_cb.front();
DisplayList* dl = gpu->getList(intrdata.listid);
- if (dl == NULL)
- {
+ if (dl == NULL) {
WARN_LOG(SCEGE, "Unable to run GE interrupt: list doesn't exist: %d", intrdata.listid);
return false;
}
- if (!dl->interruptsEnabled)
- {
+ if (!dl->interruptsEnabled) {
ERROR_LOG_REPORT(SCEGE, "Unable to run GE interrupt: list has interrupts disabled, should not happen");
return false;
}
@@ -149,10 +83,8 @@ public:
const u32 cmd = intrdata.cmd;
int subintr = -1;
- if (dl->subIntrBase >= 0)
- {
- switch (dl->signal)
- {
+ if (dl->subIntrBase >= 0) {
+ switch (dl->signal) {
case PSP_GE_SIGNAL_SYNC:
case PSP_GE_SIGNAL_JUMP:
case PSP_GE_SIGNAL_CALL:
@@ -181,8 +113,7 @@ public:
}
SubIntrHandler* handler = get(subintr);
- if (handler != NULL)
- {
+ if (handler != NULL) {
DEBUG_LOG(CPU, "Entering GE interrupt handler %08x", handler->handlerAddress);
currentMIPS->pc = handler->handlerAddress;
u32 data = dl->subIntrToken;
@@ -211,30 +142,27 @@ public:
return false;
}
- void handleResult(PendingInterrupt& pend) override
- {
+ void handleResult(PendingInterrupt& pend) override {
GeInterruptData intrdata = ge_pending_cb.front();
ge_pending_cb.pop_front();
DisplayList* dl = gpu->getList(intrdata.listid);
- if (!dl->interruptsEnabled)
- {
+ if (!dl->interruptsEnabled) {
ERROR_LOG_REPORT(SCEGE, "Unable to finish GE interrupt: list has interrupts disabled, should not happen");
return;
}
- switch (dl->signal)
- {
+ switch (dl->signal) {
case PSP_GE_SIGNAL_HANDLER_SUSPEND:
- if (sceKernelGetCompiledSdkVersion() <= 0x02000010)
- {
+ if (sceKernelGetCompiledSdkVersion() <= 0x02000010) {
// uofw says dl->state = endCmd & 0xFF;
DisplayListState newState = static_cast(Memory::ReadUnchecked_U32(intrdata.pc - 4) & 0xFF);
//dl->status = static_cast(Memory::ReadUnchecked_U32(intrdata.pc) & 0xFF);
//if(dl->status < 0 || dl->status > PSP_GE_LIST_PAUSED)
// ERROR_LOG(SCEGE, "Weird DL status after signal suspend %x", dl->status);
- if (newState != PSP_GE_DL_STATE_RUNNING)
+ if (newState != PSP_GE_DL_STATE_RUNNING) {
DEBUG_LOG_REPORT(SCEGE, "GE Interrupt: newState might be %d", newState);
+ }
if (dl->state != PSP_GE_DL_STATE_NONE && dl->state != PSP_GE_DL_STATE_COMPLETED) {
dl->state = PSP_GE_DL_STATE_QUEUED;
@@ -249,38 +177,35 @@ public:
}
};
-static void __GeExecuteSync(u64 userdata, int cyclesLate)
-{
+static void __GeExecuteSync(u64 userdata, int cyclesLate) {
int listid = userdata >> 32;
GPUSyncType type = (GPUSyncType) (userdata & 0xFFFFFFFF);
bool wokeThreads = __GeTriggerWait(type, listid);
gpu->SyncEnd(type, listid, wokeThreads);
}
-static void __GeExecuteInterrupt(u64 userdata, int cyclesLate)
-{
+static void __GeExecuteInterrupt(u64 userdata, int cyclesLate) {
__TriggerInterrupt(PSP_INTR_IMMEDIATE, PSP_GE_INTR, PSP_INTR_SUB_NONE);
}
-static void __GeCheckCycles(u64 userdata, int cyclesLate)
-{
+static void __GeCheckCycles(u64 userdata, int cyclesLate) {
u64 geTicks = gpu->GetTickEstimate();
- if (geTicks != 0)
- {
+ if (geTicks != 0) {
if (CoreTiming::GetTicks() > geTicks + usToCycles(geBehindThresholdUs)) {
u64 diff = CoreTiming::GetTicks() - geTicks;
+ // Let the GPU thread catch up.
gpu->SyncThread();
CoreTiming::Advance();
}
}
- // This may get out of step if we synced, but that's okay.
+ // This may get out of step if we synced (why?), but that's okay.
CoreTiming::ScheduleEvent(usToCycles(geIntervalUs), geCycleEvent, 0);
}
-void __GeInit()
-{
+void __GeInit() {
memset(&ge_used_callbacks, 0, sizeof(ge_used_callbacks));
+ memset(&ge_callback_data, 0, sizeof(ge_callback_data));
ge_pending_cb.clear();
__RegisterIntrHandler(PSP_GE_INTR, new GeIntrHandler());
@@ -297,14 +222,12 @@ void __GeInit()
}
}
-struct GeInterruptData_v1
-{
+struct GeInterruptData_v1 {
int listid;
u32 pc;
};
-void __GeDoState(PointerWrap &p)
-{
+void __GeDoState(PointerWrap &p) {
auto s = p.Section("sceGe", 1, 2);
if (!s)
return;
@@ -338,18 +261,14 @@ void __GeDoState(PointerWrap &p)
// Everything else is done in sceDisplay.
}
-void __GeShutdown()
-{
-
+void __GeShutdown() {
}
-// Warning: may be called from the GPU thread.
-bool __GeTriggerSync(GPUSyncType type, int id, u64 atTicks)
-{
- u64 userdata = (u64)id << 32 | (u64) type;
+// Warning: may be called asynchronously from the GPU thread.
+bool __GeTriggerSync(GPUSyncType type, int id, u64 atTicks) {
+ u64 userdata = (u64)id << 32 | (u64)type;
s64 future = atTicks - CoreTiming::GetTicks();
- if (type == GPU_SYNC_DRAW)
- {
+ if (type == GPU_SYNC_DRAW) {
s64 left = CoreTiming::UnscheduleThreadsafeEvent(geSyncEvent, userdata);
if (left > future)
future = left;
@@ -358,9 +277,8 @@ bool __GeTriggerSync(GPUSyncType type, int id, u64 atTicks)
return true;
}
-// Warning: may be called from the GPU thread.
-bool __GeTriggerInterrupt(int listid, u32 pc, u64 atTicks)
-{
+// Warning: may be called asynchronously from the GPU thread.
+bool __GeTriggerInterrupt(int listid, u32 pc, u64 atTicks) {
GeInterruptData intrdata;
intrdata.listid = listid;
intrdata.pc = pc;
@@ -373,8 +291,7 @@ bool __GeTriggerInterrupt(int listid, u32 pc, u64 atTicks)
return true;
}
-void __GeWaitCurrentThread(GPUSyncType type, SceUID waitId, const char *reason)
-{
+void __GeWaitCurrentThread(GPUSyncType type, SceUID waitId, const char *reason) {
WaitType waitType;
if (type == GPU_SYNC_DRAW) {
drawWaitingThreads.push_back(__KernelGetCurThread());
@@ -390,8 +307,7 @@ void __GeWaitCurrentThread(GPUSyncType type, SceUID waitId, const char *reason)
__KernelWaitCurThread(waitType, waitId, 0, 0, false, reason);
}
-static bool __GeTriggerWait(WaitType waitType, SceUID waitId, WaitingThreadList &waitingThreads)
-{
+static bool __GeTriggerWait(WaitType waitType, SceUID waitId, WaitingThreadList &waitingThreads) {
// TODO: Do they ever get a result other than 0?
bool wokeThreads = false;
for (auto it = waitingThreads.begin(), end = waitingThreads.end(); it != end; ++it)
@@ -400,8 +316,7 @@ static bool __GeTriggerWait(WaitType waitType, SceUID waitId, WaitingThreadList
return wokeThreads;
}
-bool __GeTriggerWait(GPUSyncType type, SceUID waitId)
-{
+bool __GeTriggerWait(GPUSyncType type, SceUID waitId) {
// We check for the old type for old savestate compatibility.
if (type == GPU_SYNC_DRAW || (WaitType)type == WAITTYPE_GEDRAWSYNC)
return __GeTriggerWait(WAITTYPE_GEDRAWSYNC, waitId, drawWaitingThreads);
@@ -412,29 +327,25 @@ bool __GeTriggerWait(GPUSyncType type, SceUID waitId)
return false;
}
-static u32 sceGeEdramGetAddr()
-{
+static u32 sceGeEdramGetAddr() {
u32 retVal = 0x04000000;
DEBUG_LOG(SCEGE, "%08x = sceGeEdramGetAddr", retVal);
hleEatCycles(150);
return retVal;
}
-static u32 sceGeEdramGetSize()
-{
- u32 retVal = 0x00200000;
+// TODO: Return a different value for the PS3 enhanced-emulator games?
+static u32 sceGeEdramGetSize() {
+ const u32 retVal = 0x00200000;
DEBUG_LOG(SCEGE, "%08x = sceGeEdramGetSize()", retVal);
return retVal;
}
-static int __GeSubIntrBase(int callbackId)
-{
+static int __GeSubIntrBase(int callbackId) {
return callbackId * 2;
}
-u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId,
- u32 optParamAddr)
-{
+u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr) {
DEBUG_LOG(SCEGE,
"sceGeListEnQueue(addr=%08x, stall=%08x, cbid=%08x, param=%08x)",
listAddress, stallAddress, callbackId, optParamAddr);
@@ -442,7 +353,7 @@ u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId,
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, false);
if ((int)listID >= 0)
- listID = 0x35000000 ^ listID;
+ listID = LIST_ID_MAGIC ^ listID;
DEBUG_LOG(SCEGE, "List %i enqueued.", listID);
hleEatCycles(490);
@@ -450,9 +361,7 @@ u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId,
return listID;
}
-u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId,
- u32 optParamAddr)
-{
+u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr) {
DEBUG_LOG(SCEGE,
"sceGeListEnQueueHead(addr=%08x, stall=%08x, cbid=%08x, param=%08x)",
listAddress, stallAddress, callbackId, optParamAddr);
@@ -460,48 +369,44 @@ u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId,
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, true);
if ((int)listID >= 0)
- listID = 0x35000000 ^ listID;
+ listID = LIST_ID_MAGIC ^ listID;
- DEBUG_LOG(SCEGE, "List %i enqueued.", listID);
+ DEBUG_LOG(SCEGE, "List %i enqueued at head.", listID);
hleEatCycles(480);
CoreTiming::ForceCheck();
return listID;
}
-static int sceGeListDeQueue(u32 listID)
-{
+static int sceGeListDeQueue(u32 listID) {
WARN_LOG(SCEGE, "sceGeListDeQueue(%08x)", listID);
- int result = gpu->DequeueList(0x35000000 ^ listID);
+ int result = gpu->DequeueList(LIST_ID_MAGIC ^ listID);
hleReSchedule("dlist dequeued");
return result;
}
-static int sceGeListUpdateStallAddr(u32 displayListID, u32 stallAddress)
-{
+static int sceGeListUpdateStallAddr(u32 displayListID, u32 stallAddress) {
// Advance() might cause an interrupt, so defer the Advance but do it ASAP.
// Final Fantasy Type-0 has a graphical artifact without this (timing issue.)
hleEatCycles(190);
CoreTiming::ForceCheck();
DEBUG_LOG(SCEGE, "sceGeListUpdateStallAddr(dlid=%i, stalladdr=%08x)", displayListID, stallAddress);
- return gpu->UpdateStall(0x35000000 ^ displayListID, stallAddress);
+ return gpu->UpdateStall(LIST_ID_MAGIC ^ displayListID, stallAddress);
}
-int sceGeListSync(u32 displayListID, u32 mode) //0 : wait for completion 1:check and return
-{
+// 0 : wait for completion. 1:check and return
+int sceGeListSync(u32 displayListID, u32 mode) {
DEBUG_LOG(SCEGE, "sceGeListSync(dlid=%08x, mode=%08x)", displayListID, mode);
- return gpu->ListSync(0x35000000 ^ displayListID, mode);
+ return gpu->ListSync(LIST_ID_MAGIC ^ displayListID, mode);
}
-static u32 sceGeDrawSync(u32 mode)
-{
+static u32 sceGeDrawSync(u32 mode) {
//wait/check entire drawing state
DEBUG_LOG(SCEGE, "sceGeDrawSync(mode=%d) (0=wait for completion, 1=peek)", mode);
return gpu->DrawSync(mode);
}
-int sceGeContinue()
-{
+int sceGeContinue() {
DEBUG_LOG(SCEGE, "sceGeContinue");
int ret = gpu->Continue();
hleEatCycles(220);
@@ -509,44 +414,40 @@ int sceGeContinue()
return ret;
}
-static int sceGeBreak(u32 mode, u32 unknownPtr)
-{
- if (mode > 1)
- {
+static int sceGeBreak(u32 mode, u32 unknownPtr) {
+ if (mode > 1) {
WARN_LOG(SCEGE, "sceGeBreak(mode=%d, unknown=%08x): invalid mode", mode, unknownPtr);
return SCE_KERNEL_ERROR_INVALID_MODE;
}
// Not sure what this is supposed to be for...
- if ((int)unknownPtr < 0 || (int)unknownPtr + 16 < 0)
- {
+ if ((int)unknownPtr < 0 || (int)unknownPtr + 16 < 0) {
WARN_LOG_REPORT(SCEGE, "sceGeBreak(mode=%d, unknown=%08x): invalid ptr", mode, unknownPtr);
return SCE_KERNEL_ERROR_PRIV_REQUIRED;
- }
- else if (unknownPtr != 0)
+ } else if (unknownPtr != 0) {
WARN_LOG_REPORT(SCEGE, "sceGeBreak(mode=%d, unknown=%08x): unknown ptr (%s)", mode, unknownPtr, Memory::IsValidAddress(unknownPtr) ? "valid" : "invalid");
+ }
//mode => 0 : current dlist 1: all drawing
DEBUG_LOG(SCEGE, "sceGeBreak(mode=%d, unknown=%08x)", mode, unknownPtr);
int result = gpu->Break(mode);
- if (result >= 0 && mode == 0)
- return 0x35000000 ^ result;
+ if (result >= 0 && mode == 0) {
+ return LIST_ID_MAGIC ^ result;
+ }
return result;
}
-static u32 sceGeSetCallback(u32 structAddr)
-{
+static u32 sceGeSetCallback(u32 structAddr) {
DEBUG_LOG(SCEGE, "sceGeSetCallback(struct=%08x)", structAddr);
int cbID = -1;
- for (size_t i = 0; i < ARRAY_SIZE(ge_used_callbacks); ++i)
- if (!ge_used_callbacks[i])
- {
+ for (size_t i = 0; i < ARRAY_SIZE(ge_used_callbacks); ++i) {
+ if (!ge_used_callbacks[i]) {
cbID = (int) i;
break;
}
+ }
- if (cbID == -1)
- {
+ if (cbID == -1) {
WARN_LOG(SCEGE, "sceGeSetCallback(): out of callback ids");
return SCE_KERNEL_ERROR_OUT_OF_MEMORY;
}
@@ -556,14 +457,12 @@ static u32 sceGeSetCallback(u32 structAddr)
int subIntrBase = __GeSubIntrBase(cbID);
- if (ge_callback_data[cbID].finish_func != 0)
- {
+ if (ge_callback_data[cbID].finish_func != 0) {
sceKernelRegisterSubIntrHandler(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH,
ge_callback_data[cbID].finish_func, ge_callback_data[cbID].finish_arg);
sceKernelEnableSubIntr(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH);
}
- if (ge_callback_data[cbID].signal_func != 0)
- {
+ if (ge_callback_data[cbID].signal_func != 0) {
sceKernelRegisterSubIntrHandler(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL,
ge_callback_data[cbID].signal_func, ge_callback_data[cbID].signal_arg);
sceKernelEnableSubIntr(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL);
@@ -572,48 +471,41 @@ static u32 sceGeSetCallback(u32 structAddr)
return cbID;
}
-static int sceGeUnsetCallback(u32 cbID)
-{
+static int sceGeUnsetCallback(u32 cbID) {
DEBUG_LOG(SCEGE, "sceGeUnsetCallback(cbid=%08x)", cbID);
- if (cbID >= ARRAY_SIZE(ge_used_callbacks))
- {
+ if (cbID >= ARRAY_SIZE(ge_used_callbacks)) {
WARN_LOG(SCEGE, "sceGeUnsetCallback(cbid=%08x): invalid callback id", cbID);
return SCE_KERNEL_ERROR_INVALID_ID;
}
- if (ge_used_callbacks[cbID])
- {
+ if (ge_used_callbacks[cbID]) {
int subIntrBase = __GeSubIntrBase(cbID);
sceKernelReleaseSubIntrHandler(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_FINISH);
sceKernelReleaseSubIntrHandler(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL);
- }
- else
+ } else {
WARN_LOG(SCEGE, "sceGeUnsetCallback(cbid=%08x): ignoring unregistered callback id", cbID);
+ }
ge_used_callbacks[cbID] = false;
-
return 0;
}
// Points to 512 32-bit words, where we can probably layout the context however we want
// unless some insane game pokes it and relies on it...
-u32 sceGeSaveContext(u32 ctxAddr)
-{
+u32 sceGeSaveContext(u32 ctxAddr) {
DEBUG_LOG(SCEGE, "sceGeSaveContext(%08x)", ctxAddr);
gpu->SyncThread();
- if (gpu->BusyDrawing())
- {
+ if (gpu->BusyDrawing()) {
WARN_LOG(SCEGE, "sceGeSaveContext(%08x): lists in process, aborting", ctxAddr);
// Real error code.
return -1;
}
// Let's just dump gstate.
- if (Memory::IsValidAddress(ctxAddr))
- {
+ if (Memory::IsValidAddress(ctxAddr)) {
gstate.Save((u32_le *)Memory::GetPointer(ctxAddr));
}
@@ -622,23 +514,20 @@ u32 sceGeSaveContext(u32 ctxAddr)
return 0;
}
-u32 sceGeRestoreContext(u32 ctxAddr)
-{
+u32 sceGeRestoreContext(u32 ctxAddr) {
DEBUG_LOG(SCEGE, "sceGeRestoreContext(%08x)", ctxAddr);
gpu->SyncThread();
- if (gpu->BusyDrawing())
- {
+ if (gpu->BusyDrawing()) {
WARN_LOG(SCEGE, "sceGeRestoreContext(%08x): lists in process, aborting", ctxAddr);
return SCE_KERNEL_ERROR_BUSY;
}
- if (Memory::IsValidAddress(ctxAddr))
- {
+ if (Memory::IsValidAddress(ctxAddr)) {
gstate.Restore((u32_le *)Memory::GetPointer(ctxAddr));
}
- ReapplyGfxState();
+ ReapplyGfxState();
return 0;
}
@@ -710,14 +599,15 @@ static u32 sceGeEdramSetAddrTranslation(int new_size) {
}
DEBUG_LOG(SCEGE, "sceGeEdramSetAddrTranslation(%i)", new_size);
+
+ // TODO: This isn't safe. EDRamWidth should be global and saved.
static int EDRamWidth = 0x400;
int last = EDRamWidth;
EDRamWidth = new_size;
return last;
}
-const HLEFunction sceGe_user[] =
-{
+const HLEFunction sceGe_user[] = {
{0XE47E40E4, &WrapU_V, "sceGeEdramGetAddr", 'x', "" },
{0XAB49E76A, &WrapU_UUIU, "sceGeListEnQueue", 'x', "xxix"},
{0X1C0D95A6, &WrapU_UUIU, "sceGeListEnQueueHead", 'x', "xxix"},
@@ -738,7 +628,6 @@ const HLEFunction sceGe_user[] =
{0XE66CB92E, &WrapI_IU, "sceGeGetStack", 'i', "ix" },
};
-void Register_sceGe_user()
-{
+void Register_sceGe_user() {
RegisterModule("sceGe_user", ARRAY_SIZE(sceGe_user), sceGe_user);
}
diff --git a/Qt/Common.pro b/Qt/Common.pro
index 2bea1516b8..ec3b4a8d0e 100644
--- a/Qt/Common.pro
+++ b/Qt/Common.pro
@@ -67,6 +67,7 @@ HEADERS += $$P/Common/ChunkFile.h \
$$P/Common/MsgHandler.h \
$$P/Common/StringUtils.h \
$$P/Common/ThreadPools.h \
+ $$P/Common/ThreadSafeList.h \
$$P/Common/Timer.h \
$$P/Common/Crypto/*.h