diff --git a/src/render/psp/SDL_render_psp.c b/src/render/psp/SDL_render_psp.c index d1ed86410..db74da539 100644 --- a/src/render/psp/SDL_render_psp.c +++ b/src/render/psp/SDL_render_psp.c @@ -24,6 +24,8 @@ #include "../SDL_sysrender.h" +#include "SDL_render_psp_c.h" + #include #include #include @@ -38,12 +40,6 @@ // PSP renderer implementation, based on the PGE -#define PSP_SCREEN_WIDTH 480 -#define PSP_SCREEN_HEIGHT 272 - -#define PSP_FRAME_BUFFER_WIDTH 512 -#define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH * PSP_SCREEN_HEIGHT) - static unsigned int __attribute__((aligned(16))) DisplayList[262144]; #define COL5650(r, g, b, a) ((r >> 3) | ((g >> 2) << 5) | ((b >> 3) << 11)) diff --git a/src/video/psp/SDL_pspmessagebox.h b/src/render/psp/SDL_render_psp_c.h similarity index 77% rename from src/video/psp/SDL_pspmessagebox.h rename to src/render/psp/SDL_render_psp_c.h index 6f9b0fe0a..98bae20e8 100644 --- a/src/video/psp/SDL_pspmessagebox.h +++ b/src/render/psp/SDL_render_psp_c.h @@ -18,14 +18,13 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ +#ifndef SDL_VIDEO_RENDER_PSP_C_H +#define SDL_VIDEO_RENDER_PSP_C_H -#ifndef SDL_pspmessagebox_h_ -#define SDL_pspmessagebox_h_ +#define PSP_SCREEN_WIDTH 480 +#define PSP_SCREEN_HEIGHT 272 -#if SDL_VIDEO_DRIVER_PSP +#define PSP_FRAME_BUFFER_WIDTH 512 +#define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH * PSP_SCREEN_HEIGHT) -int PSP_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); - -#endif // SDL_VIDEO_DRIVER_PSP - -#endif // SDL_pspmessagebox_h_ +#endif // SDL_VIDEO_RENDER_PSP_C_H diff --git a/src/video/psp/SDL_pspmessagebox.c b/src/video/psp/SDL_pspmessagebox.c deleted file mode 100644 index 4385a6930..000000000 --- a/src/video/psp/SDL_pspmessagebox.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "SDL_internal.h" - -#ifdef SDL_VIDEO_DRIVER_PSP - -#include "SDL_pspvideo.h" -#include "SDL_pspmessagebox.h" -#include -#include -#include -#include -#include - -static void configure_dialog(pspUtilityMsgDialogParams *dialog, size_t dialog_size) -{ - // clear structure and setup size - SDL_memset(dialog, 0, dialog_size); - dialog->base.size = dialog_size; - - // set language - sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, &dialog->base.language); - - // set X/O swap - sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &dialog->base.buttonSwap); - - // set thread priorities - // TODO: understand how these work - dialog->base.soundThread = 0x10; - dialog->base.graphicsThread = 0x11; - dialog->base.fontThread = 0x12; - dialog->base.accessThread = 0x13; -} - -int PSP_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID) -{ - unsigned char list[0x20000] __attribute__((aligned(64))); - pspUtilityMsgDialogParams dialog; - int status; - - // check if it's possible to do a messagebox now - if (SDL_GetKeyboardFocus() == NULL) - return SDL_SetError("No video context is available"); - - // configure dialog - configure_dialog(&dialog, sizeof(dialog)); - - // setup dialog options for text - dialog.mode = PSP_UTILITY_MSGDIALOG_MODE_TEXT; - dialog.options = PSP_UTILITY_MSGDIALOG_OPTION_TEXT; - - // copy the message in, 512 bytes max - SDL_snprintf(dialog.message, sizeof(dialog.message), "%s\r\n\r\n%s", messageboxdata->title, messageboxdata->message); - - // too many buttons - if (messageboxdata->numbuttons > 2) - return SDL_SetError("messageboxdata->numbuttons valid values are 0, 1, 2"); - - // we only have two options, "yes/no" or "ok" - if (messageboxdata->numbuttons == 2) - dialog.options |= PSP_UTILITY_MSGDIALOG_OPTION_YESNO_BUTTONS | PSP_UTILITY_MSGDIALOG_OPTION_DEFAULT_NO; - - // start dialog - if (sceUtilityMsgDialogInitStart(&dialog) != 0) - return SDL_SetError("sceUtilityMsgDialogInitStart() failed for some reason"); - - // loop while the dialog is active - status = PSP_UTILITY_DIALOG_NONE; - do - { - sceGuStart(GU_DIRECT, list); - sceGuClearColor(0); - sceGuClearDepth(0); - sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); - sceGuFinish(); - sceGuSync(0,0); - - status = sceUtilityMsgDialogGetStatus(); - - switch (status) - { - case PSP_UTILITY_DIALOG_VISIBLE: - sceUtilityMsgDialogUpdate(1); - break; - - case PSP_UTILITY_DIALOG_QUIT: - sceUtilityMsgDialogShutdownStart(); - break; - } - - sceDisplayWaitVblankStart(); - sceGuSwapBuffers(); - - } while (status != PSP_UTILITY_DIALOG_NONE); - - // success - if (dialog.buttonPressed == PSP_UTILITY_MSGDIALOG_RESULT_YES) - *buttonID = messageboxdata->buttons[0].buttonID; - else if (dialog.buttonPressed == PSP_UTILITY_MSGDIALOG_RESULT_NO) - *buttonID = messageboxdata->buttons[1].buttonID; - else - *buttonID = messageboxdata->buttons[0].buttonID; - - return 0; -} - -#endif // SDL_VIDEO_DRIVER_PSP diff --git a/src/video/psp/SDL_pspvideo.c b/src/video/psp/SDL_pspvideo.c index 5c25401e0..7004b9274 100644 --- a/src/video/psp/SDL_pspvideo.c +++ b/src/video/psp/SDL_pspvideo.c @@ -32,11 +32,12 @@ #include "SDL_pspvideo.h" #include "SDL_pspevents_c.h" #include "SDL_pspgl_c.h" -#include "SDL_pspmessagebox.h" +#include "../../render/psp/SDL_render_psp_c.h" #include #include #include +#include /* unused static bool PSP_initialized = false; @@ -120,6 +121,146 @@ static SDL_VideoDevice *PSP_Create(void) return device; } +static void configure_dialog(pspUtilityMsgDialogParams *dialog, size_t dialog_size) +{ + // clear structure and setup size + SDL_memset(dialog, 0, dialog_size); + dialog->base.size = dialog_size; + + // set language + sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, &dialog->base.language); + + // set X/O swap + sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &dialog->base.buttonSwap); + + // set thread priorities + // TODO: understand how these work + dialog->base.soundThread = 0x10; + dialog->base.graphicsThread = 0x11; + dialog->base.fontThread = 0x12; + dialog->base.accessThread = 0x13; +} + +static void *setup_temporal_gu(void *list) +{ + // Using GU_PSM_8888 for the framebuffer + int bpp = 4; + + void *doublebuffer = vramalloc(PSP_FRAME_BUFFER_SIZE * bpp * 2); + void *backbuffer = doublebuffer; + void *frontbuffer = ((uint8_t *)doublebuffer) + PSP_FRAME_BUFFER_SIZE * bpp; + + sceGuInit(); + + sceGuStart(GU_DIRECT,list); + sceGuDrawBuffer(GU_PSM_8888, vrelptr(frontbuffer), PSP_FRAME_BUFFER_WIDTH); + sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, vrelptr(backbuffer), PSP_FRAME_BUFFER_WIDTH); + + sceGuOffset(2048 - (PSP_SCREEN_WIDTH >> 1), 2048 - (PSP_SCREEN_HEIGHT >> 1)); + sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); + + sceGuDisable(GU_DEPTH_TEST); + + // Scissoring + sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + + sceGuFinish(); + sceGuSync(0,0); + + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_TRUE); + + return doublebuffer; +} + +static void term_temporal_gu(void *guBuffer) +{ + sceGuTerm(); + vfree(guBuffer); + sceDisplayWaitVblankStart(); +} + +int PSP_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID) +{ + unsigned char list[64] __attribute__((aligned(64))); + pspUtilityMsgDialogParams dialog; + int status; + void *guBuffer = NULL; + + // check if it's possible to use existing video context + if (SDL_GetKeyboardFocus() == NULL) { + guBuffer = setup_temporal_gu(list); + } + + // configure dialog + configure_dialog(&dialog, sizeof(dialog)); + + // setup dialog options for text + dialog.mode = PSP_UTILITY_MSGDIALOG_MODE_TEXT; + dialog.options = PSP_UTILITY_MSGDIALOG_OPTION_TEXT; + + // copy the message in, 512 bytes max + SDL_snprintf(dialog.message, sizeof(dialog.message), "%s\r\n\r\n%s", messageboxdata->title, messageboxdata->message); + + // too many buttons + if (messageboxdata->numbuttons > 2) + return SDL_SetError("messageboxdata->numbuttons valid values are 0, 1, 2"); + + // we only have two options, "yes/no" or "ok" + if (messageboxdata->numbuttons == 2) + dialog.options |= PSP_UTILITY_MSGDIALOG_OPTION_YESNO_BUTTONS | PSP_UTILITY_MSGDIALOG_OPTION_DEFAULT_NO; + + // start dialog + if (sceUtilityMsgDialogInitStart(&dialog) != 0) + return SDL_SetError("sceUtilityMsgDialogInitStart() failed for some reason"); + + // loop while the dialog is active + status = PSP_UTILITY_DIALOG_NONE; + do + { + sceGuStart(GU_DIRECT, list); + sceGuClearColor(0); + sceGuClearDepth(0); + sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); + sceGuFinish(); + sceGuSync(0,0); + + status = sceUtilityMsgDialogGetStatus(); + + switch (status) + { + case PSP_UTILITY_DIALOG_VISIBLE: + sceUtilityMsgDialogUpdate(1); + break; + + case PSP_UTILITY_DIALOG_QUIT: + sceUtilityMsgDialogShutdownStart(); + break; + } + + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + + } while (status != PSP_UTILITY_DIALOG_NONE); + + // cleanup + if (guBuffer) + { + term_temporal_gu(guBuffer); + } + + // success + if (dialog.buttonPressed == PSP_UTILITY_MSGDIALOG_RESULT_YES) + *buttonID = messageboxdata->buttons[0].buttonID; + else if (dialog.buttonPressed == PSP_UTILITY_MSGDIALOG_RESULT_NO) + *buttonID = messageboxdata->buttons[1].buttonID; + else + *buttonID = messageboxdata->buttons[0].buttonID; + + return 0; +} + VideoBootStrap PSP_bootstrap = { "psp", "PSP Video Driver", @@ -139,8 +280,8 @@ int PSP_VideoInit(SDL_VideoDevice *_this) } SDL_zero(mode); - mode.w = 480; - mode.h = 272; + mode.w = PSP_SCREEN_WIDTH; + mode.h = PSP_SCREEN_HEIGHT; mode.refresh_rate = 60.0f; // 32 bpp for default @@ -162,8 +303,8 @@ int PSP_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display) SDL_DisplayMode mode; SDL_zero(mode); - mode.w = 480; - mode.h = 272; + mode.w = PSP_SCREEN_WIDTH; + mode.h = PSP_SCREEN_HEIGHT; mode.refresh_rate = 60.0f; // 32 bpp for default