Daily update on 20250721-223448 by Nitload Youmu. Additional Message : Rename StgSHarp.C to StgSharp.Native. Add SDL to repo.

Signed-off-by: Nitload <YoumuLiu_NSI@whv0t.onmicrosoft.com>
This commit is contained in:
Nitload
2025-07-21 22:34:48 +08:00
parent c624a8ca38
commit 28ea5d1d1e
1215 changed files with 628924 additions and 114 deletions
@@ -0,0 +1,274 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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
/* Being a null driver, there's no event stream. We just define stubs for
most of the API. */
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../SDL_sysvideo.h"
#include "SDL_pspvideo.h"
#include "SDL_pspevents_c.h"
#include "../../thread/SDL_systhread.h"
#include <psphprm.h>
#include <pspthreadman.h>
#ifdef PSPIRKEYB
#include <pspirkeyb.h>
#include <pspirkeyb_rawkeys.h>
#define IRKBD_CONFIG_FILE NULL // this will take ms0:/seplugins/pspirkeyb.ini
static int irkbd_ready = 0;
static SDL_Scancode keymap[256];
#endif
static enum PspHprmKeys hprm = 0;
static SDL_Semaphore *event_sem = NULL;
static SDL_Thread *thread = NULL;
static int running = 0;
static struct
{
enum PspHprmKeys id;
SDL_Scancode scancode;
} keymap_psp[] = {
{ PSP_HPRM_PLAYPAUSE, SDL_SCANCODE_F10 },
{ PSP_HPRM_FORWARD, SDL_SCANCODE_F11 },
{ PSP_HPRM_BACK, SDL_SCANCODE_F12 },
{ PSP_HPRM_VOL_UP, SDL_SCANCODE_F13 },
{ PSP_HPRM_VOL_DOWN, SDL_SCANCODE_F14 },
{ PSP_HPRM_HOLD, SDL_SCANCODE_F15 }
};
int EventUpdate(void *data)
{
while (running) {
SDL_WaitSemaphore(event_sem);
sceHprmPeekCurrentKey((u32 *)&hprm);
SDL_SignalSemaphore(event_sem);
// Delay 1/60th of a second
sceKernelDelayThread(1000000 / 60);
}
return 0;
}
void PSP_PumpEvents(SDL_VideoDevice *_this)
{
int i;
enum PspHprmKeys keys;
enum PspHprmKeys changed;
static enum PspHprmKeys old_keys = 0;
SDL_WaitSemaphore(event_sem);
keys = hprm;
SDL_SignalSemaphore(event_sem);
// HPRM Keyboard
changed = old_keys ^ keys;
old_keys = keys;
if (changed) {
for (i = 0; i < sizeof(keymap_psp) / sizeof(keymap_psp[0]); i++) {
if (changed & keymap_psp[i].id) {
bool down = ((keys & keymap_psp[i].id) != 0);
SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, keymap_psp[i].id, keymap_psp[i].scancode, down);
}
}
}
#ifdef PSPIRKEYB
if (irkbd_ready) {
unsigned char buffer[255];
int i, length, count;
SIrKeybScanCodeData *scanData;
if (pspIrKeybReadinput(buffer, &length) >= 0) {
if ((length % sizeof(SIrKeybScanCodeData)) == 0) {
count = length / sizeof(SIrKeybScanCodeData);
for (i = 0; i < count; i++) {
unsigned char raw;
bool down;
scanData = (SIrKeybScanCodeData *)buffer + i;
raw = scanData->raw;
down = (scanData->pressed != 0);
SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, raw, keymap[raw], down);
}
}
}
}
#endif
sceKernelDelayThread(0);
return;
}
void PSP_InitOSKeymap(SDL_VideoDevice *_this)
{
#ifdef PSPIRKEYB
int i;
for (i = 0; i < SDL_arraysize(keymap); ++i) {
keymap[i] = SDL_SCANCODE_UNKNOWN;
}
keymap[KEY_ESC] = SDL_SCANCODE_ESCAPE;
keymap[KEY_F1] = SDL_SCANCODE_F1;
keymap[KEY_F2] = SDL_SCANCODE_F2;
keymap[KEY_F3] = SDL_SCANCODE_F3;
keymap[KEY_F4] = SDL_SCANCODE_F4;
keymap[KEY_F5] = SDL_SCANCODE_F5;
keymap[KEY_F6] = SDL_SCANCODE_F6;
keymap[KEY_F7] = SDL_SCANCODE_F7;
keymap[KEY_F8] = SDL_SCANCODE_F8;
keymap[KEY_F9] = SDL_SCANCODE_F9;
keymap[KEY_F10] = SDL_SCANCODE_F10;
keymap[KEY_F11] = SDL_SCANCODE_F11;
keymap[KEY_F12] = SDL_SCANCODE_F12;
keymap[KEY_F13] = SDL_SCANCODE_PRINT;
keymap[KEY_F14] = SDL_SCANCODE_PAUSE;
keymap[KEY_GRAVE] = SDL_SCANCODE_GRAVE;
keymap[KEY_1] = SDL_SCANCODE_1;
keymap[KEY_2] = SDL_SCANCODE_2;
keymap[KEY_3] = SDL_SCANCODE_3;
keymap[KEY_4] = SDL_SCANCODE_4;
keymap[KEY_5] = SDL_SCANCODE_5;
keymap[KEY_6] = SDL_SCANCODE_6;
keymap[KEY_7] = SDL_SCANCODE_7;
keymap[KEY_8] = SDL_SCANCODE_8;
keymap[KEY_9] = SDL_SCANCODE_9;
keymap[KEY_0] = SDL_SCANCODE_0;
keymap[KEY_MINUS] = SDL_SCANCODE_MINUS;
keymap[KEY_EQUAL] = SDL_SCANCODE_EQUALS;
keymap[KEY_BACKSPACE] = SDL_SCANCODE_BACKSPACE;
keymap[KEY_TAB] = SDL_SCANCODE_TAB;
keymap[KEY_Q] = SDL_SCANCODE_q;
keymap[KEY_W] = SDL_SCANCODE_w;
keymap[KEY_E] = SDL_SCANCODE_e;
keymap[KEY_R] = SDL_SCANCODE_r;
keymap[KEY_T] = SDL_SCANCODE_t;
keymap[KEY_Y] = SDL_SCANCODE_y;
keymap[KEY_U] = SDL_SCANCODE_u;
keymap[KEY_I] = SDL_SCANCODE_i;
keymap[KEY_O] = SDL_SCANCODE_o;
keymap[KEY_P] = SDL_SCANCODE_p;
keymap[KEY_LEFTBRACE] = SDL_SCANCODE_LEFTBRACKET;
keymap[KEY_RIGHTBRACE] = SDL_SCANCODE_RIGHTBRACKET;
keymap[KEY_ENTER] = SDL_SCANCODE_RETURN;
keymap[KEY_CAPSLOCK] = SDL_SCANCODE_CAPSLOCK;
keymap[KEY_A] = SDL_SCANCODE_a;
keymap[KEY_S] = SDL_SCANCODE_s;
keymap[KEY_D] = SDL_SCANCODE_d;
keymap[KEY_F] = SDL_SCANCODE_f;
keymap[KEY_G] = SDL_SCANCODE_g;
keymap[KEY_H] = SDL_SCANCODE_h;
keymap[KEY_J] = SDL_SCANCODE_j;
keymap[KEY_K] = SDL_SCANCODE_k;
keymap[KEY_L] = SDL_SCANCODE_l;
keymap[KEY_SEMICOLON] = SDL_SCANCODE_SEMICOLON;
keymap[KEY_APOSTROPHE] = SDL_SCANCODE_APOSTROPHE;
keymap[KEY_BACKSLASH] = SDL_SCANCODE_BACKSLASH;
keymap[KEY_Z] = SDL_SCANCODE_z;
keymap[KEY_X] = SDL_SCANCODE_x;
keymap[KEY_C] = SDL_SCANCODE_c;
keymap[KEY_V] = SDL_SCANCODE_v;
keymap[KEY_B] = SDL_SCANCODE_b;
keymap[KEY_N] = SDL_SCANCODE_n;
keymap[KEY_M] = SDL_SCANCODE_m;
keymap[KEY_COMMA] = SDL_SCANCODE_COMMA;
keymap[KEY_DOT] = SDL_SCANCODE_PERIOD;
keymap[KEY_SLASH] = SDL_SCANCODE_SLASH;
keymap[KEY_SPACE] = SDL_SCANCODE_SPACE;
keymap[KEY_UP] = SDL_SCANCODE_UP;
keymap[KEY_DOWN] = SDL_SCANCODE_DOWN;
keymap[KEY_LEFT] = SDL_SCANCODE_LEFT;
keymap[KEY_RIGHT] = SDL_SCANCODE_RIGHT;
keymap[KEY_HOME] = SDL_SCANCODE_HOME;
keymap[KEY_END] = SDL_SCANCODE_END;
keymap[KEY_INSERT] = SDL_SCANCODE_INSERT;
keymap[KEY_DELETE] = SDL_SCANCODE_DELETE;
keymap[KEY_NUMLOCK] = SDL_SCANCODE_NUMLOCK;
keymap[KEY_LEFTMETA] = SDL_SCANCODE_LSUPER;
keymap[KEY_KPSLASH] = SDL_SCANCODE_KP_DIVIDE;
keymap[KEY_KPASTERISK] = SDL_SCANCODE_KP_MULTIPLY;
keymap[KEY_KPMINUS] = SDL_SCANCODE_KP_MINUS;
keymap[KEY_KPPLUS] = SDL_SCANCODE_KP_PLUS;
keymap[KEY_KPDOT] = SDL_SCANCODE_KP_PERIOD;
keymap[KEY_KPEQUAL] = SDL_SCANCODE_KP_EQUALS;
keymap[KEY_LEFTCTRL] = SDL_SCANCODE_LCTRL;
keymap[KEY_RIGHTCTRL] = SDL_SCANCODE_RCTRL;
keymap[KEY_LEFTALT] = SDL_SCANCODE_LALT;
keymap[KEY_RIGHTALT] = SDL_SCANCODE_RALT;
keymap[KEY_LEFTSHIFT] = SDL_SCANCODE_LSHIFT;
keymap[KEY_RIGHTSHIFT] = SDL_SCANCODE_RSHIFT;
#endif
}
bool PSP_EventInit(SDL_VideoDevice *_this)
{
#ifdef PSPIRKEYB
int outputmode = PSP_IRKBD_OUTPUT_MODE_SCANCODE;
int ret = pspIrKeybInit(IRKBD_CONFIG_FILE, 0);
if (ret == PSP_IRKBD_RESULT_OK) {
pspIrKeybOutputMode(outputmode);
irkbd_ready = 1;
} else {
irkbd_ready = 0;
}
#endif
// Start thread to read data
if ((event_sem = SDL_CreateSemaphore(1)) == NULL) {
return SDL_SetError("Can't create input semaphore");
}
running = 1;
if ((thread = SDL_CreateThreadWithStackSize(EventUpdate, "PSPInputThread", 4096, NULL)) == NULL) {
return SDL_SetError("Can't create input thread");
}
return true;
}
void PSP_EventQuit(SDL_VideoDevice *_this)
{
running = 0;
SDL_WaitThread(thread, NULL);
SDL_DestroySemaphore(event_sem);
#ifdef PSPIRKEYB
if (irkbd_ready) {
pspIrKeybFinish();
irkbd_ready = 0;
}
#endif
}
// end of SDL_pspevents.c ...
#endif // SDL_VIDEO_DRIVER_PSP
@@ -0,0 +1,29 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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_pspvideo.h"
extern void PSP_InitOSKeymap(SDL_VideoDevice *_this);
extern void PSP_PumpEvents(SDL_VideoDevice *_this);
extern bool PSP_EventInit(SDL_VideoDevice *_this);
extern void PSP_EventQuit(SDL_VideoDevice *_this);
// end of SDL_pspevents_c.h ...
@@ -0,0 +1,190 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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 <stdlib.h>
#include <string.h>
#include "SDL_pspvideo.h"
#include "SDL_pspgl_c.h"
/*****************************************************************************/
// SDL OpenGL/OpenGL ES functions
/*****************************************************************************/
#define EGLCHK(stmt) \
do { \
EGLint err; \
\
stmt; \
err = eglGetError(); \
if (err != EGL_SUCCESS) { \
SDL_SetError("EGL error %d", err); \
return NULL; \
} \
} while (0)
bool PSP_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path)
{
return true;
}
/* pspgl doesn't provide this call, so stub it out since SDL requires it.
#define GLSTUB(func,params) void func params {}
GLSTUB(glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top,
GLdouble zNear, GLdouble zFar))
*/
SDL_FunctionPointer PSP_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc)
{
return eglGetProcAddress(proc);
}
void PSP_GL_UnloadLibrary(SDL_VideoDevice *_this)
{
eglTerminate(_this->gl_data->display);
}
static EGLint width = 480;
static EGLint height = 272;
SDL_GLContext PSP_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
{
SDL_WindowData *wdata = window->internal;
EGLint attribs[32];
EGLDisplay display;
EGLContext context;
EGLSurface surface;
EGLConfig config;
EGLint num_configs;
int i;
// EGL init taken from glutCreateWindow() in PSPGL's glut.c.
EGLCHK(display = eglGetDisplay(0));
EGLCHK(eglInitialize(display, NULL, NULL));
wdata->uses_gles = true;
window->flags |= SDL_WINDOW_FULLSCREEN;
// Setup the config based on SDL's current values.
i = 0;
attribs[i++] = EGL_RED_SIZE;
attribs[i++] = _this->gl_config.red_size;
attribs[i++] = EGL_GREEN_SIZE;
attribs[i++] = _this->gl_config.green_size;
attribs[i++] = EGL_BLUE_SIZE;
attribs[i++] = _this->gl_config.blue_size;
attribs[i++] = EGL_DEPTH_SIZE;
attribs[i++] = _this->gl_config.depth_size;
if (_this->gl_config.alpha_size) {
attribs[i++] = EGL_ALPHA_SIZE;
attribs[i++] = _this->gl_config.alpha_size;
}
if (_this->gl_config.stencil_size) {
attribs[i++] = EGL_STENCIL_SIZE;
attribs[i++] = _this->gl_config.stencil_size;
}
attribs[i++] = EGL_NONE;
EGLCHK(eglChooseConfig(display, attribs, &config, 1, &num_configs));
if (num_configs == 0) {
SDL_SetError("No valid EGL configs for requested mode");
return NULL;
}
EGLCHK(eglGetConfigAttrib(display, config, EGL_WIDTH, &width));
EGLCHK(eglGetConfigAttrib(display, config, EGL_HEIGHT, &height));
EGLCHK(context = eglCreateContext(display, config, NULL, NULL));
EGLCHK(surface = eglCreateWindowSurface(display, config, 0, NULL));
EGLCHK(eglMakeCurrent(display, surface, surface, context));
_this->gl_data->display = display;
_this->gl_data->context = context;
_this->gl_data->surface = surface;
return context;
}
bool PSP_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context)
{
if (!eglMakeCurrent(_this->gl_data->display, _this->gl_data->surface,
_this->gl_data->surface, _this->gl_data->context)) {
return SDL_SetError("Unable to make EGL context current");
}
return true;
}
bool PSP_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval)
{
EGLBoolean status;
status = eglSwapInterval(_this->gl_data->display, interval);
if (status == EGL_TRUE) {
// Return success to upper level
_this->gl_data->swapinterval = interval;
return true;
}
// Failed to set swap interval
return SDL_SetError("Unable to set the EGL swap interval");
}
bool PSP_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval)
{
*interval = _this->gl_data->swapinterval;
return true;
}
bool PSP_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
if (!eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface)) {
return SDL_SetError("eglSwapBuffers() failed");
}
return true;
}
bool PSP_GL_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context)
{
SDL_VideoData *phdata = _this->internal;
EGLBoolean status;
if (phdata->egl_initialized != true) {
return SDL_SetError("PSP: GLES initialization failed, no OpenGL ES support");
}
// Check if OpenGL ES connection has been initialized
if (_this->gl_data->display != EGL_NO_DISPLAY) {
if (context != EGL_NO_CONTEXT) {
status = eglDestroyContext(_this->gl_data->display, context);
if (status != EGL_TRUE) {
// Error during OpenGL ES context destroying
return SDL_SetError("PSP: OpenGL ES context destroy error");
}
}
}
return true;
}
#endif // SDL_VIDEO_DRIVER_PSP
@@ -0,0 +1,50 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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_pspgl_c_h_
#define SDL_pspgl_c_h_
#include <GLES/egl.h>
#include <GLES/gl.h>
#include "SDL_pspvideo.h"
typedef struct SDL_GLDriverData
{
EGLDisplay display;
EGLContext context;
EGLSurface surface;
uint32_t swapinterval;
} SDL_GLDriverData;
extern SDL_FunctionPointer PSP_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc);
extern bool PSP_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context);
extern void PSP_GL_SwapBuffers(SDL_VideoDevice *_this);
extern bool PSP_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern SDL_GLContext PSP_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window);
extern bool PSP_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path);
extern void PSP_GL_UnloadLibrary(SDL_VideoDevice *_this);
extern bool PSP_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval);
extern bool PSP_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval);
#endif // SDL_pspgl_c_h_
@@ -0,0 +1,37 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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 <stdio.h>
#include "../../events/SDL_events_c.h"
#include "SDL_pspmouse_c.h"
// The implementation dependent data for the window manager cursor
struct WMcursor
{
int unused;
};
#endif // SDL_VIDEO_DRIVER_PSP
@@ -0,0 +1,24 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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_pspvideo.h"
// Functions to be exported
@@ -0,0 +1,501 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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
// SDL internals
#include "../SDL_sysvideo.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
// PSP declarations
#include "SDL_pspvideo.h"
#include "SDL_pspevents_c.h"
#include "SDL_pspgl_c.h"
#include "../../render/psp/SDL_render_psp_c.h"
#include <psputility.h>
#include <pspgu.h>
#include <pspdisplay.h>
#include <vram.h>
/* unused
static bool PSP_initialized = false;
*/
static void PSP_Destroy(SDL_VideoDevice *device)
{
SDL_free(device->internal);
SDL_free(device);
}
static SDL_VideoDevice *PSP_Create(void)
{
SDL_VideoDevice *device;
SDL_VideoData *phdata;
SDL_GLDriverData *gldata;
// Initialize SDL_VideoDevice structure
device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
if (!device) {
return NULL;
}
// Initialize internal PSP specific data
phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData));
if (!phdata) {
SDL_free(device);
return NULL;
}
gldata = (SDL_GLDriverData *)SDL_calloc(1, sizeof(SDL_GLDriverData));
if (!gldata) {
SDL_free(device);
SDL_free(phdata);
return NULL;
}
device->gl_data = gldata;
device->internal = phdata;
phdata->egl_initialized = true;
// Setup amount of available displays
device->num_displays = 0;
// Set device free function
device->free = PSP_Destroy;
// Setup all functions which we can handle
device->VideoInit = PSP_VideoInit;
device->VideoQuit = PSP_VideoQuit;
device->GetDisplayModes = PSP_GetDisplayModes;
device->SetDisplayMode = PSP_SetDisplayMode;
device->CreateSDLWindow = PSP_CreateWindow;
device->SetWindowTitle = PSP_SetWindowTitle;
device->SetWindowPosition = PSP_SetWindowPosition;
device->SetWindowSize = PSP_SetWindowSize;
device->ShowWindow = PSP_ShowWindow;
device->HideWindow = PSP_HideWindow;
device->RaiseWindow = PSP_RaiseWindow;
device->MaximizeWindow = PSP_MaximizeWindow;
device->MinimizeWindow = PSP_MinimizeWindow;
device->RestoreWindow = PSP_RestoreWindow;
device->DestroyWindow = PSP_DestroyWindow;
device->GL_LoadLibrary = PSP_GL_LoadLibrary;
device->GL_GetProcAddress = PSP_GL_GetProcAddress;
device->GL_UnloadLibrary = PSP_GL_UnloadLibrary;
device->GL_CreateContext = PSP_GL_CreateContext;
device->GL_MakeCurrent = PSP_GL_MakeCurrent;
device->GL_SetSwapInterval = PSP_GL_SetSwapInterval;
device->GL_GetSwapInterval = PSP_GL_GetSwapInterval;
device->GL_SwapWindow = PSP_GL_SwapWindow;
device->GL_DestroyContext = PSP_GL_DestroyContext;
device->HasScreenKeyboardSupport = PSP_HasScreenKeyboardSupport;
device->ShowScreenKeyboard = PSP_ShowScreenKeyboard;
device->HideScreenKeyboard = PSP_HideScreenKeyboard;
device->IsScreenKeyboardShown = PSP_IsScreenKeyboardShown;
device->PumpEvents = PSP_PumpEvents;
device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY;
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();
}
bool 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 true;
}
VideoBootStrap PSP_bootstrap = {
"psp",
"PSP Video Driver",
PSP_Create,
PSP_ShowMessageBox,
false
};
/*****************************************************************************/
// SDL Video and Display initialization/handling functions
/*****************************************************************************/
bool PSP_VideoInit(SDL_VideoDevice *_this)
{
SDL_DisplayMode mode;
if (!PSP_EventInit(_this)) {
return false; // error string would already be set
}
SDL_zero(mode);
mode.w = PSP_SCREEN_WIDTH;
mode.h = PSP_SCREEN_HEIGHT;
mode.refresh_rate = 60.0f;
// 32 bpp for default
mode.format = SDL_PIXELFORMAT_ABGR8888;
if (SDL_AddBasicVideoDisplay(&mode) == 0) {
return false;
}
return true;
}
void PSP_VideoQuit(SDL_VideoDevice *_this)
{
PSP_EventQuit(_this);
}
bool PSP_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
{
SDL_DisplayMode mode;
SDL_zero(mode);
mode.w = PSP_SCREEN_WIDTH;
mode.h = PSP_SCREEN_HEIGHT;
mode.refresh_rate = 60.0f;
// 32 bpp for default
mode.format = SDL_PIXELFORMAT_ABGR8888;
SDL_AddFullscreenDisplayMode(display, &mode);
// 16 bpp secondary mode
mode.format = SDL_PIXELFORMAT_BGR565;
SDL_AddFullscreenDisplayMode(display, &mode);
return true;
}
bool PSP_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
{
return true;
}
#define EGLCHK(stmt) \
do { \
EGLint err; \
\
stmt; \
err = eglGetError(); \
if (err != EGL_SUCCESS) { \
SDL_SetError("EGL error %d", err); \
return true; \
} \
} while (0)
bool PSP_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props)
{
SDL_WindowData *wdata;
// Allocate window internal data
wdata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
if (!wdata) {
return false;
}
// Setup driver data for this window
window->internal = wdata;
SDL_SetKeyboardFocus(window);
// Window has been successfully created
return true;
}
void PSP_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
{
}
bool PSP_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
{
return SDL_Unsupported();
}
void PSP_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
{
}
void PSP_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
}
void PSP_HideWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
}
void PSP_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
}
void PSP_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
}
void PSP_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
}
void PSP_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
}
void PSP_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
}
bool PSP_HasScreenKeyboardSupport(SDL_VideoDevice *_this)
{
return true;
}
void PSP_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props)
{
char list[0x20000] __attribute__((aligned(64))); // Needed for sceGuStart to work
int i;
int done = 0;
int input_text_length = 32; // SDL_SendKeyboardText supports up to 32 characters per event
unsigned short outtext[input_text_length];
char text_string[input_text_length];
SceUtilityOskData data;
SceUtilityOskParams params;
SDL_memset(outtext, 0, input_text_length * sizeof(unsigned short));
data.language = PSP_UTILITY_OSK_LANGUAGE_DEFAULT;
data.lines = 1;
data.unk_24 = 1;
switch (SDL_GetTextInputType(props)) {
default:
case SDL_TEXTINPUT_TYPE_TEXT:
data.inputtype = PSP_UTILITY_OSK_INPUTTYPE_ALL;
break;
case SDL_TEXTINPUT_TYPE_TEXT_NAME:
data.inputtype = PSP_UTILITY_OSK_INPUTTYPE_ALL;
break;
case SDL_TEXTINPUT_TYPE_TEXT_EMAIL:
data.inputtype = PSP_UTILITY_OSK_INPUTTYPE_ALL;
break;
case SDL_TEXTINPUT_TYPE_TEXT_USERNAME:
data.inputtype = PSP_UTILITY_OSK_INPUTTYPE_ALL;
break;
case SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_HIDDEN:
data.inputtype = PSP_UTILITY_OSK_INPUTTYPE_ALL;
break;
case SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_VISIBLE:
data.inputtype = PSP_UTILITY_OSK_INPUTTYPE_ALL;
break;
case SDL_TEXTINPUT_TYPE_NUMBER:
data.inputtype = PSP_UTILITY_OSK_INPUTTYPE_LATIN_DIGIT;
break;
case SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_HIDDEN:
data.inputtype = PSP_UTILITY_OSK_INPUTTYPE_LATIN_DIGIT;
break;
case SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_VISIBLE:
data.inputtype = PSP_UTILITY_OSK_INPUTTYPE_LATIN_DIGIT;
break;
}
data.desc = NULL;
data.intext = NULL;
data.outtextlength = input_text_length;
data.outtextlimit = input_text_length;
data.outtext = outtext;
params.base.size = sizeof(params);
sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, &params.base.language);
sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &params.base.buttonSwap);
params.base.graphicsThread = 17;
params.base.accessThread = 19;
params.base.fontThread = 18;
params.base.soundThread = 16;
params.datacount = 1;
params.data = &data;
sceUtilityOskInitStart(&params);
while(!done) {
sceGuStart(GU_DIRECT, list);
sceGuClearColor(0);
sceGuClearDepth(0);
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
sceGuFinish();
sceGuSync(0,0);
switch(sceUtilityOskGetStatus())
{
case PSP_UTILITY_DIALOG_VISIBLE:
sceUtilityOskUpdate(1);
break;
case PSP_UTILITY_DIALOG_QUIT:
sceUtilityOskShutdownStart();
break;
case PSP_UTILITY_DIALOG_NONE:
done = 1;
break;
default :
break;
}
sceDisplayWaitVblankStart();
sceGuSwapBuffers();
}
// Convert input list to string
for (i = 0; i < input_text_length; i++) {
text_string[i] = outtext[i];
}
SDL_SendKeyboardText((const char *) text_string);
}
void PSP_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window)
{
}
bool PSP_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window)
{
return false;
}
#endif // SDL_VIDEO_DRIVER_PSP
@@ -0,0 +1,81 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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_pspvideo_h_
#define SDL_pspvideo_h_
#include <GLES/egl.h>
#include "SDL_internal.h"
#include "../SDL_sysvideo.h"
struct SDL_VideoData
{
bool egl_initialized; // OpenGL ES device initialization status
uint32_t egl_refcount; // OpenGL ES reference count
};
struct SDL_WindowData
{
bool uses_gles; // if true window must support OpenGL ES
};
/****************************************************************************/
// SDL_VideoDevice functions declaration
/****************************************************************************/
// Display and window functions
extern bool PSP_VideoInit(SDL_VideoDevice *_this);
extern void PSP_VideoQuit(SDL_VideoDevice *_this);
extern bool PSP_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
extern bool PSP_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
extern bool PSP_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
extern void PSP_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
extern bool PSP_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window);
extern void PSP_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window);
extern void PSP_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void PSP_HideWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void PSP_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void PSP_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void PSP_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void PSP_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void PSP_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
// OpenGL/OpenGL ES functions
extern bool PSP_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path);
extern SDL_FunctionPointer PSP_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc);
extern void PSP_GL_UnloadLibrary(SDL_VideoDevice *_this);
extern SDL_GLContext PSP_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window);
extern bool PSP_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context);
extern bool PSP_GL_SetSwapInterval(SDL_VideoDevice *_this, int interval);
extern bool PSP_GL_GetSwapInterval(SDL_VideoDevice *_this, int *interval);
extern bool PSP_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern bool PSP_GL_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context);
// PSP on screen keyboard
extern bool PSP_HasScreenKeyboardSupport(SDL_VideoDevice *_this);
extern void PSP_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props);
extern void PSP_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window);
extern bool PSP_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window);
#endif // SDL_pspvideo_h_