From 1b8d5631ef4606a7a33c22304a43b7abe87016b7 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Thu, 22 Aug 2024 18:08:12 +0200 Subject: [PATCH] Allow MessageBox to work without window --- src/render/psp/SDL_render_psp.c | 7 -- src/render/psp/SDL_render_psp.h | 6 ++ src/video/psp/SDL_pspmessagebox.c | 126 ------------------------- src/video/psp/SDL_pspmessagebox.h | 31 ------- src/video/psp/SDL_pspvideo.c | 148 +++++++++++++++++++++++++++++- 5 files changed, 150 insertions(+), 168 deletions(-) delete mode 100644 src/video/psp/SDL_pspmessagebox.c delete mode 100644 src/video/psp/SDL_pspmessagebox.h diff --git a/src/render/psp/SDL_render_psp.c b/src/render/psp/SDL_render_psp.c index a32cd5663c5a6..a493e166a2bf4 100644 --- a/src/render/psp/SDL_render_psp.c +++ b/src/render/psp/SDL_render_psp.c @@ -39,13 +39,6 @@ #include "SDL_render_psp.h" /* 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/render/psp/SDL_render_psp.h b/src/render/psp/SDL_render_psp.h index f952886c04386..0bfbbafbdee2a 100644 --- a/src/render/psp/SDL_render_psp.h +++ b/src/render/psp/SDL_render_psp.h @@ -22,6 +22,12 @@ /* this header is meant to be included after the other related internal SDL headers. it's the interface between psp renderer and video driver code. */ +#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) + enum SDL_PSP_RenderProps { SDL_PSP_RENDERPROPS_FRONTBUFFER, diff --git a/src/video/psp/SDL_pspmessagebox.c b/src/video/psp/SDL_pspmessagebox.c deleted file mode 100644 index 5742502c13377..0000000000000 --- 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_GetFocusWindow() == 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_pspmessagebox.h b/src/video/psp/SDL_pspmessagebox.h deleted file mode 100644 index 4f32285069756..0000000000000 --- a/src/video/psp/SDL_pspmessagebox.h +++ /dev/null @@ -1,31 +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. -*/ - -#ifndef SDL_pspmessagebox_h_ -#define SDL_pspmessagebox_h_ - -#if SDL_VIDEO_DRIVER_PSP - -int PSP_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); - -#endif /* SDL_VIDEO_DRIVER_PSP */ - -#endif /* SDL_pspmessagebox_h_ */ diff --git a/src/video/psp/SDL_pspvideo.c b/src/video/psp/SDL_pspvideo.c index 4144281c5c740..723566dc4607f 100644 --- a/src/video/psp/SDL_pspvideo.c +++ b/src/video/psp/SDL_pspvideo.c @@ -39,11 +39,11 @@ #include "SDL_pspvideo.h" #include "SDL_pspevents_c.h" #include "SDL_pspgl_c.h" -#include "SDL_pspmessagebox.h" #include #include #include +#include #include "../../render/psp/SDL_render_psp.h" #define SDL_WINDOWTEXTUREDATA "_SDL_WindowTextureData" @@ -65,7 +65,7 @@ int PSP_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, Uint SDL_GetWindowSizeInPixels(window, &w, &h); - if (w != 480) { + if (w != PSP_SCREEN_WIDTH) { return SDL_SetError("Unexpected window size"); } @@ -257,6 +257,146 @@ static SDL_VideoDevice *PSP_Create() 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_GetFocusWindow() == 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", @@ -278,8 +418,8 @@ int PSP_VideoInit(_THIS) SDL_zero(current_mode); - current_mode.w = 480; - current_mode.h = 272; + current_mode.w = PSP_SCREEN_WIDTH; + current_mode.h = PSP_SCREEN_HEIGHT; current_mode.refresh_rate = 60; /* 32 bpp for default */