This commit is contained in:
Nitload
2025-08-25 09:50:30 +08:00
parent bd0e31e922
commit 1359ff4ecc
1630 changed files with 738486 additions and 2399 deletions
@@ -0,0 +1,116 @@
/*
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_VITA
#include "SDL_vitavideo.h"
#include <psp2/kernel/sysmem.h>
#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
@@ -0,0 +1,25 @@
/*
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"
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);
@@ -0,0 +1,121 @@
/*
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"
#if defined(SDL_VIDEO_DRIVER_VITA) && defined(SDL_VIDEO_VITA_PVR) && defined(SDL_VIDEO_VITA_PVR_OGL)
#include <stdlib.h>
#include <string.h>
#include <psp2/kernel/modulemgr.h>
#include <gpu_es4/psp2_pvr_hint.h>
#include <gl4esinit.h>
#include "SDL_vitavideo.h"
#include "../SDL_egl_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
@@ -0,0 +1,216 @@
/*
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"
#if defined(SDL_VIDEO_DRIVER_VITA) && defined(SDL_VIDEO_VITA_PIB)
#include <stdlib.h>
#include <string.h>
#include "SDL_vitavideo.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
@@ -0,0 +1,91 @@
/*
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"
#if defined(SDL_VIDEO_DRIVER_VITA) && defined(SDL_VIDEO_VITA_PVR)
#include <stdlib.h>
#include <string.h>
#include <psp2/kernel/modulemgr.h>
#include <gpu_es4/psp2_pvr_hint.h>
#include "SDL_vitavideo.h"
#include "../SDL_egl_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
@@ -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_VITA
#include <psp2/kernel/processmgr.h>
#include <psp2/ctrl.h>
#include <psp2/hid.h>
#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
@@ -0,0 +1,31 @@
/*
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_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
@@ -0,0 +1,125 @@
/*
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_VITA
#include "SDL_vitavideo.h"
#include "SDL_vitamessagebox.h"
#include <psp2/message_dialog.h>
#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(&param);
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(&param);
// 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(&param);
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
@@ -0,0 +1,31 @@
/*
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_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_
@@ -0,0 +1,105 @@
/*
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_VITA
#include <psp2/kernel/processmgr.h>
#include <psp2/ctrl.h>
#include <psp2/hid.h>
#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
@@ -0,0 +1,31 @@
/*
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_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
@@ -0,0 +1,186 @@
/*
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_VITA
#include <psp2/kernel/processmgr.h>
#include <psp2/touch.h>
#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
@@ -0,0 +1,33 @@
/*
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_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
@@ -0,0 +1,588 @@
/*
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_VITA
// SDL internals
#include "../SDL_sysvideo.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
// VITA declarations
#include <psp2/kernel/processmgr.h>
#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"
#if defined(SDL_VIDEO_VITA_PVR)
#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;
device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY;
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(&param);
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(&param);
if (res < 0) {
SDL_SetError("Failed to init IME");
return;
}
#else
SceWChar16 *title = u"";
SceWChar16 *text = u"";
SceImeDialogParam param;
sceImeDialogParamInit(&param);
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(&param);
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
@@ -0,0 +1,121 @@
/*
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_vitavideo_h
#define SDL_vitavideo_h
#include "SDL_internal.h"
#include "../SDL_sysvideo.h"
#include "../SDL_egl_c.h"
#include <psp2/types.h>
#include <psp2/display.h>
#include <psp2/ime_dialog.h>
#include <psp2/sysmodule.h>
#ifdef SDL_VIDEO_VITA_PIB
#include <psp2/gxm.h>
#include <psp2/display.h>
#include <pib.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
typedef struct SDL_GLDriverData
{
EGLDisplay display;
EGLContext context;
EGLSurface surface;
uint32_t swapinterval;
} SDL_GLDriverData;
#endif
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_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