From 2d64e37e41eb6ab4795bba90aee26269100ff770 Mon Sep 17 00:00:00 2001
From: Ivan Epifanov <[EMAIL REDACTED]>
Date: Mon, 2 Nov 2020 18:09:43 +0300
Subject: [PATCH] Initial rebase of xerpi's port
---
Makefile.vita.dolce | 59 +++++
include/SDL_config.h | 2 +
include/SDL_config_vita.h | 158 +++++++++++++
src/SDL.c | 2 +
src/SDL_log.c | 7 +
src/audio/SDL_audio.c | 3 +
src/audio/SDL_sysaudio.h | 1 +
src/audio/vita/SDL_vitaaudio.c | 203 +++++++++++++++++
src/audio/vita/SDL_vitaaudio.h | 45 ++++
src/cpuinfo/SDL_cpuinfo.c | 2 +
src/dynapi/SDL_dynapi.h | 2 +
src/joystick/SDL_gamecontrollerdb.h | 4 +
src/joystick/vita/SDL_sysjoystick.c | 310 +++++++++++++++++++++++++
src/power/SDL_power.c | 3 +
src/power/SDL_syspower.h | 1 +
src/power/vita/SDL_syspower.c | 68 ++++++
src/thread/SDL_thread_c.h | 2 +
src/thread/vita/SDL_syscond.c | 224 ++++++++++++++++++
src/thread/vita/SDL_sysmutex.c | 136 +++++++++++
src/thread/vita/SDL_sysmutex_c.h | 22 ++
src/thread/vita/SDL_syssem.c | 163 +++++++++++++
src/thread/vita/SDL_systhread.c | 112 +++++++++
src/thread/vita/SDL_systhread_c.h | 24 ++
src/timer/vita/SDL_systimer.c | 91 ++++++++
src/video/SDL_sysvideo.h | 1 +
src/video/SDL_video.c | 3 +
src/video/vita/SDL_vitagl.c | 221 ++++++++++++++++++
src/video/vita/SDL_vitagl_c.h | 56 +++++
src/video/vita/SDL_vitakeyboard.c | 198 ++++++++++++++++
src/video/vita/SDL_vitakeyboard.h | 33 +++
src/video/vita/SDL_vitamouse.c | 94 ++++++++
src/video/vita/SDL_vitamouse_c.h | 33 +++
src/video/vita/SDL_vitatouch.c | 179 +++++++++++++++
src/video/vita/SDL_vitatouch.h | 35 +++
src/video/vita/SDL_vitavideo.c | 341 ++++++++++++++++++++++++++++
src/video/vita/SDL_vitavideo.h | 102 +++++++++
36 files changed, 2940 insertions(+)
create mode 100644 Makefile.vita.dolce
create mode 100644 include/SDL_config_vita.h
create mode 100644 src/audio/vita/SDL_vitaaudio.c
create mode 100644 src/audio/vita/SDL_vitaaudio.h
create mode 100644 src/joystick/vita/SDL_sysjoystick.c
create mode 100644 src/power/vita/SDL_syspower.c
create mode 100644 src/thread/vita/SDL_syscond.c
create mode 100644 src/thread/vita/SDL_sysmutex.c
create mode 100644 src/thread/vita/SDL_sysmutex_c.h
create mode 100644 src/thread/vita/SDL_syssem.c
create mode 100644 src/thread/vita/SDL_systhread.c
create mode 100644 src/thread/vita/SDL_systhread_c.h
create mode 100644 src/timer/vita/SDL_systimer.c
create mode 100644 src/video/vita/SDL_vitagl.c
create mode 100644 src/video/vita/SDL_vitagl_c.h
create mode 100644 src/video/vita/SDL_vitakeyboard.c
create mode 100644 src/video/vita/SDL_vitakeyboard.h
create mode 100644 src/video/vita/SDL_vitamouse.c
create mode 100644 src/video/vita/SDL_vitamouse_c.h
create mode 100644 src/video/vita/SDL_vitatouch.c
create mode 100644 src/video/vita/SDL_vitatouch.h
create mode 100644 src/video/vita/SDL_vitavideo.c
create mode 100644 src/video/vita/SDL_vitavideo.h
diff --git a/Makefile.vita.dolce b/Makefile.vita.dolce
new file mode 100644
index 000000000..c9ca1ca88
--- /dev/null
+++ b/Makefile.vita.dolce
@@ -0,0 +1,59 @@
+# Based on port by xerpi
+# Makefile to build the SDL library
+
+TARGET_LIB = libSDL2.a
+
+SOURCES = \
+ src/*.c \
+ src/atomic/*.c \
+ src/audio/*.c \
+ src/audio/vita/*.c \
+ src/cpuinfo/*.c \
+ src/events/*.c \
+ src/file/*.c \
+ src/haptic/*.c \
+ src/haptic/dummy/*.c \
+ src/joystick/*.c \
+ src/joystick/vita/*.c \
+ src/loadso/dummy/*.c \
+ src/power/*.c \
+ src/power/vita/*.c \
+ src/filesystem/dummy/*.c \
+ src/render/*.c \
+ src/render/software/*.c \
+ src/render/opengles2/SDL_render_gles2.c \
+ src/render/vita/*.c \
+ src/sensor/*.c \
+ src/sensor/dummy/*.c \
+ src/stdlib/*.c \
+ src/thread/*.c \
+ src/thread/generic/SDL_systls.c \
+ src/thread/vita/*.c \
+ src/timer/*.c \
+ src/timer/vita/*.c \
+ src/video/*.c \
+ src/video/vita/*.c \
+ src/video/yuv2rgb/*.c \
+
+OBJS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g')
+
+PREFIX = arm-dolce-eabi
+CC = $(PREFIX)-gcc
+AR = $(PREFIX)-ar
+CFLAGS = -g -Wl,-q -Wall -O3 -Iinclude \
+ -D__VITA__ -D__ARM_ARCH=7 -D__ARM_ARCH_7A__ \
+ -mfpu=neon -mcpu=cortex-a9 -mfloat-abi=hard
+ASFLAGS = $(CFLAGS)
+
+$(TARGET_LIB): $(OBJS)
+ $(AR) rcs $@ $^
+
+clean:
+ @rm -f $(TARGET_LIB) $(OBJS)
+
+install: $(TARGET_LIB)
+ @mkdir -p "$(DOLCESDK)/arm-dolce-eabi/lib"
+ @cp $(TARGET_LIB) $(DOLCESDK)/arm-dolce-eabi/lib
+ @mkdir -p "$(DOLCESDK)/arm-dolce-eabi/include/SDL2"
+ @cp include/*.h "$(DOLCESDK)/arm-dolce-eabi/include/SDL2"
+ @echo "Installed!"
diff --git a/include/SDL_config.h b/include/SDL_config.h
index 378e180d8..0c3f56f2a 100644
--- a/include/SDL_config.h
+++ b/include/SDL_config.h
@@ -43,6 +43,8 @@
#include "SDL_config_psp.h"
#elif defined(__OS2__)
#include "SDL_config_os2.h"
+#elif defined(__VITA__)
+#include "SDL_config_vita.h"
#else
/* This is a minimal configuration just to get SDL running on new platforms. */
#include "SDL_config_minimal.h"
diff --git a/include/SDL_config_vita.h b/include/SDL_config_vita.h
new file mode 100644
index 000000000..d03aae3e1
--- /dev/null
+++ b/include/SDL_config_vita.h
@@ -0,0 +1,158 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2016 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_config_vita_h
+#define _SDL_config_vita_h
+#define SDL_config_h_
+
+#include "SDL_platform.h"
+
+/* include stdint.h here, needed on Vita to compile the yuv_rgb.h */
+#include <stdint.h>
+
+#ifdef __GNUC__
+#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1
+#endif
+
+#define HAVE_GCC_ATOMICS 1
+
+#define STDC_HEADERS 1
+#define HAVE_ALLOCA_H 1
+#define HAVE_CTYPE_H 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_LIMITS_H 1
+#define HAVE_MATH_H 1
+#define HAVE_SIGNAL_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDIO_H 1
+#define HAVE_STRING_H 1
+#define HAVE_SYS_TYPES_H 1
+
+/* C library functions */
+#define HAVE_MALLOC 1
+#define HAVE_CALLOC 1
+#define HAVE_REALLOC 1
+#define HAVE_FREE 1
+#define HAVE_ALLOCA 1
+#define HAVE_GETENV 1
+#define HAVE_SETENV 1
+#define HAVE_PUTENV 1
+#define HAVE_SETENV 1
+#define HAVE_UNSETENV 1
+#define HAVE_QSORT 1
+#define HAVE_ABS 1
+#define HAVE_BCOPY 1
+#define HAVE_MEMSET 1
+#define HAVE_MEMCPY 1
+#define HAVE_MEMMOVE 1
+#define HAVE_MEMCMP 1
+#define HAVE_STRLEN 1
+#define HAVE_STRLCPY 1
+#define HAVE_STRLCAT 1
+#define HAVE_STRCHR 1
+#define HAVE_STRRCHR 1
+#define HAVE_STRSTR 1
+#define HAVE_STRTOL 1
+#define HAVE_STRTOUL 1
+#define HAVE_STRTOLL 1
+#define HAVE_STRTOULL 1
+#define HAVE_STRTOD 1
+#define HAVE_ATOI 1
+#define HAVE_ATOF 1
+#define HAVE_STRCMP 1
+#define HAVE_STRNCMP 1
+#define HAVE_STRCASECMP 1
+#define HAVE_STRNCASECMP 1
+#define HAVE_VSSCANF 1
+#define HAVE_VSNPRINTF 1
+#define HAVE_M_PI 1
+#define HAVE_ACOS 1
+#define HAVE_ACOSF 1
+#define HAVE_ASIN 1
+#define HAVE_ASINF 1
+#define HAVE_ATAN 1
+#define HAVE_ATANF 1
+#define HAVE_ATAN2 1
+#define HAVE_ATAN2F 1
+#define HAVE_CEIL 1
+#define HAVE_CEILF 1
+#define HAVE_COPYSIGN 1
+#define HAVE_COPYSIGNF 1
+#define HAVE_COS 1
+#define HAVE_COSF 1
+#define HAVE_EXP 1
+#define HAVE_EXPF 1
+#define HAVE_FABS 1
+#define HAVE_FABSF 1
+#define HAVE_FLOOR 1
+#define HAVE_FLOORF 1
+#define HAVE_FMOD 1
+#define HAVE_FMODF 1
+#define HAVE_LOG 1
+#define HAVE_LOGF 1
+#define HAVE_POW 1
+#define HAVE_POWF 1
+#define HAVE_SCALBN 1
+#define HAVE_SCALBNF 1
+#define HAVE_SIN 1
+#define HAVE_SINF 1
+#define HAVE_SQRT 1
+#define HAVE_SQRTF 1
+#define HAVE_TAN 1
+#define HAVE_TANF 1
+#define HAVE_SETJMP 1
+#define HAVE_NANOSLEEP 1
+#define HAVE_LOG10 1
+#define HAVE_LOG10F 1
+/* #define HAVE_SYSCONF 1 */
+/* #define HAVE_SIGACTION 1 */
+
+
+/* VITA isn't that sophisticated */
+#define LACKS_SYS_MMAN_H 1
+
+
+#define SDL_AUDIO_DRIVER_VITA 1
+#define SDL_THREAD_VITA 1
+#define SDL_JOYSTICK_VITA 1
+#define SDL_TIMERS_VITA 1
+#define SDL_POWER_VITA 1
+#define SDL_VIDEO_DRIVER_VITA 1
+
+
+#define SDL_VIDEO_RENDER_OGL_ES2 1
+#define SDL_VIDEO_OPENGL_ES2 1
+
+
+/* !!! FIXME: what does VITA do for filesystem stuff? */
+#define SDL_FILESYSTEM_DUMMY 1
+
+/* VITA doesn't have haptic device (src/haptic/dummy/\*.c) */
+#define SDL_HAPTIC_DISABLED 1
+
+/* VITA can't load shared object (src/loadso/dummy/\*.c) */
+// that' not true, but oh well
+#define SDL_LOADSO_DISABLED 1
+
+#define SDL_SENSOR_DISABLED 1
+#define SDL_SENSOR_DUMMY 1
+
+#endif /* _SDL_config_vita_h */
diff --git a/src/SDL.c b/src/SDL.c
index 124aceebf..c5cf06730 100644
--- a/src/SDL.c
+++ b/src/SDL.c
@@ -527,6 +527,8 @@ SDL_GetPlatform()
return "iOS";
#elif __PSP__
return "PlayStation Portable";
+#elif __VITA__
+ return "PlayStation Vita";
#else
return "Unknown (see SDL_platform.h)";
#endif
diff --git a/src/SDL_log.c b/src/SDL_log.c
index 9a5d1c480..d14c3d2f0 100644
--- a/src/SDL_log.c
+++ b/src/SDL_log.c
@@ -422,6 +422,13 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
fclose (pFile);
}
+#elif defined(__VITA__)
+ {
+ FILE* pFile;
+ pFile = fopen ("ux0:/data/SDL_Log.txt", "a");
+ fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
+ fclose (pFile);
+ }
#endif
#if HAVE_STDIO_H
fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message);
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 725e169ce..00ee976c6 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -98,6 +98,9 @@ static const AudioBootStrap *const bootstrap[] = {
#if SDL_AUDIO_DRIVER_PSP
&PSPAUDIO_bootstrap,
#endif
+#if SDL_AUDIO_DRIVER_VITA
+ &VITAAUD_bootstrap,
+#endif
#if SDL_AUDIO_DRIVER_EMSCRIPTEN
&EMSCRIPTENAUDIO_bootstrap,
#endif
diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h
index 0c66ec657..d7fd556bd 100644
--- a/src/audio/SDL_sysaudio.h
+++ b/src/audio/SDL_sysaudio.h
@@ -208,6 +208,7 @@ extern AudioBootStrap FUSIONSOUND_bootstrap;
extern AudioBootStrap openslES_bootstrap;
extern AudioBootStrap ANDROIDAUDIO_bootstrap;
extern AudioBootStrap PSPAUDIO_bootstrap;
+extern AudioBootStrap VITAAUD_bootstrap;
extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap;
extern AudioBootStrap OS2AUDIO_bootstrap;
diff --git a/src/audio/vita/SDL_vitaaudio.c b/src/audio/vita/SDL_vitaaudio.c
new file mode 100644
index 000000000..5225b8033
--- /dev/null
+++ b/src/audio/vita/SDL_vitaaudio.c
@@ -0,0 +1,203 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2015 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 SDL_AUDIO_DRIVER_VITA
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+
+#include "SDL_audio.h"
+#include "SDL_error.h"
+#include "SDL_timer.h"
+#include "../SDL_audio_c.h"
+#include "../SDL_audiodev_c.h"
+#include "../SDL_sysaudio.h"
+#include "SDL_vitaaudio.h"
+
+#include <psp2/kernel/threadmgr.h>
+#include <psp2/audioout.h>
+
+#define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63)
+#define SCE_AUDIO_MAX_VOLUME 0x8000
+
+/* The tag name used by VITA audio */
+#define VITAAUD_DRIVER_NAME "vita"
+
+static int
+VITAAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
+{
+ int format, mixlen, i, port = SCE_AUDIO_OUT_PORT_TYPE_MAIN;
+
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc(sizeof(*this->hidden));
+ if (this->hidden == NULL) {
+ return SDL_OutOfMemory();
+ }
+ SDL_memset(this->hidden, 0, sizeof(*this->hidden));
+ switch (this->spec.format & 0xff) {
+ case 8:
+ case 16:
+ this->spec.format = AUDIO_S16LSB;
+ break;
+ default:
+ return SDL_SetError("Unsupported audio format");
+ }
+
+ /* The sample count must be a multiple of 64. */
+ this->spec.samples = SCE_AUDIO_SAMPLE_ALIGN(this->spec.samples);
+
+ /* Update the fragment size as size in bytes. */
+/* SDL_CalculateAudioSpec(this->spec); MOD */
+ switch (this->spec.format) {
+ case AUDIO_U8:
+ this->spec.silence = 0x80;
+ break;
+ default:
+ this->spec.silence = 0x00;
+ break;
+ }
+ this->spec.size = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
+ this->spec.size *= this->spec.channels;
+ this->spec.size *= this->spec.samples;
+
+/* ========================================== */
+
+ /* Allocate the mixing buffer. Its size and starting address must
+ be a multiple of 64 bytes. Our sample count is already a multiple of
+ 64, so spec->size should be a multiple of 64 as well. */
+ mixlen = this->spec.size * NUM_BUFFERS;
+ this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen);
+ if (this->hidden->rawbuf == NULL) {
+ return SDL_SetError("Couldn't allocate mixing buffer");
+ }
+
+ /* Setup the hardware channel. */
+ if (this->spec.channels == 1) {
+ format = SCE_AUDIO_OUT_MODE_MONO;
+ } else {
+ format = SCE_AUDIO_OUT_MODE_STEREO;
+ }
+
+ if(this->spec.freq < 48000) {
+ port = SCE_AUDIO_OUT_PORT_TYPE_BGM;
+ }
+
+ this->hidden->channel = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
+ if (this->hidden->channel < 0) {
+ free(this->hidden->rawbuf);
+ this->hidden->rawbuf = NULL;
+ return SDL_SetError("Couldn't reserve hardware channel");
+ }
+
+ memset(this->hidden->rawbuf, 0, mixlen);
+ for (i = 0; i < NUM_BUFFERS; i++) {
+ this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
+ }
+
+ this->hidden->next_buffer = 0;
+ return 0;
+}
+
+static void VITAAUD_PlayDevice(_THIS)
+{
+ Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
+
+ int vols[2] = {SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME};
+ sceAudioOutSetVolume(this->hidden->channel, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
+ sceAudioOutOutput(this->hidden->channel, mixbuf);
+
+ this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
+}
+
+/* This function waits until it is possible to write a full sound buffer */
+static void VITAAUD_WaitDevice(_THIS)
+{
+ /* Because we block when sending audio, there's no need for this function to do anything. */
+}
+static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
+{
+ return this->hidden->mixbufs[this->hidden->next_buffer];
+}
+
+static void VITAAUD_CloseDevice(_THIS)
+{
+ if (this->hidden->channel >= 0) {
+ sceAudioOutReleasePort(this->hidden->channel);
+ this->hidden->channel = -1;
+ }
+
+ if (this->hidden->rawbuf != NULL) {
+ free(this->hidden->rawbuf);
+ this->hidden->rawbuf = NULL;
+ }
+}
+static void VITAAUD_ThreadInit(_THIS)
+{
+ /* Increase the priority of this audio thread by 1 to put it
+ ahead of other SDL threads. */
+ SceUID thid;
+ SceKernelThreadInfo info;
+ thid = sceKernelGetThreadId();
+ info.size = sizeof(SceKernelThreadInfo);
+ if (sceKernelGetThreadInfo(thid, &info) == 0) {
+ sceKernelChangeThreadPriority(thid, info.currentPriority - 1);
+ }
+}
+
+
+static int
+VITAAUD_Init(SDL_AudioDriverImpl * impl)
+{
+
+ /* Set the function pointers */
+ impl->OpenDevice = VITAAUD_OpenDevice;
+ impl->PlayDevice = VITAAUD_PlayDevice;
+ impl->WaitDevice = VITAAUD_WaitDevice;
+ impl->GetDeviceBuf = VITAAUD_GetDeviceBuf;
+ impl->CloseDevice = VITAAUD_CloseDevice;
+ impl->ThreadInit = VITAAUD_ThreadInit;
+
+ /* VITA audio device */
+ impl->OnlyHasDefaultOutputDevice = 1;
+/*
+ impl->HasCaptureSupport = 1;
+
+ impl->OnlyHasDefaultInputDevice = 1;
+*/
+ /*
+ impl->DetectDevices = DSOUND_DetectDevices;
+ impl->Deinitialize = DSOUND_Deinitialize;
+ */
+ return 1; /* this audio target is available. */
+}
+
+AudioBootStrap VITAAUD_bootstrap = {
+ "vita", "VITA audio driver", VITAAUD_Init, 0
+};
+
+ /* SDL_AUDI */
+
+#endif /* SDL_AUDIO_DRIVER_VITA */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/audio/vita/SDL_vitaaudio.h b/src/audio/vita/SDL_vitaaudio.h
new file mode 100644
index 000000000..0c1ad523b
--- /dev/null
+++ b/src/audio/vita/SDL_vitaaudio.h
@@ -0,0 +1,45 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2015 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_vitaaudio_h
+#define _SDL_vitaaudio_h
+
+#include "../SDL_sysaudio.h"
+
+/* Hidden "this" pointer for the audio functions */
+#define _THIS SDL_AudioDevice *this
+
+#define NUM_BUFFERS 2
+
+struct SDL_PrivateAudioData {
+ /* The hardware output channel. */
+ int channel;
+ /* The raw allocated mixing buffer. */
+ Uint8 *rawbuf;
+ /* Individual mixing buffers. */
+ Uint8 *mixbufs[NUM_BUFFERS];
+ /* Index of the next available mixing buffer. */
+ int next_buffer;
+};
+
+#endif /* _SDL_vitaaudio_h */
+/* vim: ts=4 sw=4
+ */
diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c
index 1f134e11b..1668e701c 100644
--- a/src/cpuinfo/SDL_cpuinfo.c
+++ b/src/cpuinfo/SDL_cpuinfo.c
@@ -450,6 +450,8 @@ CPU_haveNEON(void)
return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;
#elif (defined(__ARM_ARCH) && (__ARM_ARCH >= 8)) || defined(__aarch64__)
return 1; /* ARMv8 always has non-optional NEON support. */
+#elif __VITA__
+ return 1;
#elif defined(__APPLE__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7)
/* (note that sysctlbyname("hw.optional.neon") doesn't work!) */
return 1; /* all Apple ARMv7 chips and later have NEON. */
diff --git a/src/dynapi/SDL_dynapi.h b/src/dynapi/SDL_dynapi.h
index e8acb7f78..2619ff761 100644
--- a/src/dynapi/SDL_dynapi.h
+++ b/src/dynapi/SDL_dynapi.h
@@ -57,6 +57,8 @@
#define SDL_DYNAMIC_API 0
#elif defined(__clang_analyzer__)
#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */
+#elif defined(__VITA__)
+#define SDL_DYNAMIC_API 0 /* vitasdk doesn't support dynamic linking */
#endif
/* everyone else. This is where we turn on the API if nothing forced it off. */
diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h
index 9ee4d458a..87d3c560b 100644
--- a/src/joystick/SDL_gamecontrollerdb.h
+++ b/src/joystick/SDL_gamecontrollerdb.h
@@ -856,6 +856,10 @@ static const char *s_ControllerMappings [] =
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
"default,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
#endif
+#if defined(SDL_JOYSTICK_VITA)
+ "50535669746120436f6e74726f6c6c65,PSVita Controller,y:b0,b:b1,a:b2,x:b3,leftshoulder:b4,rightshoulder:b5,dpdown:b6,dpleft:b7,dpup:b8,dpright:b9,back:b10,start:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+#endif
+ "hidapi,*,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
NULL
};
diff --git a/src/joystick/vita/SDL_sysjoystick.c b/src/joystick/vita/SDL_sysjoystick.c
new file mode 100644
index 000000000..151e3f86c
--- /dev/null
+++ b/src/joystick/vita/SDL_sysjoystick.c
@@ -0,0 +1,310 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2015 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 SDL_JOYSTICK_VITA
+
+/* This is the PSVita implementation of the SDL joystick API */
+#include <psp2/types.h>
+#include <psp2/ctrl.h>
+#include <psp2/kernel/threadmgr.h>
+
+#include <stdio.h> /* For the definition of NULL */
+#include <stdlib.h>
+
+#include "../SDL_sysjoystick.h"
+#include "../SDL_joystick_c.h"
+
+#include "SDL_events.h"
+#include "SDL_error.h"
+#include "SDL_thread.h"
+#include "SDL_mutex.h"
+#include "SDL_timer.h"
+
+/* Current pad state */
+static SceCtrlData pad0 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .buttons = 0 };
+static SceCtrlData pad1 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .buttons = 0 };
+static SceCtrlData pad2 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .buttons = 0 };
+static SceCtrlData pad3 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .buttons = 0 };
+static int port_map[4]= { 0, 2, 3, 4 }; //index: SDL joy number, entry: Vita port number
+static int SDL_numjoysticks = 1;
+static const unsigned int button_map[] = {
+ SCE_CTRL_TRIANGLE, SCE_CTRL_CIRCLE, SCE_CTRL_CROSS, SCE_CTRL_SQUARE,
+ SCE_CTRL_LTRIGGER, SCE_CTRL_RTRIGGER,
+ SCE_CTRL_DOWN, SCE_CTRL_LEFT, SCE_CTRL_UP, SCE_CTRL_RIGHT,
+ SCE_CTRL_SELECT, SCE_CTRL_START};
+static int analog_map[256]; /* Map analog inputs to -32768 -> 32767 */
+
+typedef struct
+{
+ int x;
+ int y;
+} point;
+
+/* 4 points define the bezier-curve. */
+/* The Vita has a good amount of analog travel, so use a linear curve */
+static point a = { 0, 0 };
+static point b = { 0, 0 };
+static point c = { 128, 32767 };
+static point d = { 128, 32767 };
+
+/* simple linear interpolation between two points */
+static SDL_INLINE void lerp (point *dest, point *a, point *b, float t)
+{
+ dest->x = a->x + (b->x - a->x)*t;
+ dest->y = a->y + (b->y - a->y)*t;
+}
+
+/* evaluate a point on a bezier-curve. t goes from 0 to 1.0 */
+static int calc_bezier_y(float t)
+{
+ point ab, bc, cd, abbc, bccd, dest;
+ lerp (&ab, &a, &b, t); /* point between a and b */
+ lerp (&bc, &b, &c, t); /* point between b and c */
+ lerp (&cd, &c, &d, t); /* point between c and d */
+ lerp (&abbc, &ab, &bc, t); /* point between ab and bc */
+ lerp (&bccd, &bc, &cd, t); /* point between bc and cd */
+ lerp (&dest, &abbc, &bccd, t); /* point on the bezier-curve */
+ return dest.y;
+}
+
+/* Function to scan the system for joysticks.
+ * Joystick 0 should be the system default joystick.
+ * It should return number of joysticks, or -1 on an unrecoverable fatal error.
+ */
+int SDL_SYS_JoystickInit(void)
+{
+ int i;
+
+ /* Setup input */
+ sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE);
+
+ /* Create an accurate map from analog inputs (0 to 255)
+ to SDL joystick positions (-32768 to 32767) */
+ for (i = 0; i < 128; i++)
+ {
+ float t = (float)i/127.0f;
+ analog_map[i+128] = calc_bezier_y(t);
+ analog_map[127-i] = -1 * analog_map[i+128];
+ }
+
+ SceCtrlPortInfo myPortInfo;
+
+ // Assume we have at least one controller, even when nothing is paired
+ // This way the user can jump in, pair a controller
+ // and control things immediately even if it is paired
+ // after the app has already started.
+
+ SDL_numjoysticks = 1;
+
+ //How many additional paired controllers are there?
+ sceCtrlGetControllerPortInfo(&myPortInfo);
+ //On Vita TV, port 0 and 1 are the same controller
+ //and that is the first one, so start at port 2
+ for (i=2; i<=4; i++)
+ {
+ if (myPortInfo.port[i]!=SCE_CTRL_TYPE_UNPAIRED)
+ {
+ SDL_numjoysticks++;
+ }
+ }
+ return SDL_numjoysticks;
+}
+
+int SDL_SYS_NumJoysticks()
+{
+ return SDL_numjoysticks;
+}
+
+void SDL_SYS_JoystickDetect()
+{
+}
+
+/* Function to get the device-dependent name of a joystick */
+const char * SDL_SYS_JoystickNameForDeviceIndex(int device_index)
+{
+ if (device_index == 1)
+ return "PSVita Controller";
+
+ if (device_index == 2)
+ return "PSVita Controller";
+
+ if (device_index == 3)
+ return "PSVita Controller";
+
+ return "PSVita Controller";
+}
+
+/* Function to perform the mapping from device index to the instance id for this index */
+SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
+{
+ return device_index;
+}
+
+/* Function to get the device-dependent name of a joystick */
+const char *SDL_SYS_JoystickName(int index)
+{
+ if (index == 0)
+ return "PSVita Controller";
+
+ if (index == 1)
+ return "PSVita Controller";
+
+ if (index == 2)
+ return "PSVita Controller";
+
+ if (index == 3)
+ return "PSVita Controller";
+
+ SDL_SetError("No joystick available with that index");
+ return(NULL);
+}
+
+/* Function to open a joystick for use.
+ The joystick to open is specified by the device index.
+ This should fill the nbuttons and naxes fields of the joystick structure.
+ It returns 0, or -1 if there is an error.
+ */
+int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index)
+{
+ joystick->nbuttons = sizeof(button_map)/sizeof(*button_map);
+ joystick->naxes = 4;
+ joystick->nhats = 0;
+ joystick->instance_id = device_index;
+
+ return 0;
+}
+
+/* Function to determine if this joystick is attached to the system right now */
+SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
+{
+ return SDL_TRUE;
+}
+
+/* Function to update the state of a joystick - called as a device poll.
+ * This function shouldn't update the joystick structure directly,
+ * but instead should call SDL_PrivateJoystick*() to deliver events
+ * and update joystick device state.
+ */
+void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
+{
+ int i;
+ unsigned int buttons;
+ unsigned int changed;
+ unsigned char lx, ly, rx, ry;
+ static unsigned int old_buttons[] = { 0, 0, 0, 0 };
+ static unsigned char old_lx[] = { 0, 0, 0, 0 };
+ static unsigned char old_ly[] = { 0, 0, 0, 0 };
+ static unsigned char old_rx[] = { 0, 0, 0, 0 };
+ static unsigned char old_ry[] = { 0, 0, 0, 0 };
+ SceCtrlData *pad = NULL;
+
+ int index = (int) SDL_JoystickInstanceID(joystick);
+
+ if (index == 0) pad = &pad0;
+ else if (index == 1) pad = &pad1;
+ else if (index == 2) pad = &pad2;
+ else if (index == 3) pad = &pad3;
+ else return;
+
+ sceCtrlPeekBufferPositive(port_map[index], pad, 1);
+
+ buttons = pad->buttons;
+ lx = pad->lx;
+ ly = pad->ly;
+ rx = pad->rx;
+ ry = pad->ry;
+/*
+ for(i=0; i<sizeof(button_map)/sizeof(button_map[0]); i++) {
+ SDL_PrivateJoystickButton(
+ joystick, i,
+ (buttons & button_map[i]) ?
+ SDL_PRESSED : SDL_RELEASED);
+}
+*/
+ // Axes
+
+ if(old_lx[index] != lx) {
+ SDL_PrivateJoystickAxis(joystick, 0, analog_map[lx]);
+ old_lx[index] = lx;
+ }
+ if(old_ly[index] != ly) {
+ SDL_PrivateJoystickAxis(joystick, 1, analog_map[ly]);
+ old_ly[index] = ly;
+ }
+ if(old_rx[index] != rx) {
+ SDL_PrivateJoystickAxis(joystick, 2, analog_map[rx]);
+ old_rx[index] = rx;
+ }
+ if(old_ry[index] != ry) {
+ SDL_PrivateJoystickAxis(joystick, 3, analog_map[ry]);
+ old_ry[index] = ry;
+ }
+
+ // Buttons
+ changed = old_buttons[index] ^ buttons;
+ old_buttons[index] = buttons;
+ if(changed) {
+ for(i=0; i<sizeof(button_map)/sizeof(button_map[0]); i++) {
+ if(changed & button_map[i]) {
+ SDL_PrivateJoystickButton(
+ joystick, i,
+ (buttons & button_map[i]) ?
+ SDL_PRESSED : SDL_RELEASED);
+ }
+ }
+ }
+}
+
+/* Function to close a joystick after use */
+void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
+{
+}
+
+/* Function to perform any system-specific joystick related cleanup */
+void SDL_SYS_JoystickQuit(void)
+{
+}
+
+SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
+{
+ SDL_JoystickGUID guid;
+ /* the GUID is just the first 16 chars of the name for now */
+ const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
+ SDL_zero( guid );
+ SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
+ return guid;
+}
+
+SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
+{
+ SDL_JoystickGUID guid;
+ /* the GUID is just the first 16 chars of the name for now */
+ const char *name = joystick->name;
+ SDL_zero( guid );
+ SDL_memc
(Patch may be truncated, please check the link at the top of this post.)