From 2ecbb9d8b8dce32c537d79d14486b0afc82c97d5 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Thu, 8 May 2025 17:52:07 +0200 Subject: [PATCH 1/2] Fixing remaining magic numbers --- src/display/pspdisplay.h | 11 +++-- src/gu/Makefile.am | 1 + src/gu/guInternal.h | 2 +- src/gu/pspgu.h | 8 ++-- src/gu/resetValues.c | 4 +- src/gu/sceGuColor.c | 2 +- src/gu/sceGuDisable.c | 2 +- src/gu/sceGuDispBuffer.c | 2 +- src/gu/sceGuDisplay.c | 6 +-- src/gu/sceGuEnable.c | 2 +- src/gu/sceGuFinish.c | 36 ----------------- src/gu/sceGuFinishId.c | 45 +++++++++++++++++++++ src/gu/sceGuInit.c | 60 +++++++++++++++++++--------- src/gu/sceGuSendList.c | 17 ++++---- src/gu/sceGuSetCallback.c | 21 ++++------ src/gu/sceGuShadeModel.c | 2 +- src/gu/sceGuSync.c | 14 +++++-- src/samples/prx/image_display/main.c | 4 +- src/user/pspthreadman.h | 2 + 19 files changed, 143 insertions(+), 98 deletions(-) create mode 100644 src/gu/sceGuFinishId.c diff --git a/src/display/pspdisplay.h b/src/display/pspdisplay.h index c72ca31d..2e31f08e 100644 --- a/src/display/pspdisplay.h +++ b/src/display/pspdisplay.h @@ -31,12 +31,15 @@ enum PspDisplayPixelFormats { }; enum PspDisplaySetBufSync { - /** Buffer change effective immediately */ - PSP_DISPLAY_SETBUF_IMMEDIATE = 0, - /** Buffer change effective next frame */ - PSP_DISPLAY_SETBUF_NEXTFRAME = 1 + /** Buffer change effective next hsync */ + PSP_DISPLAY_SETBUF_NEXTHSYNC = 0, + /** Buffer change effective next vsync */ + PSP_DISPLAY_SETBUF_NEXTVSYNC = 1 }; +/** Values for retro compatibility */ +#define PSP_DISPLAY_SETBUF_IMMEDIATE PSP_DISPLAY_SETBUF_NEXTHSYNC +#define PSP_DISPLAY_SETBUF_NEXTFRAME PSP_DISPLAY_SETBUF_NEXTVSYNC enum PspDisplayErrorCodes { diff --git a/src/gu/Makefile.am b/src/gu/Makefile.am index c0cb0145..1a44d0cb 100644 --- a/src/gu/Makefile.am +++ b/src/gu/Makefile.am @@ -57,6 +57,7 @@ libpspgu_a_SOURCES = \ sceGuEnable.c \ sceGuEndObject.c \ sceGuFinish.c \ + sceGuFinishId.c \ sceGuFog.c \ sceGuFrontFace.c \ sceGuGetAllStatus.c \ diff --git a/src/gu/guInternal.h b/src/gu/guInternal.h index 8c3b5eb2..12841a68 100644 --- a/src/gu/guInternal.h +++ b/src/gu/guInternal.h @@ -116,7 +116,7 @@ extern GuLightSettings light_settings[4]; void callbackSig(int id, void *arg); void callbackFin(int id, void *arg); -void resetValues(); +void _sceGuResetGlobalVariables(); typedef enum GECommand { diff --git a/src/gu/pspgu.h b/src/gu/pspgu.h index c5f246fb..c7e1d0d3 100644 --- a/src/gu/pspgu.h +++ b/src/gu/pspgu.h @@ -433,8 +433,10 @@ void sceGuFog(float near, float far, unsigned int color); * Initalize the GU system * * This function MUST be called as the first function, otherwise state is undetermined. + * + * @return 0 for success, < 0 for failure **/ -void sceGuInit(void); +int sceGuInit(void); /** * Shutdown the GU system @@ -1525,8 +1527,8 @@ void sceGuDrawArrayN(int primitive_type, int vertex_type, int vcount, int primco * Set how the display should be set * * Available behaviours are: - * - PSP_DISPLAY_SETBUF_IMMEDIATE - Display is swapped immediately - * - PSP_DISPLAY_SETBUF_NEXTFRAME - Display is swapped on the next frame + * - PSP_DISPLAY_SETBUF_NEXTHSYNC - Display is swapped on the next hsync + * - PSP_DISPLAY_SETBUF_NEXTVSYNC - Display is swapped on the next vsync * * Do remember that this swaps the pointers internally, regardless of setting, so be careful to wait until the next * vertical blank or use another buffering algorithm (see guSwapBuffersCallback()). diff --git a/src/gu/resetValues.c b/src/gu/resetValues.c index 2b039533..4fed2744 100644 --- a/src/gu/resetValues.c +++ b/src/gu/resetValues.c @@ -8,7 +8,7 @@ #include "guInternal.h" -void resetValues() +void _sceGuResetGlobalVariables() { unsigned int i; @@ -18,7 +18,7 @@ void resetValues() gu_current_frame = 0; gu_object_stack_depth = 0; - gu_display_on = 0; + gu_display_on = GU_FALSE; gu_call_mode = GU_CALL_NORMAL; gu_draw_buffer.pixel_size = 1; diff --git a/src/gu/sceGuColor.c b/src/gu/sceGuColor.c index 4ccc4549..946bd39e 100644 --- a/src/gu/sceGuColor.c +++ b/src/gu/sceGuColor.c @@ -10,5 +10,5 @@ void sceGuColor(unsigned int color) { - sceGuMaterial(7,color); + sceGuMaterial(GU_AMBIENT | GU_DIFFUSE | GU_SPECULAR, color); } diff --git a/src/gu/sceGuDisable.c b/src/gu/sceGuDisable.c index 461fbf5b..8b05eaad 100644 --- a/src/gu/sceGuDisable.c +++ b/src/gu/sceGuDisable.c @@ -89,6 +89,6 @@ void sceGuDisable(int state) break; } - if (state < 22) + if (state < GU_MAX_STATUS) gu_states &= ~(1 << state); } diff --git a/src/gu/sceGuDispBuffer.c b/src/gu/sceGuDispBuffer.c index 0436522e..807c1d41 100644 --- a/src/gu/sceGuDispBuffer.c +++ b/src/gu/sceGuDispBuffer.c @@ -30,5 +30,5 @@ void sceGuDispBuffer(int width, int height, void *dispbp, int dispbw) sceDisplaySetMode(0, gu_draw_buffer.width, gu_draw_buffer.height); if (gu_display_on) - sceDisplaySetFrameBuf((void *)(((unsigned int)ge_edram_address) + ((unsigned int)gu_draw_buffer.disp_buffer)), dispbw, gu_draw_buffer.pixel_size, PSP_DISPLAY_SETBUF_NEXTFRAME); + sceDisplaySetFrameBuf((void *)(((unsigned int)ge_edram_address) + ((unsigned int)gu_draw_buffer.disp_buffer)), dispbw, gu_draw_buffer.pixel_size, PSP_DISPLAY_SETBUF_NEXTVSYNC); } diff --git a/src/gu/sceGuDisplay.c b/src/gu/sceGuDisplay.c index 6006c524..90987c4e 100644 --- a/src/gu/sceGuDisplay.c +++ b/src/gu/sceGuDisplay.c @@ -13,10 +13,10 @@ int sceGuDisplay(int state) { - if (state) - sceDisplaySetFrameBuf((void*)((unsigned int)ge_edram_address+(unsigned int)gu_draw_buffer.disp_buffer),gu_draw_buffer.frame_width,gu_draw_buffer.pixel_size,PSP_DISPLAY_SETBUF_NEXTFRAME); + if (state == GU_TRUE) + sceDisplaySetFrameBuf((void *)((unsigned int)ge_edram_address + (unsigned int)gu_draw_buffer.disp_buffer), gu_draw_buffer.frame_width, gu_draw_buffer.pixel_size, PSP_DISPLAY_SETBUF_NEXTVSYNC); else - sceDisplaySetFrameBuf(0,0,0,PSP_DISPLAY_SETBUF_NEXTFRAME); + sceDisplaySetFrameBuf(NULL, 0, 0, PSP_DISPLAY_SETBUF_NEXTVSYNC); gu_display_on = state; return state; diff --git a/src/gu/sceGuEnable.c b/src/gu/sceGuEnable.c index ad6d38de..770752b3 100644 --- a/src/gu/sceGuEnable.c +++ b/src/gu/sceGuEnable.c @@ -89,6 +89,6 @@ void sceGuEnable(int state) break; } - if (state < 22) + if (state < GU_MAX_STATUS) gu_states |= (1 << state); } diff --git a/src/gu/sceGuFinish.c b/src/gu/sceGuFinish.c index 9f68aadd..ad03b7f1 100644 --- a/src/gu/sceGuFinish.c +++ b/src/gu/sceGuFinish.c @@ -8,42 +8,6 @@ #include "guInternal.h" -int sceGuFinishId(unsigned int id) -{ - switch (gu_curr_context) - { - case GU_DIRECT: - case GU_SEND: - { - sendCommandi(FINISH, id & 0xffff); - sendCommandiStall(END, 0); - } - break; - - case GU_CALL: - { - if (gu_call_mode == GU_CALL_SIGNAL) - { - sendCommandi(SIGNAL, 0x120000); - sendCommandi(END, 0); - sendCommandiStall(NOP, 0); - } - else - { - sendCommandi(RET, 0); - } - } - break; - } - - unsigned int size = ((unsigned int)gu_list->current) - ((unsigned int)gu_list->start); - - // go to parent list - gu_curr_context = gu_list->parent_context; - gu_list = &gu_contexts[gu_curr_context].list; - return size; -} - int sceGuFinish(void) { return sceGuFinishId(0); diff --git a/src/gu/sceGuFinishId.c b/src/gu/sceGuFinishId.c new file mode 100644 index 00000000..a228b734 --- /dev/null +++ b/src/gu/sceGuFinishId.c @@ -0,0 +1,45 @@ +/* + * PSP Software Development Kit - https://github.com/pspdev + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * Copyright (c) 2005 Jesper Svennevid + */ + +#include "guInternal.h" + +int sceGuFinishId(unsigned int id) +{ + switch (gu_curr_context) + { + case GU_DIRECT: + case GU_SEND: + { + sendCommandi(FINISH, id & 0xffff); + sendCommandiStall(END, 0); + } + break; + + case GU_CALL: + { + if (gu_call_mode == GU_CALL_SIGNAL) + { + sendCommandi(SIGNAL, 0x120000); + sendCommandi(END, 0); + sendCommandiStall(NOP, 0); + } + else + { + sendCommandi(RET, 0); + } + } + break; + } + + unsigned int size = ((unsigned int)gu_list->current) - ((unsigned int)gu_list->start); + + // go to parent list + gu_curr_context = gu_list->parent_context; + gu_list = &gu_contexts[gu_curr_context].list; + return size; +} \ No newline at end of file diff --git a/src/gu/sceGuInit.c b/src/gu/sceGuInit.c index 46a428f8..048de45a 100644 --- a/src/gu/sceGuInit.c +++ b/src/gu/sceGuInit.c @@ -235,46 +235,70 @@ static unsigned int __attribute__((aligned(16))) ge_init_list[] = ZV(END), }; -void callbackFin(int id, void* arg) +void callbackFin(int id, void *arg) { - GuSettings* settings = (GuSettings*)arg; + GuSettings *settings = (GuSettings *)arg; if (settings->fin) settings->fin(id & 0xffff); } -void callbackSig(int id, void* arg) +void callbackSig(int id, void *arg) { - GuSettings* settings = (GuSettings*)arg; + GuSettings *settings = (GuSettings *)arg; settings->signal_history[(settings->signal_offset++) & 15] = id & 0xffff; if (settings->sig) settings->sig(id & 0xffff); - sceKernelSetEventFlag(settings->kernel_event_flag,1); + sceKernelSetEventFlag(settings->kernel_event_flag, 1); } -void sceGuInit(void) +int sceGuInit(void) { + int res; PspGeCallbackData callback; + + ge_edram_address = sceGeEdramGetAddr(); + _sceGuResetGlobalVariables(); + + res = sceKernelCreateEventFlag("SceGuSignal", PSP_EVENT_WAITMULTIPLE, 3, 0); + if (res < 0) + { + return res; + } + gu_settings.kernel_event_flag = res; + callback.signal_func = callbackSig; callback.signal_arg = &gu_settings; callback.finish_func = callbackFin; callback.finish_arg = &gu_settings; - gu_settings.ge_callback_id = sceGeSetCallback(&callback); - - gu_settings.swapBuffersCallback = 0; - gu_settings.swapBuffersBehaviour = PSP_DISPLAY_SETBUF_IMMEDIATE; - - ge_edram_address = sceGeEdramGetAddr(); + res = sceGeSetCallback(&callback); + if (res < 0) + { + sceKernelDeleteEventFlag(gu_settings.kernel_event_flag); + gu_settings.kernel_event_flag = -1; + return res; + } + gu_settings.ge_callback_id = res; // initialize graphics hardware - ge_list_executed[0] = sceGeListEnQueue((void *)((unsigned int)ge_init_list & 0x1fffffff), 0, gu_settings.ge_callback_id, 0); - - resetValues(); - - gu_settings.kernel_event_flag = sceKernelCreateEventFlag("SceGuSignal", 512, 3, 0); - + res = sceGeListEnQueue((void *)((unsigned int)ge_init_list & 0x1fffffff), 0, gu_settings.ge_callback_id, 0); + if (res < 0) + { + sceKernelDeleteEventFlag(gu_settings.kernel_event_flag); + sceGeUnsetCallback(gu_settings.ge_callback_id); + gu_settings.ge_callback_id = -1; + gu_settings.kernel_event_flag = -1; + return res; + } + ge_list_executed[0] = res; // wait for init to complete sceGeListSync(ge_list_executed[0], 0); + sceGeDrawSync(0); + + gu_settings.swapBuffersCallback = NULL; + gu_settings.swapBuffersBehaviour = PSP_DISPLAY_SETBUF_NEXTHSYNC; + + return 0; } diff --git a/src/gu/sceGuSendList.c b/src/gu/sceGuSendList.c index 41ad460e..71b781b5 100644 --- a/src/gu/sceGuSendList.c +++ b/src/gu/sceGuSendList.c @@ -13,15 +13,18 @@ int sceGuSendList(int mode, const void *list, PspGeContext *context) { - gu_settings.signal_offset = 0; - - // TODO: figure out this structure PspGeListArgs args; - args.size = 8; // Size of structure? - args.context = context; + int list_id; + int callback; - int list_id = 0; - int callback = gu_settings.ge_callback_id; + args.size = sizeof(PspGeListArgs); + args.context = context; + args.numStacks = 0; + args.stacks = NULL; + + callback = gu_settings.ge_callback_id; + gu_settings.signal_offset = 0; + list_id = -1; switch (mode) { diff --git a/src/gu/sceGuSetCallback.c b/src/gu/sceGuSetCallback.c index e101a46e..e75607ab 100644 --- a/src/gu/sceGuSetCallback.c +++ b/src/gu/sceGuSetCallback.c @@ -8,24 +8,19 @@ #include "guInternal.h" -void* sceGuSetCallback(int signal, GuCallback callback) +void *sceGuSetCallback(int signal, GuCallback callback) { - GuCallback old_callback = 0; + GuCallback old_callback = NULL; switch (signal) { - case GU_CALLBACK_SIGNAL: - { - old_callback = gu_settings.sig; - gu_settings.sig = callback; - } + case GU_CALLBACK_SIGNAL: + old_callback = gu_settings.sig; + gu_settings.sig = callback; break; - - case GU_CALLBACK_FINISH: - { - old_callback = gu_settings.fin; - gu_settings.fin = callback; - } + case GU_CALLBACK_FINISH: + old_callback = gu_settings.fin; + gu_settings.fin = callback; break; } diff --git a/src/gu/sceGuShadeModel.c b/src/gu/sceGuShadeModel.c index 35808603..faef3007 100644 --- a/src/gu/sceGuShadeModel.c +++ b/src/gu/sceGuShadeModel.c @@ -10,5 +10,5 @@ void sceGuShadeModel(int mode) { - sendCommandi(SHADE_MODE, mode ? 1 : 0); + sendCommandi(SHADE_MODE, mode); } diff --git a/src/gu/sceGuSync.c b/src/gu/sceGuSync.c index ffd77acd..d23a753f 100644 --- a/src/gu/sceGuSync.c +++ b/src/gu/sceGuSync.c @@ -15,9 +15,15 @@ int sceGuSync(int mode, int what) { switch (mode) { - case GU_SYNC_FINISH: return sceGeDrawSync(what); - case GU_SYNC_LIST: return sceGeListSync(ge_list_executed[0],what); - case GU_SYNC_SEND: return sceGeListSync(ge_list_executed[1],what); - default: case GU_SYNC_SIGNAL: case GU_SYNC_DONE: return 0; + case GU_SYNC_FINISH: + return sceGeDrawSync(what); + case GU_SYNC_LIST: + return sceGeListSync(ge_list_executed[0], what); + case GU_SYNC_SEND: + return sceGeListSync(ge_list_executed[1], what); + default: + case GU_SYNC_SIGNAL: + case GU_SYNC_DONE: + return 0; } } diff --git a/src/samples/prx/image_display/main.c b/src/samples/prx/image_display/main.c index 82aedf6b..260bfe3b 100644 --- a/src/samples/prx/image_display/main.c +++ b/src/samples/prx/image_display/main.c @@ -129,8 +129,8 @@ int main_thread(SceSize args, void *argp){ // get vram - int ret = sceDisplayGetFrameBuf((void*)&vram32, &bufferwidth, &pixelformat, PSP_DISPLAY_SETBUF_IMMEDIATE); - // works with both PSP_DISPLAY_SETBUF_NEXTFRAME and PSP_DISPLAY_SETBUF_IMMEDIATE + int ret = sceDisplayGetFrameBuf((void*)&vram32, &bufferwidth, &pixelformat, PSP_DISPLAY_SETBUF_NEXTHSYNC); + // works with both PSP_DISPLAY_SETBUF_NEXTVSYNC and PSP_DISPLAY_SETBUF_NEXTHSYNC // check if return value from sceDisplayGetFrameBuf is valid // check if vram32 is not NULL diff --git a/src/user/pspthreadman.h b/src/user/pspthreadman.h index 8fe7b350..60ff9126 100644 --- a/src/user/pspthreadman.h +++ b/src/user/pspthreadman.h @@ -690,6 +690,8 @@ typedef struct SceKernelEventFlagOptParam SceKernelEventFlagOptParam; /** Event flag creation attributes */ enum PspEventFlagAttributes { + /** Allow the event flag to be waited upon by a single thread */ + PSP_EVENT_WAITSINGLE = 0x00, /** Allow the event flag to be waited upon by multiple threads */ PSP_EVENT_WAITMULTIPLE = 0x200 }; From 4743678478f7f8aadd12e7cea0365036fd52513e Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Fri, 9 May 2025 21:47:55 +0200 Subject: [PATCH 2/2] Improvements around STALL --- src/gu/guInternal.h | 18 ++++++++++++------ src/gu/pspgu.h | 8 +++++++- src/gu/sceGuCallList.c | 12 +++++++++--- src/gu/sceGuDrawArray.c | 3 ++- src/gu/sceGuDrawArrayN.c | 4 ++-- src/gu/sceGuFinishId.c | 31 +++++++++++++++++++++---------- src/gu/sceGuInit.c | 2 +- src/gu/sceGuSignal.c | 6 +++--- src/gu/sceGuStart.c | 7 ++++++- 9 files changed, 63 insertions(+), 28 deletions(-) diff --git a/src/gu/guInternal.h b/src/gu/guInternal.h index 12841a68..0b214dd9 100644 --- a/src/gu/guInternal.h +++ b/src/gu/guInternal.h @@ -645,12 +645,18 @@ static inline void sendCommandf(GECommand cmd, float argument) sendCommandi(cmd, t.i >> 8); } -static inline void sendCommandiStall(GECommand cmd, int argument) -{ - sendCommandi(cmd, argument); - - if (!gu_object_stack_depth && !gu_curr_context) - sceGeListUpdateStallAddr(ge_list_executed[0], gu_list->current); +static inline int _sceGuUpdateStallAddr(void) { + if (gu_curr_context == GU_DIRECT) { + // Just if there are no objects in the stack (no guBeginObject) + if (!gu_object_stack_depth) { + int res; + res = sceGeListUpdateStallAddr(ge_list_executed[0], gu_list->current); + if (res < 0) { + return res; + } + } + } + return 0; } #endif diff --git a/src/gu/pspgu.h b/src/gu/pspgu.h index c7e1d0d3..bd185dfc 100644 --- a/src/gu/pspgu.h +++ b/src/gu/pspgu.h @@ -477,6 +477,11 @@ void* sceGuSetCallback(int signal, void (*callback)(int)); /** * Trigger signal to call code from the command stream + * + * Available signals are: + * - GU_SIGNAL_WAIT - Wait for callback to finish + * - GU_SIGNAL_NOWAIT - Do not wait for callback to finish + * - GU_SIGNAL_PAUSE - Pause execution until callback is finished * * Available behaviors are: * - GU_BEHAVIOR_SUSPEND - Stops display list execution until callback function finished @@ -566,8 +571,9 @@ int sceGuFinishId(unsigned int id); * Call previously generated display-list * * @param list - Display list to call + * @return 0 for success, < 0 for failure **/ -void sceGuCallList(const void* list); +int sceGuCallList(const void* list); /** * Set wether to use stack-based calls or signals to handle execution of called lists. diff --git a/src/gu/sceGuCallList.c b/src/gu/sceGuCallList.c index d59043ad..20a4bb0c 100644 --- a/src/gu/sceGuCallList.c +++ b/src/gu/sceGuCallList.c @@ -8,19 +8,25 @@ #include "guInternal.h" -void sceGuCallList(const void *list) +int sceGuCallList(const void *list) { + int res; unsigned int list_addr = (unsigned int)list; if (gu_call_mode == GU_CALL_SIGNAL) { sendCommandi(SIGNAL, (list_addr >> 16) | 0x110000); sendCommandi(END, list_addr & 0xffff); - sendCommandiStall(NOP, 0); } else { sendCommandi(BASE, (list_addr >> 8) & 0xf0000); - sendCommandiStall(CALL, list_addr); + sendCommandi(CALL, list_addr); } + + res = _sceGuUpdateStallAddr(); + if (res < 0) { + return res; + } + return 0; } diff --git a/src/gu/sceGuDrawArray.c b/src/gu/sceGuDrawArray.c index c98143c9..2dcdb872 100644 --- a/src/gu/sceGuDrawArray.c +++ b/src/gu/sceGuDrawArray.c @@ -25,5 +25,6 @@ void sceGuDrawArray(int prim, int vtype, int count, const void *indices, const v sendCommandi(VADDR, ((unsigned int)vertices)); } - sendCommandiStall(PRIM, (prim << 16) | count); + sendCommandi(PRIM, (prim << 16) | count); + _sceGuUpdateStallAddr(); } diff --git a/src/gu/sceGuDrawArrayN.c b/src/gu/sceGuDrawArrayN.c index 7bf743f5..dd5ecc45 100644 --- a/src/gu/sceGuDrawArrayN.c +++ b/src/gu/sceGuDrawArrayN.c @@ -30,7 +30,7 @@ void sceGuDrawArrayN(int primitive_type, int vertex_type, int vcount, int primco int i; for (i = 0; i < primcount; i++) sendCommandi(PRIM, (primitive_type << 16) | vcount); - - sendCommandiStall(PRIM, (primitive_type << 16) | vcount); } + + _sceGuUpdateStallAddr(); } diff --git a/src/gu/sceGuFinishId.c b/src/gu/sceGuFinishId.c index a228b734..ad5e638f 100644 --- a/src/gu/sceGuFinishId.c +++ b/src/gu/sceGuFinishId.c @@ -7,39 +7,50 @@ */ #include "guInternal.h" +#include +#include int sceGuFinishId(unsigned int id) { + int ret; + int intr; + switch (gu_curr_context) { case GU_DIRECT: - case GU_SEND: - { sendCommandi(FINISH, id & 0xffff); - sendCommandiStall(END, 0); - } - break; - + sendCommandi(END, 0); + ret = _sceGuUpdateStallAddr(); + if (ret < 0) + { + return ret; + } + break; + case GU_SEND: + sendCommandi(FINISH, id & 0xffff); + sendCommandi(END, 0); + break; case GU_CALL: - { if (gu_call_mode == GU_CALL_SIGNAL) { sendCommandi(SIGNAL, 0x120000); sendCommandi(END, 0); - sendCommandiStall(NOP, 0); } else { sendCommandi(RET, 0); } - } - break; + break; + default: + return SCE_DISPLAY_ERROR_ARGUMENT; } unsigned int size = ((unsigned int)gu_list->current) - ((unsigned int)gu_list->start); // go to parent list + intr = sceKernelCpuSuspendIntr(); gu_curr_context = gu_list->parent_context; gu_list = &gu_contexts[gu_curr_context].list; + sceKernelCpuResumeIntr(intr); return size; } \ No newline at end of file diff --git a/src/gu/sceGuInit.c b/src/gu/sceGuInit.c index 048de45a..8a51ae80 100644 --- a/src/gu/sceGuInit.c +++ b/src/gu/sceGuInit.c @@ -283,7 +283,7 @@ int sceGuInit(void) gu_settings.ge_callback_id = res; // initialize graphics hardware - res = sceGeListEnQueue((void *)((unsigned int)ge_init_list & 0x1fffffff), 0, gu_settings.ge_callback_id, 0); + res = sceGeListEnQueue((void *)((unsigned int)ge_init_list & 0x1fffffff), NULL, gu_settings.ge_callback_id, NULL); if (res < 0) { sceKernelDeleteEventFlag(gu_settings.kernel_event_flag); diff --git a/src/gu/sceGuSignal.c b/src/gu/sceGuSignal.c index c1779c16..df691cc0 100644 --- a/src/gu/sceGuSignal.c +++ b/src/gu/sceGuSignal.c @@ -13,11 +13,11 @@ void sceGuSignal(int signal, int argument) sendCommandi(SIGNAL, ((signal & 0xff) << 16) | (argument & 0xffff)); sendCommandi(END, 0); - if (GU_SIGNAL_PAUSE == 3) + if (signal == GU_SIGNAL_PAUSE) { sendCommandi(FINISH, 0); sendCommandi(END, 0); } - sendCommandiStall(NOP, 0); -} + _sceGuUpdateStallAddr(); +} \ No newline at end of file diff --git a/src/gu/sceGuStart.c b/src/gu/sceGuStart.c index ef14da39..96791e9a 100644 --- a/src/gu/sceGuStart.c +++ b/src/gu/sceGuStart.c @@ -10,12 +10,16 @@ #include #include +#include void sceGuStart(int ctype, void *list) { + int intr; GuContext *context = &gu_contexts[ctype]; unsigned int *local_list = (unsigned int *)(((unsigned int)list) | 0x40000000); + intr = sceKernelCpuSuspendIntr(); + // setup display list context->list.start = local_list; @@ -26,10 +30,11 @@ void sceGuStart(int ctype, void *list) // store current context gu_curr_context = ctype; + sceKernelCpuResumeIntr(intr); if (ctype == GU_DIRECT) { - ge_list_executed[0] = sceGeListEnQueue(local_list, local_list, gu_settings.ge_callback_id, 0); + ge_list_executed[0] = sceGeListEnQueue(local_list, local_list, gu_settings.ge_callback_id, NULL); gu_settings.signal_offset = 0; }