From 5a079a2d114f96d4847d1ee305d5b7c16eeec50e Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 27 Dec 2025 12:03:39 -0800 Subject: Initial commit --- .../SDL-3.2.8/src/video/vita/SDL_vitaframebuffer.c | 116 ++++ .../SDL-3.2.8/src/video/vita/SDL_vitaframebuffer.h | 25 + contrib/SDL-3.2.8/src/video/vita/SDL_vitagl_pvr.c | 122 +++++ .../SDL-3.2.8/src/video/vita/SDL_vitagl_pvr_c.h | 31 ++ contrib/SDL-3.2.8/src/video/vita/SDL_vitagles.c | 217 ++++++++ contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_c.h | 53 ++ .../SDL-3.2.8/src/video/vita/SDL_vitagles_pvr.c | 92 ++++ .../SDL-3.2.8/src/video/vita/SDL_vitagles_pvr_c.h | 32 ++ .../SDL-3.2.8/src/video/vita/SDL_vitakeyboard.c | 190 +++++++ .../SDL-3.2.8/src/video/vita/SDL_vitakeyboard.h | 31 ++ .../SDL-3.2.8/src/video/vita/SDL_vitamessagebox.c | 125 +++++ .../SDL-3.2.8/src/video/vita/SDL_vitamessagebox.h | 31 ++ contrib/SDL-3.2.8/src/video/vita/SDL_vitamouse.c | 105 ++++ contrib/SDL-3.2.8/src/video/vita/SDL_vitamouse_c.h | 31 ++ contrib/SDL-3.2.8/src/video/vita/SDL_vitatouch.c | 186 +++++++ contrib/SDL-3.2.8/src/video/vita/SDL_vitatouch.h | 33 ++ contrib/SDL-3.2.8/src/video/vita/SDL_vitavideo.c | 592 +++++++++++++++++++++ contrib/SDL-3.2.8/src/video/vita/SDL_vitavideo.h | 106 ++++ 18 files changed, 2118 insertions(+) create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitaframebuffer.c create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitaframebuffer.h create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitagl_pvr.c create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitagl_pvr_c.h create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitagles.c create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_c.h create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_pvr.c create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_pvr_c.h create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitakeyboard.c create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitakeyboard.h create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitamessagebox.c create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitamessagebox.h create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitamouse.c create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitamouse_c.h create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitatouch.c create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitatouch.h create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitavideo.c create mode 100644 contrib/SDL-3.2.8/src/video/vita/SDL_vitavideo.h (limited to 'contrib/SDL-3.2.8/src/video/vita') diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitaframebuffer.c b/contrib/SDL-3.2.8/src/video/vita/SDL_vitaframebuffer.c new file mode 100644 index 0000000..b9bfb50 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitaframebuffer.c @@ -0,0 +1,116 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_VITA + +#include "SDL_vitavideo.h" + +#include + +#define SCREEN_W 960 +#define SCREEN_H 544 +#define ALIGN(x, a) (((x) + ((a)-1)) & ~((a)-1)) +#define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8 + +void *vita_gpu_alloc(unsigned int type, unsigned int size, SceUID *uid) +{ + void *mem; + + if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) { + size = ALIGN(size, 256 * 1024); + } else { + size = ALIGN(size, 4 * 1024); + } + + *uid = sceKernelAllocMemBlock("gpu_mem", type, size, NULL); + + if (*uid < 0) { + return NULL; + } + + if (sceKernelGetMemBlockBase(*uid, &mem) < 0) { + return NULL; + } + + return mem; +} + +void vita_gpu_free(SceUID uid) +{ + void *mem = NULL; + if (sceKernelGetMemBlockBase(uid, &mem) < 0) { + return; + } + sceKernelFreeMemBlock(uid); +} + +bool VITA_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch) +{ + SDL_WindowData *data = window->internal; + SceDisplayFrameBuf framebuf; + + *format = SDL_PIXELFORMAT_ABGR8888; + *pitch = SCREEN_W * 4; + + data->buffer = vita_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + 4 * SCREEN_W * SCREEN_H, + &data->buffer_uid); + + // SDL_memset the buffer to black + SDL_memset(data->buffer, 0x0, SCREEN_W * SCREEN_H * 4); + + SDL_memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf)); + framebuf.size = sizeof(SceDisplayFrameBuf); + framebuf.base = data->buffer; + framebuf.pitch = SCREEN_W; + framebuf.pixelformat = DISPLAY_PIXEL_FORMAT; + framebuf.width = SCREEN_W; + framebuf.height = SCREEN_H; + sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME); + + *pixels = data->buffer; + + return true; +} + +bool VITA_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects) +{ + // do nothing + return true; +} + +void VITA_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window) +{ + SDL_WindowData *data = window->internal; + + if (!data) { + // The window wasn't fully initialized + return; + } + + vita_gpu_free(data->buffer_uid); + data->buffer = NULL; + return; +} + +#endif // SDL_VIDEO_DRIVER_VITA diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitaframebuffer.h b/contrib/SDL-3.2.8/src/video/vita/SDL_vitaframebuffer.h new file mode 100644 index 0000000..b85e9c3 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitaframebuffer.h @@ -0,0 +1,25 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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" + +extern bool VITA_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch); +extern bool VITA_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects); +extern void VITA_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window); diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitagl_pvr.c b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagl_pvr.c new file mode 100644 index 0000000..1255e4e --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagl_pvr.c @@ -0,0 +1,122 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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" + +#if defined(SDL_VIDEO_DRIVER_VITA) && defined(SDL_VIDEO_VITA_PVR) && defined(SDL_VIDEO_VITA_PVR_OGL) +#include +#include +#include +#include +#include + +#include "SDL_vitavideo.h" +#include "../SDL_egl_c.h" +#include "SDL_vitagl_pvr_c.h" + +#define MAX_PATH 256 // vita limits are somehow wrong + +// Defaults +static int FB_WIDTH = 960; +static int FB_HEIGHT = 544; + +static void getFBSize(int *width, int *height) +{ + *width = FB_WIDTH; + *height = FB_HEIGHT; +} + +bool VITA_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path) +{ + PVRSRV_PSP2_APPHINT hint; + char *default_path = "app0:module"; + char target_path[MAX_PATH]; + + if (SDL_GetHintBoolean(SDL_HINT_VITA_PVR_INIT, true)) { + const char *override = SDL_GetHint(SDL_HINT_VITA_MODULE_PATH); + + if (override && *override) { + default_path = override; + } + + sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL); + sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + PVRSRVInitializeAppHint(&hint); + + SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx"); + SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx"); + SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx"); + + PVRSRVCreateVirtualAppHint(&hint); + } + + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType)0, 0); +} + +SDL_GLContext VITA_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window) +{ + char gl_version[3]; + SDL_GLContext context = NULL; + int temp_major = _this->gl_config.major_version; + int temp_minor = _this->gl_config.minor_version; + int temp_profile = _this->gl_config.profile_mask; + + // Set version to 2.0 and PROFILE to ES + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 0; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; + + context = SDL_EGL_CreateContext(_this, window->internal->egl_surface); + + if (context != NULL) { + FB_WIDTH = window->w; + FB_HEIGHT = window->h; + set_getprocaddress((void *(*)(const char *))eglGetProcAddress); + set_getmainfbsize(getFBSize); + SDL_snprintf(gl_version, 3, "%d%d", temp_major, temp_minor); + gl4es_setenv("LIBGL_NOTEXRECT", "1", 1); // Currently broken in driver + gl4es_setenv("LIBGL_GL", gl_version, 1); + initialize_gl4es(); + } + + // Restore gl_config + _this->gl_config.major_version = temp_major; + _this->gl_config.minor_version = temp_minor; + _this->gl_config.profile_mask = temp_profile; + + return context; +} + +SDL_FunctionPointer VITA_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc) +{ + return gl4es_GetProcAddress(proc); +} + +#endif // SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitagl_pvr_c.h b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagl_pvr_c.h new file mode 100644 index 0000000..118602d --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagl_pvr_c.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_vitagl_pvr_c_h_ +#define SDL_vitagl_pvr_c_h_ + +#include "SDL_vitavideo.h" + +extern SDL_GLContext VITA_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window); +extern int VITA_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path); +extern SDL_FunctionPointer VITA_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc); + +#endif // SDL_vitagl_pvr_c_h_ diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles.c b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles.c new file mode 100644 index 0000000..2c74447 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles.c @@ -0,0 +1,217 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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" + +#if defined(SDL_VIDEO_DRIVER_VITA) && defined(SDL_VIDEO_VITA_PIB) +#include +#include + +#include "SDL_vitavideo.h" +#include "SDL_vitagles_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) + +void VITA_GLES_KeyboardCallback(ScePigletPreSwapData *data) +{ + SceCommonDialogUpdateParam commonDialogParam; + SDL_zero(commonDialogParam); + commonDialogParam.renderTarget.colorFormat = data->colorFormat; + commonDialogParam.renderTarget.surfaceType = data->surfaceType; + commonDialogParam.renderTarget.colorSurfaceData = data->colorSurfaceData; + commonDialogParam.renderTarget.depthSurfaceData = data->depthSurfaceData; + commonDialogParam.renderTarget.width = data->width; + commonDialogParam.renderTarget.height = data->height; + commonDialogParam.renderTarget.strideInPixels = data->strideInPixels; + commonDialogParam.displaySyncObject = data->displaySyncObject; + + sceCommonDialogUpdate(&commonDialogParam); +} + +bool VITA_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path) +{ + pibInit(PIB_SHACCCG | PIB_GET_PROC_ADDR_CORE); + return true; +} + +SDL_FunctionPointer VITA_GLES_GetProcAddress(SDL_VideoDevice *_this, const char *proc) +{ + return eglGetProcAddress(proc); +} + +void VITA_GLES_UnloadLibrary(SDL_VideoDevice *_this) +{ + eglTerminate(_this->gl_data->display); +} + +static EGLint width = 960; +static EGLint height = 544; + +SDL_GLContext VITA_GLES_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; + PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC preSwapCallback; + int i; + + const EGLint contextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + EGLCHK(display = eglGetDisplay(0)); + + EGLCHK(eglInitialize(display, NULL, NULL)); + wdata->uses_gles = true; + window->flags |= SDL_WINDOW_FULLSCREEN; + + EGLCHK(eglBindAPI(EGL_OPENGL_ES_API)); + + i = 0; + attribs[i++] = EGL_RED_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_GREEN_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_BLUE_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_DEPTH_SIZE; + attribs[i++] = 0; + attribs[i++] = EGL_ALPHA_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_STENCIL_SIZE; + attribs[i++] = 0; + + attribs[i++] = EGL_SURFACE_TYPE; + attribs[i++] = 5; + + attribs[i++] = EGL_RENDERABLE_TYPE; + attribs[i++] = EGL_OPENGL_ES2_BIT; + + attribs[i++] = EGL_CONFORMANT; + attribs[i++] = EGL_OPENGL_ES2_BIT; + + 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(surface = eglCreateWindowSurface(display, config, VITA_WINDOW_960X544, NULL)); + + EGLCHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs)); + + EGLCHK(eglMakeCurrent(display, surface, surface, context)); + + EGLCHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); + EGLCHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); + + _this->gl_data->display = display; + _this->gl_data->context = context; + _this->gl_data->surface = surface; + + preSwapCallback = (PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC)eglGetProcAddress("eglPigletVitaSetPreSwapCallbackSCE"); + preSwapCallback(VITA_GLES_KeyboardCallback); + + return context; +} + +bool VITA_GLES_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 VITA_GLES_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 VITA_GLES_GetSwapInterval(SDL_VideoDevice *_this, int *interval) +{ + *interval = _this->gl_data->swapinterval; + return true; +} + +bool VITA_GLES_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 VITA_GLES_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context) +{ + SDL_VideoData *phdata = _this->internal; + EGLBoolean status; + + if (phdata->egl_initialized != true) { + return SDL_SetError("VITA: 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("VITA: OpenGL ES context destroy error"); + } + } + } + + return true; +} + +#endif // SDL_VIDEO_DRIVER_VITA diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_c.h b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_c.h new file mode 100644 index 0000000..44cb14d --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_c.h @@ -0,0 +1,53 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_vitagles_c_h_ +#define SDL_vitagles_c_h_ + +#include +#include +#include +#include +#include + +#include "SDL_vitavideo.h" + +typedef struct SDL_GLDriverData +{ + EGLDisplay display; + EGLContext context; + EGLSurface surface; + uint32_t swapinterval; +} SDL_GLDriverData; + +extern SDL_FunctionPointer VITA_GLES_GetProcAddress(SDL_VideoDevice *_this, const char *proc); +extern bool VITA_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context); +extern void VITA_GLES_SwapBuffers(SDL_VideoDevice *_this); + +extern bool VITA_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern SDL_GLContext VITA_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window); + +extern bool VITA_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path); +extern void VITA_GLES_UnloadLibrary(SDL_VideoDevice *_this); +extern bool VITA_GLES_SetSwapInterval(SDL_VideoDevice *_this, int interval); +extern bool VITA_GLES_GetSwapInterval(SDL_VideoDevice *_this, int *interval); + +#endif // SDL_vitagles_c_h_ diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_pvr.c b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_pvr.c new file mode 100644 index 0000000..4ba0573 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_pvr.c @@ -0,0 +1,92 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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" + +#if defined(SDL_VIDEO_DRIVER_VITA) && defined(SDL_VIDEO_VITA_PVR) +#include +#include +#include +#include + +#include "SDL_vitavideo.h" +#include "../SDL_egl_c.h" +#include "SDL_vitagles_pvr_c.h" + +#define MAX_PATH 256 // vita limits are somehow wrong + +bool VITA_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path) +{ + PVRSRV_PSP2_APPHINT hint; + const char *default_path = "app0:module"; + char target_path[MAX_PATH]; + + if (SDL_GetHintBoolean(SDL_HINT_VITA_PVR_INIT, true)) { + const char *override = SDL_GetHint(SDL_HINT_VITA_MODULE_PATH); + + if (override && *override) { + default_path = override; + } + + sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL); + sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + PVRSRVInitializeAppHint(&hint); + + SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx"); + SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx"); + SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx"); + + PVRSRVCreateVirtualAppHint(&hint); + } + + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType)0, 0); +} + +SDL_GLContext VITA_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window) +{ + return SDL_EGL_CreateContext(_this, window->internal->egl_surface); +} + +bool VITA_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context) +{ + if (window && context) { + return SDL_EGL_MakeCurrent(_this, window->internal->egl_surface, context); + } else { + return SDL_EGL_MakeCurrent(_this, NULL, NULL); + } +} + +bool VITA_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window) +{ + SDL_VideoData *videodata = _this->internal; + if (videodata->ime_active) { + sceImeUpdate(); + } + return SDL_EGL_SwapBuffers(_this, window->internal->egl_surface); +} + +#endif // SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_pvr_c.h b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_pvr_c.h new file mode 100644 index 0000000..ad87212 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitagles_pvr_c.h @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_vitagles_pvr_c_h_ +#define SDL_vitagles_pvr_c_h_ + +#include "SDL_vitavideo.h" + +extern bool VITA_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context); +extern bool VITA_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern SDL_GLContext VITA_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window); +extern bool VITA_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path); + +#endif // SDL_vitagles_pvr_c_h_ diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitakeyboard.c b/contrib/SDL-3.2.8/src/video/vita/SDL_vitakeyboard.c new file mode 100644 index 0000000..9967756 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitakeyboard.c @@ -0,0 +1,190 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_VITA + +#include +#include +#include + +#include "SDL_vitavideo.h" +#include "SDL_vitakeyboard.h" +#include "../../events/SDL_keyboard_c.h" + +SceHidKeyboardReport k_reports[SCE_HID_MAX_REPORT]; +int keyboard_hid_handle = 0; +Uint8 prev_keys[6] = { 0 }; +Uint8 prev_modifiers = 0; +Uint8 locks = 0; +Uint8 lock_key_down = 0; + +void VITA_InitKeyboard(void) +{ +#ifdef SDL_VIDEO_VITA_PVR + sceSysmoduleLoadModule(SCE_SYSMODULE_IME); /** For PVR OSK Support **/ +#endif + sceHidKeyboardEnumerate(&keyboard_hid_handle, 1); + + if (keyboard_hid_handle > 0) { + SDL_AddKeyboard((SDL_KeyboardID)keyboard_hid_handle, NULL, false); + } +} + +void VITA_PollKeyboard(void) +{ + // We skip polling keyboard if no window is created + if (!Vita_Window) { + return; + } + + if (keyboard_hid_handle > 0) { + SDL_KeyboardID keyboardID = (SDL_KeyboardID)keyboard_hid_handle; + int numReports = sceHidKeyboardRead(keyboard_hid_handle, (SceHidKeyboardReport **)&k_reports, SCE_HID_MAX_REPORT); + + if (numReports < 0) { + keyboard_hid_handle = 0; + } else if (numReports) { + // Numlock and Capslock state changes only on a pressed event + // The k_report only reports the state of the LED + if (k_reports[numReports - 1].modifiers[1] & 0x1) { + if (!(locks & 0x1)) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_NUMLOCKCLEAR, true); + locks |= 0x1; + } + } else { + if (locks & 0x1) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_NUMLOCKCLEAR, false); + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_NUMLOCKCLEAR, true); + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_NUMLOCKCLEAR, false); + locks &= ~0x1; + } + } + + if (k_reports[numReports - 1].modifiers[1] & 0x2) { + if (!(locks & 0x2)) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_CAPSLOCK, true); + locks |= 0x2; + } + } else { + if (locks & 0x2) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_CAPSLOCK, false); + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_CAPSLOCK, true); + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_CAPSLOCK, false); + locks &= ~0x2; + } + } + + if (k_reports[numReports - 1].modifiers[1] & 0x4) { + if (!(locks & 0x4)) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_SCROLLLOCK, true); + locks |= 0x4; + } + } else { + if (locks & 0x4) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_SCROLLLOCK, false); + locks &= ~0x4; + } + } + + { + Uint8 changed_modifiers = k_reports[numReports - 1].modifiers[0] ^ prev_modifiers; + + if (changed_modifiers & 0x01) { + if (prev_modifiers & 0x01) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_LCTRL, false); + } else { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_LCTRL, true); + } + } + if (changed_modifiers & 0x02) { + if (prev_modifiers & 0x02) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_LSHIFT, false); + } else { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_LSHIFT, true); + } + } + if (changed_modifiers & 0x04) { + if (prev_modifiers & 0x04) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_LALT, false); + } else { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_LALT, true); + } + } + if (changed_modifiers & 0x08) { + if (prev_modifiers & 0x08) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_LGUI, false); + } else { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_LGUI, true); + } + } + if (changed_modifiers & 0x10) { + if (prev_modifiers & 0x10) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_RCTRL, false); + } else { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_RCTRL, true); + } + } + if (changed_modifiers & 0x20) { + if (prev_modifiers & 0x20) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_RSHIFT, false); + } else { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_RSHIFT, true); + } + } + if (changed_modifiers & 0x40) { + if (prev_modifiers & 0x40) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_RALT, false); + } else { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_RALT, true); + } + } + if (changed_modifiers & 0x80) { + if (prev_modifiers & 0x80) { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_RGUI, false); + } else { + SDL_SendKeyboardKey(0, keyboardID, 0, SDL_SCANCODE_RGUI, true); + } + } + } + + prev_modifiers = k_reports[numReports - 1].modifiers[0]; + + for (int i = 0; i < 6; i++) { + + int keyCode = k_reports[numReports - 1].keycodes[i]; + + if (keyCode != prev_keys[i]) { + + if (prev_keys[i]) { + SDL_SendKeyboardKey(0, keyboardID, 0, prev_keys[i], false); + } + if (keyCode) { + SDL_SendKeyboardKey(0, keyboardID, 0, keyCode, true); + } + prev_keys[i] = keyCode; + } + } + } + } +} + +#endif // SDL_VIDEO_DRIVER_VITA diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitakeyboard.h b/contrib/SDL-3.2.8/src/video/vita/SDL_vitakeyboard.h new file mode 100644 index 0000000..4b52864 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitakeyboard.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_vitakeyboard_h +#define SDL_vitakeyboard_h + +#include "SDL_internal.h" + +// Keyboard functions +extern void VITA_InitKeyboard(void); +extern void VITA_PollKeyboard(void); + +#endif // SDL_vitakeyboard_h diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitamessagebox.c b/contrib/SDL-3.2.8/src/video/vita/SDL_vitamessagebox.c new file mode 100644 index 0000000..a63e156 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitamessagebox.c @@ -0,0 +1,125 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_VITA + +#include "SDL_vitavideo.h" +#include "SDL_vitamessagebox.h" +#include + +#ifdef SDL_VIDEO_RENDER_VITA_GXM +#include "../../render/vitagxm/SDL_render_vita_gxm_tools.h" +#endif // SDL_VIDEO_RENDER_VITA_GXM + +bool VITA_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID) +{ +#ifdef SDL_VIDEO_RENDER_VITA_GXM + SceMsgDialogParam param; + SceMsgDialogUserMessageParam msgParam; + SceMsgDialogButtonsParam buttonParam; + SceDisplayFrameBuf dispparam; + char message[512]; + + SceMsgDialogResult dialog_result; + SceCommonDialogErrorCode init_result; + bool setup_minimal_gxm = false; + + if (messageboxdata->numbuttons > 3) { + return false; + } + + SDL_zero(param); + sceMsgDialogParamInit(¶m); + param.mode = SCE_MSG_DIALOG_MODE_USER_MSG; + + SDL_zero(msgParam); + SDL_snprintf(message, sizeof(message), "%s\r\n\r\n%s", messageboxdata->title, messageboxdata->message); + + msgParam.msg = (const SceChar8 *)message; + SDL_zero(buttonParam); + + if (messageboxdata->numbuttons == 3) { + msgParam.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_3BUTTONS; + msgParam.buttonParam = &buttonParam; + buttonParam.msg1 = messageboxdata->buttons[0].text; + buttonParam.msg2 = messageboxdata->buttons[1].text; + buttonParam.msg3 = messageboxdata->buttons[2].text; + } else if (messageboxdata->numbuttons == 2) { + msgParam.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_YESNO; + } else if (messageboxdata->numbuttons == 1) { + msgParam.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_OK; + } + param.userMsgParam = &msgParam; + + dispparam.size = sizeof(dispparam); + + init_result = sceMsgDialogInit(¶m); + + // Setup display if it hasn't been initialized before + if (init_result == SCE_COMMON_DIALOG_ERROR_GXM_IS_UNINITIALIZED) { + gxm_minimal_init_for_common_dialog(); + init_result = sceMsgDialogInit(¶m); + setup_minimal_gxm = true; + } + + gxm_init_for_common_dialog(); + + if (init_result >= 0) { + while (sceMsgDialogGetStatus() == SCE_COMMON_DIALOG_STATUS_RUNNING) { + gxm_swap_for_common_dialog(); + } + SDL_zero(dialog_result); + sceMsgDialogGetResult(&dialog_result); + + if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_BUTTON1) { + *buttonID = messageboxdata->buttons[0].buttonID; + } else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_BUTTON2) { + *buttonID = messageboxdata->buttons[1].buttonID; + } else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_BUTTON3) { + *buttonID = messageboxdata->buttons[2].buttonID; + } else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_YES) { + *buttonID = messageboxdata->buttons[0].buttonID; + } else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_NO) { + *buttonID = messageboxdata->buttons[1].buttonID; + } else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_OK) { + *buttonID = messageboxdata->buttons[0].buttonID; + } + sceMsgDialogTerm(); + } else { + return false; + } + + gxm_term_for_common_dialog(); + + if (setup_minimal_gxm) { + gxm_minimal_term_for_common_dialog(); + } + + return true; +#else + (void)messageboxdata; + (void)buttonID; + return SDL_Unsupported(); +#endif // SDL_VIDEO_RENDER_VITA_GXM +} + +#endif // SDL_VIDEO_DRIVER_VITA diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitamessagebox.h b/contrib/SDL-3.2.8/src/video/vita/SDL_vitamessagebox.h new file mode 100644 index 0000000..7e4148d --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitamessagebox.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_vitamessagebox_h_ +#define SDL_vitamessagebox_h_ + +#ifdef SDL_VIDEO_DRIVER_VITA + +extern bool VITA_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID); + +#endif // SDL_VIDEO_DRIVER_VITA + +#endif // SDL_vitamessagebox_h_ diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitamouse.c b/contrib/SDL-3.2.8/src/video/vita/SDL_vitamouse.c new file mode 100644 index 0000000..7181023 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitamouse.c @@ -0,0 +1,105 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_VITA + +#include +#include +#include + +#include "SDL_vitavideo.h" +#include "SDL_vitamouse_c.h" +#include "../../events/SDL_mouse_c.h" + +SceHidMouseReport m_reports[SCE_HID_MAX_REPORT]; +int mouse_hid_handle = 0; +Uint8 prev_buttons = 0; + +void VITA_InitMouse(void) +{ + sceHidMouseEnumerate(&mouse_hid_handle, 1); + + if (mouse_hid_handle > 0) { + SDL_AddMouse((SDL_MouseID)mouse_hid_handle, NULL, false); + } +} + +void VITA_PollMouse(void) +{ + // We skip polling mouse if no window is created + if (!Vita_Window) { + return; + } + + if (mouse_hid_handle > 0) { + SDL_MouseID mouseID = (SDL_MouseID)mouse_hid_handle; + int numReports = sceHidMouseRead(mouse_hid_handle, (SceHidMouseReport **)&m_reports, SCE_HID_MAX_REPORT); + if (numReports > 0) { + for (int i = 0; i <= numReports - 1; i++) { + Uint8 changed_buttons = m_reports[i].buttons ^ prev_buttons; + + if (changed_buttons & 0x1) { + if (prev_buttons & 0x1) + SDL_SendMouseButton(0, Vita_Window, mouseID, SDL_BUTTON_LEFT, false); + else + SDL_SendMouseButton(0, Vita_Window, mouseID, SDL_BUTTON_LEFT, true); + } + if (changed_buttons & 0x2) { + if (prev_buttons & 0x2) + SDL_SendMouseButton(0, Vita_Window, mouseID, SDL_BUTTON_RIGHT, false); + else + SDL_SendMouseButton(0, Vita_Window, mouseID, SDL_BUTTON_RIGHT, true); + } + if (changed_buttons & 0x4) { + if (prev_buttons & 0x4) + SDL_SendMouseButton(0, Vita_Window, mouseID, SDL_BUTTON_MIDDLE, false); + else + SDL_SendMouseButton(0, Vita_Window, mouseID, SDL_BUTTON_MIDDLE, true); + } + if (changed_buttons & 0x8) { + if (prev_buttons & 0x8) + SDL_SendMouseButton(0, Vita_Window, mouseID, SDL_BUTTON_X1, false); + else + SDL_SendMouseButton(0, Vita_Window, mouseID, SDL_BUTTON_X1, true); + } + if (changed_buttons & 0x10) { + if (prev_buttons & 0x10) + SDL_SendMouseButton(0, Vita_Window, mouseID, SDL_BUTTON_X2, false); + else + SDL_SendMouseButton(0, Vita_Window, mouseID, SDL_BUTTON_X2, true); + } + + prev_buttons = m_reports[i].buttons; + + if (m_reports[i].rel_x || m_reports[i].rel_y) { + SDL_SendMouseMotion(0, Vita_Window, mouseID, true, (float)m_reports[i].rel_x, (float)m_reports[i].rel_y); + } + + if (m_reports[i].tilt != 0 || m_reports[i].wheel != 0) { + SDL_SendMouseWheel(0, Vita_Window, mouseID, m_reports[i].tilt, m_reports[i].wheel, SDL_MOUSEWHEEL_NORMAL); + } + } + } + } +} + +#endif // SDL_VIDEO_DRIVER_VITA diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitamouse_c.h b/contrib/SDL-3.2.8/src/video/vita/SDL_vitamouse_c.h new file mode 100644 index 0000000..ef6a7c9 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitamouse_c.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_vitamouse_h +#define SDL_vitamouse_h + +#include "SDL_internal.h" + +// mouse functions +extern void VITA_InitMouse(void); +extern void VITA_PollMouse(void); + +#endif // SDL_vitamouse_h diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitatouch.c b/contrib/SDL-3.2.8/src/video/vita/SDL_vitatouch.c new file mode 100644 index 0000000..ac6f764 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitatouch.c @@ -0,0 +1,186 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_VITA + +#include +#include + +#include "SDL_vitavideo.h" +#include "SDL_vitatouch.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" + +SceTouchData touch_old[SCE_TOUCH_PORT_MAX_NUM]; +SceTouchData touch[SCE_TOUCH_PORT_MAX_NUM]; + +SDL_FRect area_info[SCE_TOUCH_PORT_MAX_NUM]; + +struct +{ + float min; + float range; +} force_info[SCE_TOUCH_PORT_MAX_NUM]; + +static bool disableFrontPoll; +static bool disableBackPoll; + +void VITA_InitTouch(void) +{ + disableFrontPoll = !SDL_GetHintBoolean(SDL_HINT_VITA_ENABLE_FRONT_TOUCH, true); + disableBackPoll = !SDL_GetHintBoolean(SDL_HINT_VITA_ENABLE_BACK_TOUCH, true); + + sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START); + sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, SCE_TOUCH_SAMPLING_STATE_START); + sceTouchEnableTouchForce(SCE_TOUCH_PORT_FRONT); + sceTouchEnableTouchForce(SCE_TOUCH_PORT_BACK); + + for (int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) { + SceTouchPanelInfo panelinfo; + sceTouchGetPanelInfo(port, &panelinfo); + + area_info[port].x = (float)panelinfo.minAaX; + area_info[port].y = (float)panelinfo.minAaY; + area_info[port].w = (float)(panelinfo.maxAaX - panelinfo.minAaX); + area_info[port].h = (float)(panelinfo.maxAaY - panelinfo.minAaY); + + force_info[port].min = (float)panelinfo.minForce; + force_info[port].range = (float)(panelinfo.maxForce - panelinfo.minForce); + } + + // Support passing both front and back touch devices in events + SDL_AddTouch(1, SDL_TOUCH_DEVICE_DIRECT, "Front"); + SDL_AddTouch(2, SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, "Back"); +} + +void VITA_QuitTouch(void) +{ + sceTouchDisableTouchForce(SCE_TOUCH_PORT_FRONT); + sceTouchDisableTouchForce(SCE_TOUCH_PORT_BACK); +} + +void VITA_PollTouch(void) +{ + SDL_TouchID touch_id; + SDL_FingerID finger_id; + int port; + + // We skip polling touch if no window is created + if (!Vita_Window) { + return; + } + + SDL_memcpy(touch_old, touch, sizeof(touch_old)); + + for (port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) { + /** Skip polling of Touch Device if hint is set **/ + if (((port == 0) && disableFrontPoll) || ((port == 1) && disableBackPoll)) { + continue; + } + sceTouchPeek(port, &touch[port], 1); + + touch_id = (SDL_TouchID)(port + 1); + + if (touch[port].reportNum > 0) { + for (int i = 0; i < touch[port].reportNum; i++) { + // adjust coordinates and forces to return normalized values + // for the front, screen area is used as a reference (for direct touch) + // e.g. touch_x = 1.0 corresponds to screen_x = 960 + // for the back panel, the active touch area is used as reference + float x = 0; + float y = 0; + float force = (touch[port].report[i].force - force_info[port].min) / force_info[port].range; + int finger_down = 0; + + if (touch_old[port].reportNum > 0) { + for (int j = 0; j < touch_old[port].reportNum; j++) { + if (touch[port].report[i].id == touch_old[port].report[j].id) { + finger_down = 1; + } + } + } + + VITA_ConvertTouchXYToSDLXY(&x, &y, touch[port].report[i].x, touch[port].report[i].y, port); + finger_id = (SDL_FingerID)(touch[port].report[i].id + 1); + + // Skip if finger was already previously down + if (!finger_down) { + // Send an initial touch + SDL_SendTouch(0, touch_id, finger_id, Vita_Window, SDL_EVENT_FINGER_DOWN, x, y, force); + } + + // Always send the motion + SDL_SendTouchMotion(0, touch_id, finger_id, Vita_Window, x, y, force); + } + } + + // some fingers might have been let go + if (touch_old[port].reportNum > 0) { + for (int i = 0; i < touch_old[port].reportNum; i++) { + int finger_up = 1; + if (touch[port].reportNum > 0) { + for (int j = 0; j < touch[port].reportNum; j++) { + if (touch[port].report[j].id == touch_old[port].report[i].id) { + finger_up = 0; + } + } + } + if (finger_up == 1) { + float x = 0; + float y = 0; + float force = (touch_old[port].report[i].force - force_info[port].min) / force_info[port].range; + VITA_ConvertTouchXYToSDLXY(&x, &y, touch_old[port].report[i].x, touch_old[port].report[i].y, port); + finger_id = (SDL_FingerID)(touch_old[port].report[i].id + 1); + // Finger released from screen + SDL_SendTouch(0, touch_id, finger_id, Vita_Window, SDL_EVENT_FINGER_UP, x, y, force); + } + } + } + } +} + +void VITA_ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port) +{ + float x, y; + + if (area_info[port].w <= 1) { + x = 0.5f; + } else { + x = (vita_x - area_info[port].x) / (area_info[port].w - 1); + } + if (area_info[port].h <= 1) { + y = 0.5f; + } else { + y = (vita_y - area_info[port].y) / (area_info[port].h - 1); + } + + x = SDL_max(x, 0.0f); + x = SDL_min(x, 1.0f); + + y = SDL_max(y, 0.0f); + y = SDL_min(y, 1.0f); + + *sdl_x = x; + *sdl_y = y; +} + +#endif // SDL_VIDEO_DRIVER_VITA diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitatouch.h b/contrib/SDL-3.2.8/src/video/vita/SDL_vitatouch.h new file mode 100644 index 0000000..b94051a --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitatouch.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_vitatouch_h +#define SDL_vitatouch_h + +#include "SDL_internal.h" + +// Touch functions +extern void VITA_InitTouch(void); +extern void VITA_QuitTouch(void); +extern void VITA_PollTouch(void); +void VITA_ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port); + +#endif // SDL_vitatouch_h diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitavideo.c b/contrib/SDL-3.2.8/src/video/vita/SDL_vitavideo.c new file mode 100644 index 0000000..6b5dbd7 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitavideo.c @@ -0,0 +1,592 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_VITA + +// SDL internals +#include "../SDL_sysvideo.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_keyboard_c.h" + +// VITA declarations +#include +#include "SDL_vitavideo.h" +#include "SDL_vitatouch.h" +#include "SDL_vitakeyboard.h" +#include "SDL_vitamouse_c.h" +#include "SDL_vitaframebuffer.h" +#include "SDL_vitamessagebox.h" + +#ifdef SDL_VIDEO_VITA_PIB +#include "SDL_vitagles_c.h" +#elif defined(SDL_VIDEO_VITA_PVR) +#include "SDL_vitagles_pvr_c.h" +#ifdef SDL_VIDEO_VITA_PVR_OGL +#include "SDL_vitagl_pvr_c.h" +#endif +#define VITA_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal +#define VITA_GLES_UnloadLibrary SDL_EGL_UnloadLibrary +#define VITA_GLES_SetSwapInterval SDL_EGL_SetSwapInterval +#define VITA_GLES_GetSwapInterval SDL_EGL_GetSwapInterval +#define VITA_GLES_DestroyContext SDL_EGL_DestroyContext +#endif + +SDL_Window *Vita_Window; + +static void VITA_Destroy(SDL_VideoDevice *device) +{ + SDL_free(device->internal); + SDL_free(device); +} + +static SDL_VideoDevice *VITA_Create(void) +{ + SDL_VideoDevice *device; + SDL_VideoData *phdata; +#ifdef SDL_VIDEO_VITA_PIB + SDL_GLDriverData *gldata; +#endif + // Initialize SDL_VideoDevice structure + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + return NULL; + } + + // Initialize internal VITA specific data + phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); + if (!phdata) { + SDL_free(device); + return NULL; + } +#ifdef SDL_VIDEO_VITA_PIB + + gldata = (SDL_GLDriverData *)SDL_calloc(1, sizeof(SDL_GLDriverData)); + if (!gldata) { + SDL_free(device); + SDL_free(phdata); + return NULL; + } + device->gl_data = gldata; + phdata->egl_initialized = true; +#endif + phdata->ime_active = false; + + device->internal = phdata; + + // Setup amount of available displays and current display + device->num_displays = 0; + + // Set device free function + device->free = VITA_Destroy; + + // Setup all functions which we can handle + device->VideoInit = VITA_VideoInit; + device->VideoQuit = VITA_VideoQuit; + device->CreateSDLWindow = VITA_CreateWindow; + device->SetWindowTitle = VITA_SetWindowTitle; + device->SetWindowPosition = VITA_SetWindowPosition; + device->SetWindowSize = VITA_SetWindowSize; + device->ShowWindow = VITA_ShowWindow; + device->HideWindow = VITA_HideWindow; + device->RaiseWindow = VITA_RaiseWindow; + device->MaximizeWindow = VITA_MaximizeWindow; + device->MinimizeWindow = VITA_MinimizeWindow; + device->RestoreWindow = VITA_RestoreWindow; + device->SetWindowMouseGrab = VITA_SetWindowGrab; + device->SetWindowKeyboardGrab = VITA_SetWindowGrab; + device->DestroyWindow = VITA_DestroyWindow; + + /* + // Disabled, causes issues on high-framerate updates. SDL still emulates this. + device->CreateWindowFramebuffer = VITA_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = VITA_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = VITA_DestroyWindowFramebuffer; + */ + +#if defined(SDL_VIDEO_VITA_PIB) || defined(SDL_VIDEO_VITA_PVR) +#ifdef SDL_VIDEO_VITA_PVR_OGL + if (SDL_GetHintBoolean(SDL_HINT_VITA_PVR_OPENGL, false)) { + device->GL_LoadLibrary = VITA_GL_LoadLibrary; + device->GL_CreateContext = VITA_GL_CreateContext; + device->GL_GetProcAddress = VITA_GL_GetProcAddress; + } else { +#endif + device->GL_LoadLibrary = VITA_GLES_LoadLibrary; + device->GL_CreateContext = VITA_GLES_CreateContext; + device->GL_GetProcAddress = VITA_GLES_GetProcAddress; +#ifdef SDL_VIDEO_VITA_PVR_OGL + } +#endif + + device->GL_UnloadLibrary = VITA_GLES_UnloadLibrary; + device->GL_MakeCurrent = VITA_GLES_MakeCurrent; + device->GL_SetSwapInterval = VITA_GLES_SetSwapInterval; + device->GL_GetSwapInterval = VITA_GLES_GetSwapInterval; + device->GL_SwapWindow = VITA_GLES_SwapWindow; + device->GL_DestroyContext = VITA_GLES_DestroyContext; +#endif + + device->HasScreenKeyboardSupport = VITA_HasScreenKeyboardSupport; + device->ShowScreenKeyboard = VITA_ShowScreenKeyboard; + device->HideScreenKeyboard = VITA_HideScreenKeyboard; + device->IsScreenKeyboardShown = VITA_IsScreenKeyboardShown; + + device->PumpEvents = VITA_PumpEvents; + + return device; +} + +VideoBootStrap VITA_bootstrap = { + "vita", + "VITA Video Driver", + VITA_Create, + VITA_ShowMessageBox, + false +}; + +/*****************************************************************************/ +// SDL Video and Display initialization/handling functions +/*****************************************************************************/ +bool VITA_VideoInit(SDL_VideoDevice *_this) +{ + SDL_DisplayMode mode; +#ifdef SDL_VIDEO_VITA_PVR + const char *res = SDL_GetHint(SDL_HINT_VITA_RESOLUTION); +#endif + SDL_zero(mode); + +#ifdef SDL_VIDEO_VITA_PVR + if (res) { + // 1088i for PSTV (Or Sharpscale) + if (SDL_strncmp(res, "1080", 4) == 0) { + mode.w = 1920; + mode.h = 1088; + } + // 725p for PSTV (Or Sharpscale) + else if (SDL_strncmp(res, "720", 3) == 0) { + mode.w = 1280; + mode.h = 725; + } + } + // 544p + else { +#endif + mode.w = 960; + mode.h = 544; +#ifdef SDL_VIDEO_VITA_PVR + } +#endif + + mode.refresh_rate = 60.0f; + + // 32 bpp for default + mode.format = SDL_PIXELFORMAT_ABGR8888; + + if (SDL_AddBasicVideoDisplay(&mode) == 0) { + return false; + } + + VITA_InitTouch(); + VITA_InitKeyboard(); + VITA_InitMouse(); + + return true; +} + +void VITA_VideoQuit(SDL_VideoDevice *_this) +{ + VITA_QuitTouch(); +} + +bool VITA_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props) +{ + SDL_WindowData *wdata; +#ifdef SDL_VIDEO_VITA_PVR + Psp2NativeWindow win; + int temp_major = 2; + int temp_minor = 1; + int temp_profile = 0; +#endif + + // 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; + + // Vita can only have one window + if (Vita_Window) { + return SDL_SetError("Only one window supported"); + } + + Vita_Window = window; + +#ifdef SDL_VIDEO_VITA_PVR + win.type = PSP2_DRAWABLE_TYPE_WINDOW; + win.numFlipBuffers = 2; + win.flipChainThrdAffinity = 0x20000; + + // 1088i for PSTV (Or Sharpscale) + if (window->w == 1920) { + win.windowSize = PSP2_WINDOW_1920X1088; + } + // 725p for PSTV (Or Sharpscale) + else if (window->w == 1280) { + win.windowSize = PSP2_WINDOW_1280X725; + } + // 544p + else { + win.windowSize = PSP2_WINDOW_960X544; + } + if (window->flags & SDL_WINDOW_OPENGL) { + bool use_opengl = SDL_GetHintBoolean(SDL_HINT_VITA_PVR_OPENGL, false); + if (use_opengl) { + // Set version to 2.1 and PROFILE to ES + temp_major = _this->gl_config.major_version; + temp_minor = _this->gl_config.minor_version; + temp_profile = _this->gl_config.profile_mask; + + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 1; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; + } + wdata->egl_surface = SDL_EGL_CreateSurface(_this, window, &win); + if (wdata->egl_surface == EGL_NO_SURFACE) { + return SDL_SetError("Could not create GLES window surface"); + } + if (use_opengl) { + // Revert + _this->gl_config.major_version = temp_major; + _this->gl_config.minor_version = temp_minor; + _this->gl_config.profile_mask = temp_profile; + } + } +#endif + + // fix input, we need to find a better way + SDL_SetKeyboardFocus(window); + + // Window has been successfully created + return true; +} + +void VITA_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window) +{ +} +bool VITA_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window) +{ + return SDL_Unsupported(); +} +void VITA_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window) +{ +} +void VITA_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) +{ +} +void VITA_HideWindow(SDL_VideoDevice *_this, SDL_Window *window) +{ +} +void VITA_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window) +{ +} +void VITA_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window) +{ +} +void VITA_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window) +{ +} +void VITA_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window) +{ +} +bool VITA_SetWindowGrab(SDL_VideoDevice *_this, SDL_Window *window, bool grabbed) +{ + return true; +} + +void VITA_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window) +{ + SDL_WindowData *data; + + data = window->internal; + if (data) { + // TODO: should we destroy egl context? No one sane should recreate ogl window as non-ogl + SDL_free(data); + } + + window->internal = NULL; + Vita_Window = NULL; +} + +bool VITA_HasScreenKeyboardSupport(SDL_VideoDevice *_this) +{ + return true; +} + +#ifndef SCE_IME_LANGUAGE_ENGLISH_US +#define SCE_IME_LANGUAGE_ENGLISH_US SCE_IME_LANGUAGE_ENGLISH +#endif + +static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) +{ + int i; + for (i = 0; src[i]; i++) { + if (!(src[i] & 0xFF80)) { + *(dst++) = src[i] & 0xFF; + } else if (!(src[i] & 0xF800)) { + *(dst++) = ((src[i] >> 6) & 0xFF) | 0xC0; + *(dst++) = (src[i] & 0x3F) | 0x80; + } else if ((src[i] & 0xFC00) == 0xD800 && (src[i + 1] & 0xFC00) == 0xDC00) { + *(dst++) = (((src[i] + 64) >> 8) & 0x3) | 0xF0; + *(dst++) = (((src[i] >> 2) + 16) & 0x3F) | 0x80; + *(dst++) = ((src[i] >> 4) & 0x30) | 0x80 | ((src[i + 1] << 2) & 0xF); + *(dst++) = (src[i + 1] & 0x3F) | 0x80; + i += 1; + } else { + *(dst++) = ((src[i] >> 12) & 0xF) | 0xE0; + *(dst++) = ((src[i] >> 6) & 0x3F) | 0x80; + *(dst++) = (src[i] & 0x3F) | 0x80; + } + } + + *dst = '\0'; +} + +#ifdef SDL_VIDEO_VITA_PVR +SceWChar16 libime_out[SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1]; +char libime_initval[8] = { 1 }; +SceImeCaret caret_rev; + +void VITA_ImeEventHandler(void *arg, const SceImeEventData *e) +{ + SDL_VideoData *videodata = (SDL_VideoData *)arg; + uint8_t utf8_buffer[SCE_IME_MAX_TEXT_LENGTH]; + switch (e->id) { + case SCE_IME_EVENT_UPDATE_TEXT: + if (e->param.text.caretIndex == 0) { + SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_BACKSPACE); + sceImeSetText((SceWChar16 *)libime_initval, 4); + } else { + utf16_to_utf8((SceWChar16 *)&libime_out[1], utf8_buffer); + if (utf8_buffer[0] == ' ') { + SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_SPACE); + } else { + SDL_SendKeyboardText((const char *)utf8_buffer); + } + SDL_memset(&caret_rev, 0, sizeof(SceImeCaret)); + SDL_memset(libime_out, 0, ((SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1) * sizeof(SceWChar16))); + caret_rev.index = 1; + sceImeSetCaret(&caret_rev); + sceImeSetText((SceWChar16 *)libime_initval, 4); + } + break; + case SCE_IME_EVENT_PRESS_ENTER: + SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RETURN); + break; + case SCE_IME_EVENT_PRESS_CLOSE: + sceImeClose(); + videodata->ime_active = false; + break; + } +} +#endif + +void VITA_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props) +{ + SDL_VideoData *videodata = _this->internal; + SceInt32 res; + +#ifdef SDL_VIDEO_VITA_PVR + + SceUInt32 libime_work[SCE_IME_WORK_BUFFER_SIZE / sizeof(SceInt32)]; + SceImeParam param; + + sceImeParamInit(¶m); + + SDL_memset(libime_out, 0, ((SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1) * sizeof(SceWChar16))); + + param.supportedLanguages = SCE_IME_LANGUAGE_ENGLISH_US; + param.languagesForced = SCE_FALSE; + switch (SDL_GetTextInputType(props)) { + default: + case SDL_TEXTINPUT_TYPE_TEXT: + param.type = SCE_IME_TYPE_DEFAULT; + break; + case SDL_TEXTINPUT_TYPE_TEXT_NAME: + param.type = SCE_IME_TYPE_DEFAULT; + break; + case SDL_TEXTINPUT_TYPE_TEXT_EMAIL: + param.type = SCE_IME_TYPE_MAIL; + break; + case SDL_TEXTINPUT_TYPE_TEXT_USERNAME: + param.type = SCE_IME_TYPE_DEFAULT; + break; + case SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_HIDDEN: + param.type = SCE_IME_TYPE_DEFAULT; + break; + case SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_VISIBLE: + param.type = SCE_IME_TYPE_DEFAULT; + break; + case SDL_TEXTINPUT_TYPE_NUMBER: + param.type = SCE_IME_TYPE_NUMBER; + break; + case SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_HIDDEN: + param.type = SCE_IME_TYPE_NUMBER; + break; + case SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_VISIBLE: + param.type = SCE_IME_TYPE_NUMBER; + break; + } + param.option = 0; + if (SDL_GetTextInputCapitalization(props) != SDL_CAPITALIZE_SENTENCES) { + param.option |= SCE_IME_OPTION_NO_AUTO_CAPITALIZATION; + } + if (!SDL_GetTextInputAutocorrect(props)) { + param.option |= SCE_IME_OPTION_NO_ASSISTANCE; + } + if (SDL_GetTextInputMultiline(props)) { + param.option |= SCE_IME_OPTION_MULTILINE; + } + param.inputTextBuffer = libime_out; + param.maxTextLength = SCE_IME_MAX_TEXT_LENGTH; + param.handler = VITA_ImeEventHandler; + param.filter = NULL; + param.initialText = (SceWChar16 *)libime_initval; + param.arg = videodata; + param.work = libime_work; + + res = sceImeOpen(¶m); + if (res < 0) { + SDL_SetError("Failed to init IME"); + return; + } + +#else + SceWChar16 *title = u""; + SceWChar16 *text = u""; + + SceImeDialogParam param; + sceImeDialogParamInit(¶m); + + param.supportedLanguages = 0; + param.languagesForced = SCE_FALSE; + param.type = SCE_IME_TYPE_DEFAULT; + param.option = 0; + param.textBoxMode = SCE_IME_DIALOG_TEXTBOX_MODE_WITH_CLEAR; + param.maxTextLength = SCE_IME_DIALOG_MAX_TEXT_LENGTH; + + param.title = title; + param.initialText = text; + param.inputTextBuffer = videodata->ime_buffer; + + res = sceImeDialogInit(¶m); + if (res < 0) { + SDL_SetError("Failed to init IME dialog"); + return; + } + +#endif + + videodata->ime_active = true; +} + +void VITA_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window) +{ +#ifndef SDL_VIDEO_VITA_PVR + SDL_VideoData *videodata = _this->internal; + + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + + switch (dialogStatus) { + default: + case SCE_COMMON_DIALOG_STATUS_NONE: + case SCE_COMMON_DIALOG_STATUS_RUNNING: + break; + case SCE_COMMON_DIALOG_STATUS_FINISHED: + sceImeDialogTerm(); + break; + } + + videodata->ime_active = false; +#endif +} + +bool VITA_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window) +{ +#ifdef SDL_VIDEO_VITA_PVR + SDL_VideoData *videodata = _this->internal; + return videodata->ime_active; +#else + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + return dialogStatus == SCE_COMMON_DIALOG_STATUS_RUNNING; +#endif +} + +void VITA_PumpEvents(SDL_VideoDevice *_this) +{ +#ifndef SDL_VIDEO_VITA_PVR + SDL_VideoData *videodata = _this->internal; +#endif + + if (_this->suspend_screensaver) { + // cancel all idle timers to prevent vita going to sleep + sceKernelPowerTick(SCE_KERNEL_POWER_TICK_DEFAULT); + } + + VITA_PollTouch(); + VITA_PollKeyboard(); + VITA_PollMouse(); + +#ifndef SDL_VIDEO_VITA_PVR + if (videodata->ime_active == true) { + // update IME status. Terminate, if finished + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + if (dialogStatus == SCE_COMMON_DIALOG_STATUS_FINISHED) { + uint8_t utf8_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; + + SceImeDialogResult result; + SDL_memset(&result, 0, sizeof(SceImeDialogResult)); + sceImeDialogGetResult(&result); + + // Convert UTF16 to UTF8 + utf16_to_utf8(videodata->ime_buffer, utf8_buffer); + + // Send SDL event + SDL_SendKeyboardText((const char *)utf8_buffer); + + // Send enter key only on enter + if (result.button == SCE_IME_DIALOG_BUTTON_ENTER) { + SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RETURN); + } + + sceImeDialogTerm(); + + videodata->ime_active = false; + } + } +#endif +} + +#endif // SDL_VIDEO_DRIVER_VITA diff --git a/contrib/SDL-3.2.8/src/video/vita/SDL_vitavideo.h b/contrib/SDL-3.2.8/src/video/vita/SDL_vitavideo.h new file mode 100644 index 0000000..268bed8 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/vita/SDL_vitavideo.h @@ -0,0 +1,106 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 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_vitavideo_h +#define SDL_vitavideo_h + +#include "SDL_internal.h" +#include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" + +#include +#include +#include +#include + +struct SDL_VideoData +{ + bool egl_initialized; // OpenGL device initialization status + uint32_t egl_refcount; // OpenGL reference count + + SceWChar16 ime_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; + bool ime_active; +}; + +struct SDL_WindowData +{ + bool uses_gles; + SceUID buffer_uid; + void *buffer; +#ifdef SDL_VIDEO_VITA_PVR + EGLSurface egl_surface; + EGLContext egl_context; +#endif +}; + +extern SDL_Window *Vita_Window; + +/****************************************************************************/ +// SDL_VideoDevice functions declaration +/****************************************************************************/ + +// Display and window functions +extern bool VITA_VideoInit(SDL_VideoDevice *_this); +extern void VITA_VideoQuit(SDL_VideoDevice *_this); +extern bool VITA_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display); +extern bool VITA_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode); +extern bool VITA_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props); +extern void VITA_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window); +extern bool VITA_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window); +extern void VITA_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window); +extern void VITA_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void VITA_HideWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void VITA_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void VITA_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void VITA_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern void VITA_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern bool VITA_SetWindowGrab(SDL_VideoDevice *_this, SDL_Window *window, bool grabbed); +extern void VITA_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window); + +#ifdef SDL_VIDEO_DRIVER_VITA +#ifdef SDL_VIDEO_VITA_PVR_OGL +// OpenGL functions +extern bool VITA_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path); +extern SDL_GLContext VITA_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window); +extern SDL_FunctionPointer VITA_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc); +#endif + +// OpenGLES functions +extern bool VITA_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path); +extern SDL_FunctionPointer VITA_GLES_GetProcAddress(SDL_VideoDevice *_this, const char *proc); +extern void VITA_GLES_UnloadLibrary(SDL_VideoDevice *_this); +extern SDL_GLContext VITA_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window); +extern bool VITA_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context); +extern bool VITA_GLES_SetSwapInterval(SDL_VideoDevice *_this, int interval); +extern bool VITA_GLES_GetSwapInterval(SDL_VideoDevice *_this, int *interval); +extern bool VITA_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window); +extern bool VITA_GLES_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context); +#endif + +// VITA on screen keyboard +extern bool VITA_HasScreenKeyboardSupport(SDL_VideoDevice *_this); +extern void VITA_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props); +extern void VITA_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window); +extern bool VITA_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window); + +extern void VITA_PumpEvents(SDL_VideoDevice *_this); + +#endif // SDL_pspvideo_h -- cgit v1.2.3