diff options
author | xantares | 2015-06-08 23:30:34 +0200 |
---|---|---|
committer | xantares | 2015-06-08 23:30:34 +0200 |
commit | 59617e3ad4069e7fb1c5a95137f92ea95660f699 (patch) | |
tree | af1047fdbbd85b0643d381d8ea47111a58609726 | |
download | aur-59617e3ad4069e7fb1c5a95137f92ea95660f699.tar.gz |
Initial import
-rw-r--r-- | .SRCINFO | 20 | ||||
-rw-r--r-- | PKGBUILD | 39 | ||||
-rw-r--r-- | SDL-1.2.15-PSP.patch | 2943 |
3 files changed, 3002 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..7d1ac8072732 --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,20 @@ +pkgbase = psp-sdl + pkgdesc = A library for portable low-level access to a video framebuffer, audio output, mouse, and keyboard (psp) + pkgver = 1.2.15 + pkgrel = 1 + url = http://www.libsdl.org + arch = any + license = LGPL + makedepends = psp-gcc + depends = psp-sdk + depends = psp-pspirkeyb + options = staticlibs + options = !buildflags + options = !strip + source = http://www.libsdl.org/release/SDL-1.2.15.tar.gz + source = SDL-1.2.15-PSP.patch + md5sums = 9d96df8417572a2afb781a7c4c811a85 + md5sums = SKIP + +pkgname = psp-sdl + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..0fcda4dfa100 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,39 @@ + +pkgname=psp-sdl +pkgver=1.2.15 +pkgrel=1 +pkgdesc="A library for portable low-level access to a video framebuffer, audio output, mouse, and keyboard (psp)" +arch=('any') +url="http://www.libsdl.org" +license=('LGPL') +depends=('psp-sdk' 'psp-pspirkeyb') +makedepends=('psp-gcc') +options=('staticlibs' '!buildflags' '!strip') +source=("http://www.libsdl.org/release/SDL-${pkgver}.tar.gz" + "SDL-${pkgver}-PSP.patch") +md5sums=('9d96df8417572a2afb781a7c4c811a85' + 'SKIP') + +prepare() { + cd SDL-$pkgver + rm -f src/*/psp/*.[hc] + rm -f README.PSP + patch -Np1 -i ../SDL-1.2.15-PSP.patch +} + +build() { + cd SDL-$pkgver + sh autogen.sh + export LDFLAGS="-L$(psp-config --pspsdk-path)/lib -L$(psp-config --psp-prefix)/lib -lc -lpspuser" + export LIBS="-lc -lpspuser" + mkdir -p build-psp && pushd build-psp + ../configure --prefix=/usr/psp --host=psp \ + --enable-pspirkeyb + make +} + +package() { + cd SDL-$pkgver/build-psp + make DESTDIR="$pkgdir" install + rm -r "$pkgdir"/usr/psp/share/man +} diff --git a/SDL-1.2.15-PSP.patch b/SDL-1.2.15-PSP.patch new file mode 100644 index 000000000000..100fedd7f003 --- /dev/null +++ b/SDL-1.2.15-PSP.patch @@ -0,0 +1,2943 @@ +diff -burN SDL-1.2.15/build-scripts/config.sub SDL-1.2.15-PSP/build-scripts/config.sub +--- SDL-1.2.15/build-scripts/config.sub 2012-01-19 07:30:05.000000000 +0100 ++++ SDL-1.2.15-PSP/build-scripts/config.sub 2012-06-06 12:55:07.465588936 +0200 +@@ -942,6 +942,10 @@ + ps2) + basic_machine=i386-ibm + ;; ++ psp) ++ basic_machine=mipsallegrexel-psp ++ os=-elf ++ ;; + pw32) + basic_machine=i586-unknown + os=-pw32 +diff -burN SDL-1.2.15/configure.in SDL-1.2.15-PSP/configure.in +--- SDL-1.2.15/configure.in 2012-01-19 07:30:05.000000000 +0100 ++++ SDL-1.2.15-PSP/configure.in 2012-06-06 12:55:07.468588936 +0200 +@@ -1771,6 +1771,26 @@ + AC_DEFINE(SDL_VIDEO_DISABLE_SCREENSAVER) + fi + ++dnl Check for pspgl ++CheckPSPGL() ++{ ++ if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then ++ AC_MSG_CHECKING(for OpenGL (pspgl) support) ++ video_opengl=no ++ AC_TRY_COMPILE([ ++ #include <GL/gl.h> ++ ],[ ++ ],[ ++ video_opengl=yes ++ ]) ++ AC_MSG_RESULT($video_opengl) ++ if test x$video_opengl = xyes; then ++ EXTRA_CFLAGS="$EXTRA_CFLAGS -DHAVE_OPENGL" ++ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lGL -lpspvfpu" ++ fi ++ fi ++} ++ + dnl See if we can use the new unified event interface in Linux 2.4 + CheckInputEvents() + { +@@ -2304,6 +2324,39 @@ + fi + } + ++dnl Check for a valid PSPSDK installation ++CheckPSPSDK() ++{ ++ AC_CHECK_PROG(psp_config, psp-config, psp-config, no) ++ if test x$psp_config = xno; then ++ AC_MSG_ERROR(Couldn't locate psp-config.) ++ fi ++ ++ AC_MSG_CHECKING(for PSPSDK) ++ pspsdk_path=`$psp_config --pspsdk-path` ++ if test ! -d $pspsdk_path -o -z $pspsdk_path; then ++ AC_MSG_RESULT(not found) ++ AC_MSG_ERROR(Couldn't locate PSPSDK.) ++ fi ++ AC_MSG_RESULT($pspsdk_path) ++ psp_prefix=`$psp_config --psp-prefix` ++ ++ # Compile SDL with -G0 to disable the $gp register. ++ EXTRA_CFLAGS="$EXTRA_CFLAGS -G0 -I\"${pspsdk_path}/include\"" ++ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -L${pspsdk_path}/lib -L${psp_prefix} -lpspdebug -lpspgu -lpspctrl" ++ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lpspge -lpspdisplay -lpsphprm -lpspsdk -lpsprtc" ++ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lpspaudio -lpsputility -lpspnet_inet" ++ ++ AC_ARG_ENABLE(pspirkeyb, ++ [ --enable-pspirkeyb use external keyboard via libpspirkeyb [default=no]], ++ , enable_pspirkeyb=no) ++ if test x$enable_pspirkeyb = xyes ; then ++ EXTRA_CFLAGS="$EXTRA_CFLAGS -DPSPIRKEYB" ++ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lpspirkeyb -lpsppower" ++ fi ++ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lc -lpspuser" ++} ++ + dnl Check if we want to use RPATH + CheckRPATH() + { +@@ -2831,6 +2884,50 @@ + # The RISC OS platform requires special setup. + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ljpeg -ltiff -lpng -lz" + ;; ++ *-psp-*) ++ ARCH=psp ++ CheckPSPGL ++ CheckPSPSDK ++ # Set up files for the video library ++ if test x$enable_video = xyes; then ++ AC_DEFINE(SDL_VIDEO_DRIVER_PSP) ++ SOURCES="$SOURCES $srcdir/src/video/psp/*.c" ++ have_video=yes ++ fi ++ # Set up files for the audio library ++ if test x$enable_audio = xyes; then ++ AC_DEFINE(SDL_AUDIO_DRIVER_PSP) ++ SOURCES="$SOURCES $srcdir/src/audio/psp/*.c" ++ have_audio=yes ++ fi ++ # Set up files for the joystick library ++ if test x$enable_joystick = xyes; then ++ AC_DEFINE(SDL_JOYSTICK_PSP) ++ SOURCES="$SOURCES $srcdir/src/joystick/psp/*.c" ++ have_joystick=yes ++ fi ++ # Set up files for the thread library ++ if test x$enable_threads = xyes; then ++ AC_DEFINE(SDL_THREAD_PSP) ++ SOURCES="$SOURCES $srcdir/src/thread/psp/*.c" ++ SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_sysmutex.c" ++ SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c" ++ have_threads=yes ++ fi ++ # Set up files for the timer library ++ if test x$enable_timers = xyes; then ++ AC_DEFINE(SDL_TIMER_PSP) ++ SOURCES="$SOURCES $srcdir/src/timer/psp/SDL_systimer.c" ++ have_timers=yes ++ fi ++ ++ EXTRA_CFLAGS="$EXTRA_CFLAGS -DENABLE_PSP -DDISABLE_STDIO" ++ ++ # Use SDL_main wrapper to set up callbacks etc. ++ SDL_CFLAGS="$SDL_CFLAGS -Dmain=SDL_main" ++ SDL_LIBS="-lSDLmain $SDL_LIBS" ++ SDLMAIN_SOURCES="$srcdir/src/main/psp/*.c" ++ ;; + *) + AC_MSG_ERROR([ + *** Unsupported host: Please add to configure.in +diff -burN SDL-1.2.15/include/SDL_config.h.in SDL-1.2.15-PSP/include/SDL_config.h.in +--- SDL-1.2.15/include/SDL_config.h.in 2012-01-19 07:30:05.000000000 +0100 ++++ SDL-1.2.15-PSP/include/SDL_config.h.in 2012-06-06 12:55:07.469588936 +0200 +@@ -181,6 +181,7 @@ + #undef SDL_AUDIO_DRIVER_OSS + #undef SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H + #undef SDL_AUDIO_DRIVER_PAUD ++#undef SDL_AUDIO_DRIVER_PSP + #undef SDL_AUDIO_DRIVER_QNXNTO + #undef SDL_AUDIO_DRIVER_SNDMGR + #undef SDL_AUDIO_DRIVER_SUNAUDIO +@@ -214,6 +215,7 @@ + #undef SDL_JOYSTICK_MACOS + #undef SDL_JOYSTICK_MINT + #undef SDL_JOYSTICK_OS2 ++#undef SDL_JOYSTICK_PSP + #undef SDL_JOYSTICK_RISCOS + #undef SDL_JOYSTICK_WINMM + #undef SDL_JOYSTICK_USBHID +@@ -233,6 +235,7 @@ + #undef SDL_THREAD_BEOS + #undef SDL_THREAD_DC + #undef SDL_THREAD_OS2 ++#undef SDL_THREAD_PSP + #undef SDL_THREAD_PTH + #undef SDL_THREAD_PTHREAD + #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX +@@ -247,6 +250,7 @@ + #undef SDL_TIMER_MACOS + #undef SDL_TIMER_MINT + #undef SDL_TIMER_OS2 ++#undef SDL_TIMER_PSP + #undef SDL_TIMER_RISCOS + #undef SDL_TIMER_UNIX + #undef SDL_TIMER_WIN32 +@@ -273,6 +277,7 @@ + #undef SDL_VIDEO_DRIVER_PICOGUI + #undef SDL_VIDEO_DRIVER_PS2GS + #undef SDL_VIDEO_DRIVER_PS3 ++#undef SDL_VIDEO_DRIVER_PSP + #undef SDL_VIDEO_DRIVER_QTOPIA + #undef SDL_VIDEO_DRIVER_QUARTZ + #undef SDL_VIDEO_DRIVER_RISCOS +diff -burN SDL-1.2.15/README.PSP SDL-1.2.15-PSP/README.PSP +--- SDL-1.2.15/README.PSP 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/README.PSP 2012-06-06 12:55:07.469588936 +0200 +@@ -0,0 +1,111 @@ ++SDL port for the Sony PSP contributed by ++ Marcus R. Brown <mrbrown@ocgnet.org> ++ Jim Paris <jim@jtan.com> ++ Matthew H <matthewh@webone.com.au> ++ ++Building ++-------- ++To build for the PSP, make sure psp-config is in the path and run: ++ ++ ./autogen.sh ++ LDFLAGS="-L$(psp-config --pspsdk-path)/lib" LIBS="-lc -lpspuser" \ ++ ./configure --host psp --prefix=$(psp-config --psp-prefix) ++ make ++ make install ++ ++Status ++------ ++ Video - yes ++ - For accelerated 2D video output using the GE hardware, ++ use SDL_SWSURFACE in SDL_SetVideoMode. ++ - For video output via direct framebuffer access, use ++ SDL_HWSURFACE. ++ - OpenGL is supported with SDL_OPENGL. ++ Timers - yes ++ Threads - yes ++ Input - yes, see "Input" below ++ Audio - yes ++ ++ ++SDL_main ++-------- ++When writing an SDL program, the typical use is to write your main ++function as "SDL_main", then link -lSDLmain which provides the real ++main(). In this implementation, -lSDLmain will: ++ - Define the required PSP_* macros ++ - Set up the "home" button callback. ++ - Initialize the debugging screen ++ - Call the user-supplied SDL_main ++ - When it returns, delay 2.5 seconds, then exit to VSH. ++ ++Of course, you can leave off -lSDLmain, and write the real main() ++yourself if you need more control than this. ++ ++By default, the PSP "sdl-config --cflags" will define main=SDL_main. ++ ++ ++Building applications ++--------------------- ++Write your source file as you would a normal SDL program. Use the standard ++Makefile as supplied with any PSPSDK sample program. Above the final "include" ++line, add: ++ ++PSPBIN = $(PSPSDK)/../bin ++CFLAGS += $(shell $(PSPBIN)/sdl-config --cflags) ++LIBS += $(shell $(PSPBIN)/sdl-config --libs) ++ ++ ++Building autoconf applications ++------------------------------ ++The general way to build autoconf applications is to add the psp ++architecture to configure.in, then use --with-sdl-prefix to point to ++the proper sdl-config. For example, to build the applications in the ++test/ subdirectory, use: ++ ++ ./autogen.sh ++ LDFLAGS="-L$(psp-config --pspsdk-path)/lib -lc -lpspuser" \ ++ ./configure --host psp --with-sdl-prefix=$(psp-config --psp-prefix) ++ ++ ++Libc ++---- ++SDL is linked against newlib's libc, and your SDL programs should be ++too. Linking against psplibc will appear to work but may behave ++strangely at runtime. ++ ++ ++Input ++----- ++Joystick: ++The PSP's controls provide a joystick with a two axes on the analog ++stick and 14 independent buttons. The button mapping is fixed: ++ ++ 0 Triangle ++ 1 Circle ++ 2 Cross ++ 3 Square ++ 4 Left trigger ++ 5 Right trigger ++ 6 Down ++ 7 Left ++ 8 Up ++ 9 Right ++10 Select ++11 Start ++12 Home ++13 Hold ++ ++Mouse: ++There is no mouse support, although an application could be written to ++simulate it by receiving joystick events and using SDL_WarpMouse. ++ ++Keyboard: ++The headphone remote control is treated as a keyboard that sends the ++following keypresses: ++ ++F10 Play/Pause ++F11 Forward ++F12 Back ++F13 Volume Up ++F14 Volume Down ++F15 Hold +diff -burN SDL-1.2.15/src/audio/psp/SDL_pspaudio.c SDL-1.2.15-PSP/src/audio/psp/SDL_pspaudio.c +--- SDL-1.2.15/src/audio/psp/SDL_pspaudio.c 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/audio/psp/SDL_pspaudio.c 2012-06-06 12:55:07.469588936 +0200 +@@ -0,0 +1,212 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* PSP port contributed by Marcus R. Brown <mrbrown@ocgnet.org>. */ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_diskaudio.c,v 1.5 2004/01/04 16:49:13 slouken Exp $"; ++#endif ++ ++#include <stdio.h> ++#include <string.h> ++#include <stdlib.h> ++#include <malloc.h> ++ ++#include "SDL_audio.h" ++#include "SDL_error.h" ++#include "../SDL_audiomem.h" ++#include "../SDL_audio_c.h" ++#include "SDL_timer.h" ++#include "../SDL_audiodev_c.h" ++#include "SDL_pspaudio.h" ++ ++#include <pspaudio.h> ++#include <pspthreadman.h> ++ ++/* The tag name used by PSP audio */ ++#define PSPAUD_DRIVER_NAME "psp" ++ ++/* Audio driver functions */ ++static int PSPAUD_OpenAudio(_THIS, SDL_AudioSpec *spec); ++static void PSPAUD_ThreadInit(_THIS); ++static void PSPAUD_WaitAudio(_THIS); ++static void PSPAUD_PlayAudio(_THIS); ++static Uint8 *PSPAUD_GetAudioBuf(_THIS); ++static void PSPAUD_CloseAudio(_THIS); ++ ++/* Audio driver bootstrap functions */ ++static int PSPAUD_Available(void) ++{ ++ return 1; ++} ++ ++static void PSPAUD_DeleteDevice(SDL_AudioDevice *device) ++{ ++ free(device->hidden); ++ free(device); ++} ++ ++static SDL_AudioDevice *PSPAUD_CreateDevice(int devindex) ++{ ++ SDL_AudioDevice *this; ++ ++ /* Initialize all variables that we clean on shutdown */ ++ this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); ++ if ( this ) { ++ memset(this, 0, (sizeof *this)); ++ this->hidden = (struct SDL_PrivateAudioData *) ++ malloc((sizeof *this->hidden)); ++ } ++ if ( (this == NULL) || (this->hidden == NULL) ) { ++ SDL_OutOfMemory(); ++ if ( this ) { ++ free(this); ++ } ++ return(0); ++ } ++ memset(this->hidden, 0, (sizeof *this->hidden)); ++ ++ /* Set the function pointers */ ++ this->OpenAudio = PSPAUD_OpenAudio; ++ this->ThreadInit = PSPAUD_ThreadInit; ++ this->WaitAudio = PSPAUD_WaitAudio; ++ this->PlayAudio = PSPAUD_PlayAudio; ++ this->GetAudioBuf = PSPAUD_GetAudioBuf; ++ this->CloseAudio = PSPAUD_CloseAudio; ++ ++ this->free = PSPAUD_DeleteDevice; ++ ++ return this; ++} ++ ++AudioBootStrap PSPAUD_bootstrap = { ++ PSPAUD_DRIVER_NAME, "PSP audio driver", ++ PSPAUD_Available, PSPAUD_CreateDevice ++}; ++ ++/* This function waits until it is possible to write a full sound buffer */ ++static void PSPAUD_WaitAudio(_THIS) ++{ ++ /* Because we block when sending audio, there's no need for this function to do anything. */ ++} ++ ++static void PSPAUD_PlayAudio(_THIS) ++{ ++ Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer]; ++ ++ if (this->spec.channels == 1) { ++ sceAudioOutputBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, mixbuf); ++ } else { ++ sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf); ++ } ++ ++ this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS; ++} ++ ++static Uint8 *PSPAUD_GetAudioBuf(_THIS) ++{ ++ return this->hidden->mixbufs[this->hidden->next_buffer]; ++} ++ ++static void PSPAUD_CloseAudio(_THIS) ++{ ++ if (this->hidden->channel >= 0) { ++ sceAudioChRelease(this->hidden->channel); ++ this->hidden->channel = -1; ++ } ++ ++ if (this->hidden->rawbuf != NULL) { ++ free(this->hidden->rawbuf); ++ this->hidden->rawbuf = NULL; ++ } ++} ++ ++static void PSPAUD_ThreadInit(_THIS) ++{ ++ /* Increase the priority of this audio thread by 1 to put it ++ ahead of other SDL threads. */ ++ SceUID thid; ++ SceKernelThreadInfo status; ++ thid = sceKernelGetThreadId(); ++ status.size = sizeof(SceKernelThreadInfo); ++ if (sceKernelReferThreadStatus(thid, &status) == 0) { ++ sceKernelChangeThreadPriority(thid, status.currentPriority - 1); ++ } ++} ++ ++static int PSPAUD_OpenAudio(_THIS, SDL_AudioSpec *spec) ++{ ++ int format, mixlen, i; ++ ++ switch (spec->format & 0xff) { ++ case 8: ++ case 16: ++ spec->format = AUDIO_S16LSB; ++ break; ++ default: ++ SDL_SetError("Unsupported audio format"); ++ return -1; ++ } ++ ++ /* The sample count must be a multiple of 64. */ ++ spec->samples = PSP_AUDIO_SAMPLE_ALIGN(spec->samples); ++ spec->freq = 44100; ++ ++ /* Update the fragment size as size in bytes. */ ++ SDL_CalculateAudioSpec(spec); ++ ++ /* 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 = spec->size * NUM_BUFFERS; ++ this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen); ++ if (this->hidden->rawbuf == NULL) { ++ SDL_SetError("Couldn't allocate mixing buffer"); ++ return -1; ++ } ++ ++ /* Setup the hardware channel. */ ++ if (spec->channels == 1) { ++ format = PSP_AUDIO_FORMAT_MONO; ++ } else { ++ format = PSP_AUDIO_FORMAT_STEREO; ++ } ++ this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, spec->samples, format); ++ if (this->hidden->channel < 0) { ++ SDL_SetError("Couldn't reserve hardware channel"); ++ free(this->hidden->rawbuf); ++ this->hidden->rawbuf = NULL; ++ return -1; ++ } ++ ++ memset(this->hidden->rawbuf, 0, mixlen); ++ for (i = 0; i < NUM_BUFFERS; i++) { ++ this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * spec->size]; ++ } ++ ++ this->hidden->next_buffer = 0; ++ return 0; ++} ++ ++/* vim: ts=4 sw=4 ++ */ +diff -burN SDL-1.2.15/src/audio/psp/SDL_pspaudio.h SDL-1.2.15-PSP/src/audio/psp/SDL_pspaudio.h +--- SDL-1.2.15/src/audio/psp/SDL_pspaudio.h 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/audio/psp/SDL_pspaudio.h 2012-06-06 12:55:07.470588936 +0200 +@@ -0,0 +1,53 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* PSP port contributed by Marcus R. Brown <mrbrown@ocgnet.org>. */ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_diskaudio.h,v 1.4 2004/01/04 16:49:13 slouken Exp $"; ++#endif ++ ++#ifndef _SDL_pspaudio_h ++#define _SDL_pspaudio_h ++ ++#include "../SDL_sysaudio.h" ++ ++/* Hidden "this" pointer for the video 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_pspaudio_h */ ++/* vim: ts=4 sw=4 ++ */ +diff -burN SDL-1.2.15/src/audio/SDL_audio.c SDL-1.2.15-PSP/src/audio/SDL_audio.c +--- SDL-1.2.15/src/audio/SDL_audio.c 2012-01-19 07:30:06.000000000 +0100 ++++ SDL-1.2.15-PSP/src/audio/SDL_audio.c 2012-06-06 12:55:07.470588936 +0200 +@@ -113,6 +113,9 @@ + #if SDL_AUDIO_DRIVER_EPOCAUDIO + &EPOCAudio_bootstrap, + #endif ++#ifdef SDL_AUDIO_DRIVER_PSP ++ &PSPAUD_bootstrap, ++#endif + NULL + }; + SDL_AudioDevice *current_audio = NULL; +diff -burN SDL-1.2.15/src/audio/SDL_sysaudio.h SDL-1.2.15-PSP/src/audio/SDL_sysaudio.h +--- SDL-1.2.15/src/audio/SDL_sysaudio.h 2012-01-19 07:30:06.000000000 +0100 ++++ SDL-1.2.15-PSP/src/audio/SDL_sysaudio.h 2012-06-06 12:55:07.471588936 +0200 +@@ -179,6 +179,9 @@ + #if SDL_AUDIO_DRIVER_EPOCAUDIO + extern AudioBootStrap EPOCAudio_bootstrap; + #endif ++#if SDL_AUDIO_DRIVER_PSP ++extern AudioBootStrap PSPAUD_bootstrap; ++#endif + + /* This is the current audio device */ + extern SDL_AudioDevice *current_audio; +diff -burN SDL-1.2.15/src/joystick/psp/SDL_sysjoystick.c SDL-1.2.15-PSP/src/joystick/psp/SDL_sysjoystick.c +--- SDL-1.2.15/src/joystick/psp/SDL_sysjoystick.c 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/joystick/psp/SDL_sysjoystick.c 2012-06-06 12:55:07.472588936 +0200 +@@ -0,0 +1,234 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@devolution.com ++*/ ++ ++/* PSP port contributed by Marcus R. Brown <mrbrown@ocgnet.org>. */ ++/* Joystick stuff by Matthew H <matthewh@webone.com.au>. */ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_sysjoystick.c,v 1.3 2005/02/12 18:01:30 slouken Exp $"; ++#endif ++ ++/* This is the system specific header for the SDL joystick API */ ++#include <pspctrl.h> ++#include <pspkernel.h> ++ ++#include <stdio.h> /* For the definition of NULL */ ++#include <stdlib.h> ++ ++#include "SDL_error.h" ++#include "SDL_joystick.h" ++#include "../SDL_sysjoystick.h" ++#include "../SDL_joystick_c.h" ++#include "SDL_thread.h" ++#include "SDL_mutex.h" ++#include "SDL_timer.h" ++#include "SDL_events.h" ++ ++/* Current pad state */ ++static SceCtrlData pad = { .Lx = 0, .Ly = 0, .Buttons = 0 }; ++static SDL_sem *pad_sem = NULL; ++static SDL_Thread *thread = NULL; ++static int running = 0; ++static const enum PspCtrlButtons button_map[] = { ++ PSP_CTRL_TRIANGLE, PSP_CTRL_CIRCLE, PSP_CTRL_CROSS, PSP_CTRL_SQUARE, ++ PSP_CTRL_LTRIGGER, PSP_CTRL_RTRIGGER, ++ PSP_CTRL_DOWN, PSP_CTRL_LEFT, PSP_CTRL_UP, PSP_CTRL_RIGHT, ++ PSP_CTRL_SELECT, PSP_CTRL_START, PSP_CTRL_HOME, PSP_CTRL_HOLD }; ++static int analog_map[256]; /* Map analog inputs to -32768 -> 32767 */ ++ ++typedef struct ++{ ++ int x; ++ int y; ++} point; ++ ++// 4 points define the bezier-curve. ++static point a = { 0, 0 }; ++static point b = { 50, 0 }; ++static point c = { 78, 32767 }; ++static point d = { 128, 32767 }; ++ ++// simple linear interpolation between two points ++static __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; ++} ++ ++/* ++ * Collect pad data about once per frame ++ */ ++int JoystickUpdate(void *data) ++{ ++ while (running) { ++ SDL_SemWait(pad_sem); ++ sceCtrlPeekBufferPositive(&pad, 1); ++ SDL_SemPost(pad_sem); ++ /* Delay 1/60th of a second */ ++ sceKernelDelayThread(1000000 / 60); ++ } ++ return 0; ++} ++ ++ ++ ++/* Function to scan the system for joysticks. ++ * This function should set SDL_numjoysticks to the number of available ++ * 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; ++ ++ SDL_numjoysticks = 1; ++ ++ /* Setup input */ ++ sceCtrlSetSamplingCycle(0); ++ sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); ++ ++ /* Start thread to read data */ ++ if((pad_sem = SDL_CreateSemaphore(1)) == NULL) { ++ SDL_SetError("Can't create input semaphore\n"); ++ return -1; ++ } ++ running = 1; ++ if((thread = SDL_CreateThread(JoystickUpdate, NULL)) == NULL) { ++ SDL_SetError("Can't create input thread\n"); ++ return -1; ++ } ++ ++ /* 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]; ++ } ++ ++ return 1; ++} ++ ++/* Function to get the device-dependent name of a joystick */ ++const char *SDL_SYS_JoystickName(int index) ++{ ++ if (index == 0) ++ return "PSP 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 index field of the joystick. ++ 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) ++{ ++ joystick->nbuttons = 14; ++ joystick->naxes = 2; ++ joystick->nhats = 0; ++ ++ return 0; ++} ++ ++/* 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; ++ enum PspCtrlButtons buttons; ++ enum PspCtrlButtons changed; ++ unsigned char x, y; ++ static enum PspCtrlButtons old_buttons = 0; ++ static unsigned char old_x = 0, old_y = 0; ++ ++ SDL_SemWait(pad_sem); ++ buttons = pad.Buttons; ++ x = pad.Lx; ++ y = pad.Ly; ++ SDL_SemPost(pad_sem); ++ ++ /* Axes */ ++ if(old_x != x) { ++ SDL_PrivateJoystickAxis(joystick, 0, analog_map[x]); ++ old_x = x; ++ } ++ if(old_y != y) { ++ SDL_PrivateJoystickAxis(joystick, 1, analog_map[y]); ++ old_y = y; ++ } ++ ++ /* Buttons */ ++ changed = old_buttons ^ buttons; ++ old_buttons = 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); ++ } ++ } ++ } ++ ++ sceKernelDelayThread(0); ++} ++ ++/* Function to close a joystick after use */ ++void SDL_SYS_JoystickClose(SDL_Joystick *joystick) ++{ ++ /* Do nothing. */ ++} ++ ++/* Function to perform any system-specific joystick related cleanup */ ++void SDL_SYS_JoystickQuit(void) ++{ ++ /* Cleanup Threads and Semaphore. */ ++ running = 0; ++ SDL_WaitThread(thread, NULL); ++ SDL_DestroySemaphore(pad_sem); ++} ++ ++/* vim: ts=4 sw=4 ++ */ +diff -burN SDL-1.2.15/src/main/psp/SDL_psp_main.c SDL-1.2.15-PSP/src/main/psp/SDL_psp_main.c +--- SDL-1.2.15/src/main/psp/SDL_psp_main.c 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/main/psp/SDL_psp_main.c 2012-06-06 12:55:07.472588936 +0200 +@@ -0,0 +1,88 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* ++ PSP port contributed by: ++ Marcus R. Brown <mrbrown@ocgnet.org> ++ Jim Paris <jim@jtan.com> ++ Matthew H <matthewh@webone.com.au> ++*/ ++ ++#include "SDL_main.h" ++#include <pspkernel.h> ++#include <pspdebug.h> ++#include <pspsdk.h> ++#include <pspthreadman.h> ++#include <stdlib.h> ++#include <stdio.h> ++ ++/* If application's main() is redefined as SDL_main, and libSDLmain is ++ linked, then this file will create the standard exit callback, ++ define the PSP_MODULE_INFO macro, and exit back to the browser when ++ the program is finished. ++ ++ You can still override other parameters in your own code if you ++ desire, such as PSP_HEAP_SIZE_KB, PSP_MAIN_THREAD_ATTR, ++ PSP_MAIN_THREAD_STACK_SIZE, etc. ++*/ ++ ++extern int SDL_main(int argc, char *argv[]); ++ ++PSP_MODULE_INFO("SDL App", 0, 1, 1); ++ ++int sdl_psp_exit_callback(int arg1, int arg2, void *common) ++{ ++ exit(0); ++ return 0; ++} ++ ++int sdl_psp_callback_thread(SceSize args, void *argp) ++{ ++ int cbid; ++ cbid = sceKernelCreateCallback("Exit Callback", ++ sdl_psp_exit_callback, NULL); ++ sceKernelRegisterExitCallback(cbid); ++ sceKernelSleepThreadCB(); ++ return 0; ++} ++ ++int sdl_psp_setup_callbacks(void) ++{ ++ int thid = 0; ++ thid = sceKernelCreateThread("update_thread", ++ sdl_psp_callback_thread, 0x11, 0xFA0, 0, 0); ++ if(thid >= 0) ++ sceKernelStartThread(thid, 0, 0); ++ return thid; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ pspDebugScreenInit(); ++ sdl_psp_setup_callbacks(); ++ ++ /* Register sceKernelExitGame() to be called when we exit */ ++ atexit(sceKernelExitGame); ++ ++ (void)SDL_main(argc, argv); ++ return 0; ++} +diff -burN SDL-1.2.15/src/stdlib/SDL_malloc.c SDL-1.2.15-PSP/src/stdlib/SDL_malloc.c +--- SDL-1.2.15/src/stdlib/SDL_malloc.c 2012-01-19 07:30:06.000000000 +0100 ++++ SDL-1.2.15-PSP/src/stdlib/SDL_malloc.c 2012-06-06 12:55:07.474588936 +0200 +@@ -504,6 +504,10 @@ + #endif /* HAVE_MORECORE */ + #endif /* DARWIN */ + ++#ifdef ENABLE_PSP ++#define HAVE_MMAP 0 ++#endif ++ + #ifndef LACKS_SYS_TYPES_H + #include <sys/types.h> /* For size_t */ + #endif /* LACKS_SYS_TYPES_H */ +diff -burN SDL-1.2.15/src/thread/psp/SDL_syssem.c SDL-1.2.15-PSP/src/thread/psp/SDL_syssem.c +--- SDL-1.2.15/src/thread/psp/SDL_syssem.c 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/thread/psp/SDL_syssem.c 2012-06-06 12:55:07.478588936 +0200 +@@ -0,0 +1,168 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* PSP port contributed by Marcus R. Brown <mrbrown@ocgnet.org>. */ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_syssem.c,v 1.6 2004/01/04 16:49:19 slouken Exp $"; ++#endif ++ ++/* Semaphore functions for the PSP. */ ++ ++#include <stdio.h> ++#include <stdlib.h> ++ ++#include "SDL_error.h" ++#include "SDL_thread.h" ++ ++#include <pspkerneltypes.h> ++#include <pspthreadman.h> ++#include <pspkerror.h> ++ ++struct SDL_semaphore { ++ SceUID semid; ++}; ++ ++ ++/* Create a semaphore */ ++SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) ++{ ++ SDL_sem *sem; ++ ++ sem = (SDL_sem *) malloc(sizeof(*sem)); ++ if (sem != NULL) { ++ /* TODO: Figure out the limit on the maximum value. */ ++ sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL); ++ if (sem->semid < 0) { ++ SDL_SetError("Couldn't create semaphore"); ++ free(sem); ++ sem = NULL; ++ } ++ } else { ++ SDL_OutOfMemory(); ++ } ++ ++ return sem; ++} ++ ++/* Free the semaphore */ ++void SDL_DestroySemaphore(SDL_sem *sem) ++{ ++ if (sem != NULL) { ++ if (sem->semid > 0) { ++ sceKernelDeleteSema(sem->semid); ++ sem->semid = 0; ++ } ++ ++ free(sem); ++ } ++} ++ ++/* TODO: This routine is a bit overloaded. ++ * If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass ++ * NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout ++ * is specified, convert it to microseconds. */ ++int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) ++{ ++ Uint32 *pTimeout; ++ unsigned int res; ++ ++ if (sem == NULL) { ++ SDL_SetError("Passed a NULL sem"); ++ return 0; ++ } ++ ++ if (timeout == 0) { ++ res = sceKernelPollSema(sem->semid, 1); ++ if (res < 0) { ++ return SDL_MUTEX_TIMEDOUT; ++ } ++ return 0; ++ } ++ ++ if (timeout == SDL_MUTEX_MAXWAIT) { ++ pTimeout = NULL; ++ } else { ++ timeout *= 1000; /* Convert to microseconds. */ ++ pTimeout = &timeout; ++ } ++ ++ res = sceKernelWaitSema(sem->semid, 1, pTimeout); ++ switch (res) { ++ case SCE_KERNEL_ERROR_OK: ++ return 0; ++ case SCE_KERNEL_ERROR_WAIT_TIMEOUT: ++ return SDL_MUTEX_TIMEDOUT; ++ default: ++ SDL_SetError("WaitForSingleObject() failed"); ++ return -1; ++ } ++} ++ ++int SDL_SemTryWait(SDL_sem *sem) ++{ ++ return SDL_SemWaitTimeout(sem, 0); ++} ++ ++int SDL_SemWait(SDL_sem *sem) ++{ ++ return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); ++} ++ ++/* Returns the current count of the semaphore */ ++Uint32 SDL_SemValue(SDL_sem *sem) ++{ ++ SceKernelSemaInfo info; ++ ++ if (sem == NULL) { ++ SDL_SetError("Passed a NULL sem"); ++ return 0; ++ } ++ ++ if (sceKernelReferSemaStatus(sem->semid, &info) >= 0) { ++ return info.currentCount; ++ } ++ ++ return 0; ++} ++ ++int SDL_SemPost(SDL_sem *sem) ++{ ++ int res; ++ ++ if (sem == NULL) { ++ SDL_SetError("Passed a NULL sem"); ++ return -1; ++ } ++ ++ res = sceKernelSignalSema(sem->semid, 1); ++ if (res < 0) { ++ SDL_SetError("sceKernelSignalSema() failed"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/* vim: ts=4 sw=4 ++ */ +diff -burN SDL-1.2.15/src/thread/psp/SDL_systhread.c SDL-1.2.15-PSP/src/thread/psp/SDL_systhread.c +--- SDL-1.2.15/src/thread/psp/SDL_systhread.c 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/thread/psp/SDL_systhread.c 2012-06-06 12:55:07.478588936 +0200 +@@ -0,0 +1,94 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* PSP port contributed by Marcus R. Brown <mrbrown@ocgnet.org>. */ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_systhread.c,v 1.5 2004/01/04 16:49:19 slouken Exp $"; ++#endif ++ ++/* PSP thread management routines for SDL */ ++ ++#include <stdio.h> ++#include <stdlib.h> ++ ++#include "SDL_error.h" ++#include "SDL_thread.h" ++#include "../SDL_systhread.h" ++#include "../SDL_thread_c.h" ++ ++#include <pspkerneltypes.h> ++#include <pspthreadman.h> ++ ++static int ThreadEntry(SceSize args, void *argp) ++{ ++ SDL_RunThread(*(void **) argp); ++ return 0; ++} ++ ++int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) ++{ ++ SceKernelThreadInfo status; ++ int priority = 32; ++ ++ /* Set priority of new thread to the same as the current thread */ ++ status.size = sizeof(SceKernelThreadInfo); ++ if (sceKernelReferThreadStatus(sceKernelGetThreadId(), &status) == 0) { ++ priority = status.currentPriority; ++ } ++ ++ thread->handle = sceKernelCreateThread("SDL thread", ThreadEntry, ++ priority, 0x8000, ++ PSP_THREAD_ATTR_VFPU, NULL); ++ if (thread->handle < 0) { ++ SDL_SetError("sceKernelCreateThread() failed"); ++ return -1; ++ } ++ ++ sceKernelStartThread(thread->handle, 4, &args); ++ return 0; ++} ++ ++void SDL_SYS_SetupThread(void) ++{ ++ /* Do nothing. */ ++} ++ ++Uint32 SDL_ThreadID(void) ++{ ++ return (Uint32) sceKernelGetThreadId(); ++} ++ ++void SDL_SYS_WaitThread(SDL_Thread *thread) ++{ ++ sceKernelWaitThreadEnd(thread->handle, NULL); ++ sceKernelDeleteThread(thread->handle); ++} ++ ++void SDL_SYS_KillThread(SDL_Thread *thread) ++{ ++ sceKernelTerminateDeleteThread(thread->handle); ++} ++ ++/* vim: ts=4 sw=4 ++ */ +diff -burN SDL-1.2.15/src/thread/psp/SDL_systhread_c.h SDL-1.2.15-PSP/src/thread/psp/SDL_systhread_c.h +--- SDL-1.2.15/src/thread/psp/SDL_systhread_c.h 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/thread/psp/SDL_systhread_c.h 2012-06-06 12:55:07.478588936 +0200 +@@ -0,0 +1,27 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* PSP port contributed by Marcus R. Brown <mrbrown@ocgnet.org>. */ ++ ++#include <pspkerneltypes.h> ++ ++typedef SceUID SYS_ThreadHandle; +diff -burN SDL-1.2.15/src/thread/SDL_thread_c.h SDL-1.2.15-PSP/src/thread/SDL_thread_c.h +--- SDL-1.2.15/src/thread/SDL_thread_c.h 2012-01-19 07:30:06.000000000 +0100 ++++ SDL-1.2.15-PSP/src/thread/SDL_thread_c.h 2012-06-06 12:55:07.479588936 +0200 +@@ -43,6 +43,8 @@ + #include "win32/SDL_systhread_c.h" + #elif SDL_THREAD_SYMBIAN + #include "symbian/SDL_systhread_c.h" ++#elif SDL_THREAD_PSP ++#include "psp/SDL_systhread_c.h" + #else + #error Need thread implementation for this platform + #include "generic/SDL_systhread_c.h" +diff -burN SDL-1.2.15/src/timer/psp/SDL_systimer.c SDL-1.2.15-PSP/src/timer/psp/SDL_systimer.c +--- SDL-1.2.15/src/timer/psp/SDL_systimer.c 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/timer/psp/SDL_systimer.c 2012-06-06 12:55:07.479588936 +0200 +@@ -0,0 +1,114 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* ++ PSP port contributed by: ++ Marcus R. Brown <mrbrown@ocgnet.org> ++ Jim Paris <jim@jtan.com> ++*/ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_systimer.c,v 1.2 2004/01/04 16:49:19 slouken Exp $"; ++#endif ++ ++#include "SDL_thread.h" ++#include "SDL_timer.h" ++#include "SDL_error.h" ++#include "../SDL_timer_c.h" ++#include <stdlib.h> ++#include <time.h> ++#include <sys/time.h> ++#include <pspthreadman.h> ++ ++static struct timeval start; ++ ++void SDL_StartTicks(void) ++{ ++ gettimeofday(&start, NULL); ++} ++ ++Uint32 SDL_GetTicks(void) ++{ ++ struct timeval now; ++ Uint32 ticks; ++ ++ gettimeofday(&now, NULL); ++ ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; ++ return(ticks); ++} ++ ++void SDL_Delay(Uint32 ms) ++{ ++ const Uint32 max_delay = 0xffffffffUL / 1000; ++ if(ms > max_delay) ++ ms = max_delay; ++ sceKernelDelayThreadCB(ms * 1000); ++} ++ ++/* Data to handle a single periodic alarm */ ++static int timer_alive = 0; ++static SDL_Thread *timer = NULL; ++ ++static int RunTimer(void *unused) ++{ ++ while ( timer_alive ) { ++ if ( SDL_timer_running ) { ++ SDL_ThreadedTimerCheck(); ++ } ++ SDL_Delay(10); ++ } ++ return(0); ++} ++ ++/* This is only called if the event thread is not running */ ++int SDL_SYS_TimerInit(void) ++{ ++ timer_alive = 1; ++ timer = SDL_CreateThread(RunTimer, NULL); ++ if ( timer == NULL ) ++ return(-1); ++ return(SDL_SetTimerThreaded(1)); ++} ++ ++void SDL_SYS_TimerQuit(void) ++{ ++ timer_alive = 0; ++ if ( timer ) { ++ SDL_WaitThread(timer, NULL); ++ timer = NULL; ++ } ++} ++ ++int SDL_SYS_StartTimer(void) ++{ ++ SDL_SetError("Internal logic error: PSP uses threaded timer"); ++ return(-1); ++} ++ ++void SDL_SYS_StopTimer(void) ++{ ++ return; ++} ++ ++/* vim: ts=4 sw=4 ++ */ +diff -burN SDL-1.2.15/src/video/psp/SDL_pspevents.c SDL-1.2.15-PSP/src/video/psp/SDL_pspevents.c +--- SDL-1.2.15/src/video/psp/SDL_pspevents.c 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/video/psp/SDL_pspevents.c 2012-06-06 12:55:07.480588936 +0200 +@@ -0,0 +1,281 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* PSP port contributed by Marcus R. Brown <mrbrown@ocgnet.org>. */ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_nullevents.c,v 1.4 2004/01/04 16:49:24 slouken Exp $"; ++#endif ++ ++/* Being a null driver, there's no event stream. We just define stubs for ++ most of the API. */ ++ ++#include "SDL.h" ++#include "../../events/SDL_sysevents.h" ++#include "../../events/SDL_events_c.h" ++#include "SDL_pspvideo.h" ++#include "SDL_pspevents_c.h" ++#include "SDL_thread.h" ++#include <psphprm.h> ++ ++#ifdef PSPIRKEYB ++#include <pspirkeyb.h> ++#include <pspirkeyb_rawkeys.h> ++ ++#define IRKBD_CONFIG_FILE NULL /* this will take ms0:/seplugins/pspirkeyb.ini */ ++ ++static int irkbd_ready = 0; ++static SDLKey keymap[256]; ++#endif ++ ++static enum PspHprmKeys hprm = 0; ++static SDL_sem *event_sem = NULL; ++static SDL_Thread *thread = NULL; ++static int running = 0; ++static struct { ++ enum PspHprmKeys id; ++ SDLKey sym; ++} keymap_psp[] = { ++ { PSP_HPRM_PLAYPAUSE, SDLK_F10 }, ++ { PSP_HPRM_FORWARD, SDLK_F11 }, ++ { PSP_HPRM_BACK, SDLK_F12 }, ++ { PSP_HPRM_VOL_UP, SDLK_F13 }, ++ { PSP_HPRM_VOL_DOWN, SDLK_F14 }, ++ { PSP_HPRM_HOLD, SDLK_F15 } ++}; ++ ++int EventUpdate(void *data) ++{ ++ while (running) { ++ SDL_SemWait(event_sem); ++ sceHprmPeekCurrentKey(&hprm); ++ SDL_SemPost(event_sem); ++ /* Delay 1/60th of a second */ ++ sceKernelDelayThread(1000000 / 60); ++ } ++ return 0; ++} ++ ++void PSP_PumpEvents(_THIS) ++{ ++ int i; ++ enum PspHprmKeys keys; ++ enum PspHprmKeys changed; ++ static enum PspHprmKeys old_keys = 0; ++ SDL_keysym sym; ++ ++ SDL_SemWait(event_sem); ++ keys = hprm; ++ SDL_SemPost(event_sem); ++ ++ /* HPRM Keyboard */ ++ changed = old_keys ^ keys; ++ old_keys = keys; ++ if(changed) { ++ for(i=0; i<sizeof(keymap_psp)/sizeof(keymap_psp[0]); i++) { ++ if(changed & keymap_psp[i].id) { ++ sym.scancode = keymap_psp[i].id; ++ sym.sym = keymap_psp[i].sym; ++ SDL_PrivateKeyboard((keys & keymap_psp[i].id) ? ++ SDL_PRESSED : SDL_RELEASED, ++ &sym); ++ } ++ } ++ } ++ ++#ifdef PSPIRKEYB ++ if (irkbd_ready) { ++ unsigned char buffer[255]; ++ int i, length, count; ++ SIrKeybScanCodeData *scanData; ++ ++ if(pspIrKeybReadinput(buffer, &length) >= 0) { ++ if((length % sizeof(SIrKeybScanCodeData)) == 0){ ++ count = length / sizeof(SIrKeybScanCodeData); ++ for( i=0; i < count; i++ ) { ++ unsigned char raw, pressed; ++ scanData=(SIrKeybScanCodeData*) buffer+i; ++ raw = scanData->raw; ++ pressed = scanData->pressed; ++ sym.scancode = raw; ++ sym.sym = keymap[raw]; ++ SDL_PrivateKeyboard(pressed?SDL_PRESSED:SDL_RELEASED, &sym); ++ } ++ } ++ } ++ } ++#endif ++ sceKernelDelayThread(0); ++ ++ return; ++} ++ ++void PSP_InitOSKeymap(_THIS) ++{ ++#ifdef PSPIRKEYB ++ int i; ++ for (i=0; i<SDL_TABLESIZE(keymap); ++i) ++ keymap[i] = SDLK_UNKNOWN; ++ ++ keymap[KEY_ESC] = SDLK_ESCAPE; ++ ++ keymap[KEY_F1] = SDLK_F1; ++ keymap[KEY_F2] = SDLK_F2; ++ keymap[KEY_F3] = SDLK_F3; ++ keymap[KEY_F4] = SDLK_F4; ++ keymap[KEY_F5] = SDLK_F5; ++ keymap[KEY_F6] = SDLK_F6; ++ keymap[KEY_F7] = SDLK_F7; ++ keymap[KEY_F8] = SDLK_F8; ++ keymap[KEY_F9] = SDLK_F9; ++ keymap[KEY_F10] = SDLK_F10; ++ keymap[KEY_F11] = SDLK_F11; ++ keymap[KEY_F12] = SDLK_F12; ++ keymap[KEY_F13] = SDLK_PRINT; ++ keymap[KEY_F14] = SDLK_PAUSE; ++ ++ keymap[KEY_GRAVE] = SDLK_BACKQUOTE; ++ keymap[KEY_1] = SDLK_1; ++ keymap[KEY_2] = SDLK_2; ++ keymap[KEY_3] = SDLK_3; ++ keymap[KEY_4] = SDLK_4; ++ keymap[KEY_5] = SDLK_5; ++ keymap[KEY_6] = SDLK_6; ++ keymap[KEY_7] = SDLK_7; ++ keymap[KEY_8] = SDLK_8; ++ keymap[KEY_9] = SDLK_9; ++ keymap[KEY_0] = SDLK_0; ++ keymap[KEY_MINUS] = SDLK_MINUS; ++ keymap[KEY_EQUAL] = SDLK_EQUALS; ++ keymap[KEY_BACKSPACE] = SDLK_BACKSPACE; ++ ++ keymap[KEY_TAB] = SDLK_TAB; ++ keymap[KEY_Q] = SDLK_q; ++ keymap[KEY_W] = SDLK_w; ++ keymap[KEY_E] = SDLK_e; ++ keymap[KEY_R] = SDLK_r; ++ keymap[KEY_T] = SDLK_t; ++ keymap[KEY_Y] = SDLK_y; ++ keymap[KEY_U] = SDLK_u; ++ keymap[KEY_I] = SDLK_i; ++ keymap[KEY_O] = SDLK_o; ++ keymap[KEY_P] = SDLK_p; ++ keymap[KEY_LEFTBRACE] = SDLK_LEFTBRACKET; ++ keymap[KEY_RIGHTBRACE] = SDLK_RIGHTBRACKET; ++ keymap[KEY_ENTER] = SDLK_RETURN; ++ ++ keymap[KEY_CAPSLOCK] = SDLK_CAPSLOCK; ++ keymap[KEY_A] = SDLK_a; ++ keymap[KEY_S] = SDLK_s; ++ keymap[KEY_D] = SDLK_d; ++ keymap[KEY_F] = SDLK_f; ++ keymap[KEY_G] = SDLK_g; ++ keymap[KEY_H] = SDLK_h; ++ keymap[KEY_J] = SDLK_j; ++ keymap[KEY_K] = SDLK_k; ++ keymap[KEY_L] = SDLK_l; ++ keymap[KEY_SEMICOLON] = SDLK_SEMICOLON; ++ keymap[KEY_APOSTROPHE] = SDLK_QUOTE; ++ keymap[KEY_BACKSLASH] = SDLK_BACKSLASH; ++ ++ keymap[KEY_Z] = SDLK_z; ++ keymap[KEY_X] = SDLK_x; ++ keymap[KEY_C] = SDLK_c; ++ keymap[KEY_V] = SDLK_v; ++ keymap[KEY_B] = SDLK_b; ++ keymap[KEY_N] = SDLK_n; ++ keymap[KEY_M] = SDLK_m; ++ keymap[KEY_COMMA] = SDLK_COMMA; ++ keymap[KEY_DOT] = SDLK_PERIOD; ++ keymap[KEY_SLASH] = SDLK_SLASH; ++ ++ keymap[KEY_SPACE] = SDLK_SPACE; ++ ++ keymap[KEY_UP] = SDLK_UP; ++ keymap[KEY_DOWN] = SDLK_DOWN; ++ keymap[KEY_LEFT] = SDLK_LEFT; ++ keymap[KEY_RIGHT] = SDLK_RIGHT; ++ ++ keymap[KEY_HOME] = SDLK_HOME; ++ keymap[KEY_END] = SDLK_END; ++ keymap[KEY_INSERT] = SDLK_INSERT; ++ keymap[KEY_DELETE] = SDLK_DELETE; ++ ++ keymap[KEY_NUMLOCK] = SDLK_NUMLOCK; ++ keymap[KEY_LEFTMETA] = SDLK_LSUPER; ++ ++ keymap[KEY_KPSLASH] = SDLK_KP_DIVIDE; ++ keymap[KEY_KPASTERISK] = SDLK_KP_MULTIPLY; ++ keymap[KEY_KPMINUS] = SDLK_KP_MINUS; ++ keymap[KEY_KPPLUS] = SDLK_KP_PLUS; ++ keymap[KEY_KPDOT] = SDLK_KP_PERIOD; ++ keymap[KEY_KPEQUAL] = SDLK_KP_EQUALS; ++ ++ keymap[KEY_LEFTCTRL] = SDLK_LCTRL; ++ keymap[KEY_RIGHTCTRL] = SDLK_RCTRL; ++ keymap[KEY_LEFTALT] = SDLK_LALT; ++ keymap[KEY_RIGHTALT] = SDLK_RALT; ++ keymap[KEY_LEFTSHIFT] = SDLK_LSHIFT; ++ keymap[KEY_RIGHTSHIFT] = SDLK_RSHIFT; ++#endif ++} ++ ++void PSP_EventInit(_THIS) ++{ ++#ifdef PSPIRKEYB ++ int outputmode = PSP_IRKBD_OUTPUT_MODE_SCANCODE; ++ int ret = pspIrKeybInit(IRKBD_CONFIG_FILE, 0); ++ if (ret == PSP_IRKBD_RESULT_OK) { ++ pspIrKeybOutputMode(outputmode); ++ irkbd_ready = 1; ++ } else { ++ irkbd_ready = 0; ++ } ++#endif ++ /* Start thread to read data */ ++ if((event_sem = SDL_CreateSemaphore(1)) == NULL) { ++ SDL_SetError("Can't create input semaphore\n"); ++ return; ++ } ++ running = 1; ++ if((thread = SDL_CreateThread(EventUpdate, NULL)) == NULL) { ++ SDL_SetError("Can't create input thread\n"); ++ return; ++ } ++} ++ ++void PSP_EventQuit(_THIS) ++{ ++ running = 0; ++ SDL_WaitThread(thread, NULL); ++ SDL_DestroySemaphore(event_sem); ++#ifdef PSPIRKEYB ++ if (irkbd_ready) { ++ pspIrKeybFinish(); ++ irkbd_ready = 0; ++ } ++#endif ++} ++ ++/* end of SDL_pspevents.c ... */ ++ +diff -burN SDL-1.2.15/src/video/psp/SDL_pspevents_c.h SDL-1.2.15-PSP/src/video/psp/SDL_pspevents_c.h +--- SDL-1.2.15/src/video/psp/SDL_pspevents_c.h 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/video/psp/SDL_pspevents_c.h 2012-06-06 12:55:07.480588936 +0200 +@@ -0,0 +1,39 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* PSP port contributed by Marcus R. Brown <mrbrown@ocgnet.org>. */ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_nullevents_c.h,v 1.4 2004/01/04 16:49:24 slouken Exp $"; ++#endif ++ ++#include "SDL_pspvideo.h" ++ ++/* Variables and functions exported by SDL_sysevents.c to other parts ++ of the native video subsystem (SDL_sysvideo.c) ++*/ ++extern void PSP_InitOSKeymap(_THIS); ++extern void PSP_PumpEvents(_THIS); ++ ++/* end of SDL_pspevents_c.h ... */ ++ +diff -burN SDL-1.2.15/src/video/psp/SDL_pspgl.c SDL-1.2.15-PSP/src/video/psp/SDL_pspgl.c +--- SDL-1.2.15/src/video/psp/SDL_pspgl.c 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/video/psp/SDL_pspgl.c 2012-06-06 12:55:07.480588936 +0200 +@@ -0,0 +1,151 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++#include <stdlib.h> ++#include <string.h> ++ ++#include "SDL_error.h" ++#include "SDL_pspvideo.h" ++#include "SDL_pspgl_c.h" ++ ++#ifdef HAVE_OPENGL ++ ++/* pspgl doesn't provide this call, so stub it out since SDL requires it. */ ++#define GLSTUB(func,params) void func params {} ++GLSTUB(glCopyTexImage1D, (GLenum target, GLint level, GLenum internalFormat, ++ GLint x, GLint y, GLsizei width, GLint border)) ++ ++static const struct { ++ const char *proc; ++ void *func; ++} glfuncs[] = { ++#define SDL_PROC(ret,func,params) {#func,&func}, ++#include "../SDL_glfuncs.h" ++#undef SDL_PROC ++}; ++#define GLFUNCS_COUNT (sizeof(glfuncs) / sizeof(glfuncs[0])) ++ ++void * PSP_GL_GetProcAddress(_THIS, const char *proc) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < GLFUNCS_COUNT; i++) ++ { ++ if (strcmp(proc, glfuncs[i].proc) == 0) ++ return glfuncs[i].func; ++ } ++ ++ return NULL; ++} ++ ++int PSP_GL_GetAttribute(_THIS, SDL_GLattr attrib, int *value) ++{ ++ return 0; ++} ++ ++int PSP_GL_MakeCurrent(_THIS) ++{ ++ struct SDL_PrivateGLData *gl_data = this->gl_data; ++ ++ if (!eglMakeCurrent(gl_data->display, gl_data->surface, gl_data->surface, gl_data->context)) ++ { ++ SDL_SetError("Unable to make EGL context current"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++void PSP_GL_SwapBuffers(_THIS) ++{ ++ struct SDL_PrivateGLData *gl_data = this->gl_data; ++ ++ eglSwapBuffers(gl_data->display, gl_data->surface); ++} ++ ++#define EGLCHK(stmt) \ ++ do { \ ++ EGLint err; \ ++ \ ++ stmt; \ ++ err = eglGetError(); \ ++ if (err != EGL_SUCCESS) { \ ++ SDL_SetError("EGL error %d", err); \ ++ return 0; \ ++ } \ ++ } while (0) ++ ++/* Return 1 if we were able to initialize PSPGL successfully. */ ++int PSP_GL_Init(_THIS) ++{ ++ EGLint attribs[32]; ++ EGLDisplay display; ++ EGLContext context; ++ EGLSurface surface; ++ EGLConfig config; ++ EGLint num_configs; ++ int i; ++ ++ /* EGL init taken from glutCreateWindow() in PSPGL's glut.c. */ ++ EGLCHK(display = eglGetDisplay(0)); ++ EGLCHK(eglInitialize(display, NULL, NULL)); ++ ++ /* Setup the config based on SDL's current values. */ ++ i = 0; ++ attribs[i++] = EGL_RED_SIZE; ++ attribs[i++] = this->gl_config.red_size; ++ attribs[i++] = EGL_GREEN_SIZE; ++ attribs[i++] = this->gl_config.green_size; ++ attribs[i++] = EGL_BLUE_SIZE; ++ attribs[i++] = this->gl_config.blue_size; ++ attribs[i++] = EGL_DEPTH_SIZE; ++ attribs[i++] = this->gl_config.depth_size; ++ ++ if (this->gl_config.alpha_size) ++ { ++ attribs[i++] = EGL_ALPHA_SIZE; ++ attribs[i++] = this->gl_config.alpha_size; ++ } ++ if (this->gl_config.stencil_size) ++ { ++ attribs[i++] = EGL_STENCIL_SIZE; ++ attribs[i++] = this->gl_config.stencil_size; ++ } ++ ++ attribs[i++] = EGL_NONE; ++ EGLCHK(eglChooseConfig(display, attribs, &config, 1, &num_configs)); ++ ++ if (num_configs == 0) ++ { ++ SDL_SetError("No valid EGL configs for requested mode"); ++ return 0; ++ } ++ ++ EGLCHK(context = eglCreateContext(display, config, NULL, NULL)); ++ EGLCHK(surface = eglCreateWindowSurface(display, config, 0, NULL)); ++ ++ this->gl_data->display = display; ++ this->gl_data->context = context; ++ this->gl_data->surface = surface; ++ return 1; ++} ++#endif /* HAVE_OPENGL */ +diff -burN SDL-1.2.15/src/video/psp/SDL_pspgl_c.h SDL-1.2.15-PSP/src/video/psp/SDL_pspgl_c.h +--- SDL-1.2.15/src/video/psp/SDL_pspgl_c.h 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/video/psp/SDL_pspgl_c.h 2012-06-06 12:55:07.481588936 +0200 +@@ -0,0 +1,50 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++#ifndef _SDL_pspgl_c_h ++#define _SDL_pspgl_c_h ++ ++#ifdef HAVE_OPENGL ++#include <GL/gl.h> ++#include <GLES/egl.h> ++#endif ++ ++#include "SDL_pspvideo.h" ++ ++struct SDL_PrivateGLData { ++#ifdef HAVE_OPENGL ++ EGLDisplay display; ++ EGLContext context; ++ EGLSurface surface; ++#endif ++}; ++ ++#ifdef HAVE_OPENGL ++extern int PSP_GL_Init(_THIS); ++ ++extern void * PSP_GL_GetProcAddress(_THIS, const char *proc); ++extern int PSP_GL_GetAttribute(_THIS, SDL_GLattr attrib, int *value); ++extern int PSP_GL_MakeCurrent(_THIS); ++extern void PSP_GL_SwapBuffers(_THIS); ++#endif ++ ++#endif /* _SDL_pspgl_c_h */ +diff -burN SDL-1.2.15/src/video/psp/SDL_pspmouse.c SDL-1.2.15-PSP/src/video/psp/SDL_pspmouse.c +--- SDL-1.2.15/src/video/psp/SDL_pspmouse.c 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/video/psp/SDL_pspmouse.c 2012-06-06 12:55:07.481588936 +0200 +@@ -0,0 +1,42 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* PSP port contributed by Marcus R. Brown <mrbrown@ocgnet.org>. */ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_nullmouse.c,v 1.4 2004/01/04 16:49:24 slouken Exp $"; ++#endif ++ ++#include <stdio.h> ++ ++#include "SDL_error.h" ++#include "SDL_mouse.h" ++#include "../../events/SDL_events_c.h" ++ ++#include "SDL_pspmouse_c.h" ++ ++ ++/* The implementation dependent data for the window manager cursor */ ++struct WMcursor { ++ int unused; ++}; +diff -burN SDL-1.2.15/src/video/psp/SDL_pspmouse_c.h SDL-1.2.15-PSP/src/video/psp/SDL_pspmouse_c.h +--- SDL-1.2.15/src/video/psp/SDL_pspmouse_c.h 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/video/psp/SDL_pspmouse_c.h 2012-06-06 12:55:07.481588936 +0200 +@@ -0,0 +1,32 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* PSP port contributed by Marcus R. Brown <mrbrown@ocgnet.org>. */ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_nullmouse_c.h,v 1.4 2004/01/04 16:49:24 slouken Exp $"; ++#endif ++ ++#include "SDL_pspvideo.h" ++ ++/* Functions to be exported */ +diff -burN SDL-1.2.15/src/video/psp/SDL_pspvideo.c SDL-1.2.15-PSP/src/video/psp/SDL_pspvideo.c +--- SDL-1.2.15/src/video/psp/SDL_pspvideo.c 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/video/psp/SDL_pspvideo.c 2012-06-06 12:55:07.482588936 +0200 +@@ -0,0 +1,790 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* ++ PSP port contributed by: ++ Marcus R. Brown <mrbrown@ocgnet.org> ++ Jim Paris <jim@jtan.com> ++ Matthew H <matthewh@webone.com.au> ++*/ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_nullvideo.c,v 1.7 2004/01/04 16:49:24 slouken Exp $"; ++#endif ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <malloc.h> ++ ++#include "SDL.h" ++#include "SDL_error.h" ++#include "SDL_video.h" ++#include "SDL_mouse.h" ++#include "../SDL_sysvideo.h" ++#include "../SDL_pixels_c.h" ++#include "../../events/SDL_events_c.h" ++ ++#include "SDL_pspvideo.h" ++#include "SDL_pspevents_c.h" ++#include "SDL_pspgl_c.h" ++#include "SDL_pspmouse_c.h" ++ ++#define PSPVID_DRIVER_NAME "psp" ++ ++#define PSP_SLICE_SIZE (32) ++#define PSP_LINE_SIZE (512) ++#define SCREEN_WIDTH (480) ++#define SCREEN_HEIGHT (272) ++ ++#define IS_SWSURFACE(flags) ((flags & SDL_HWSURFACE) == SDL_SWSURFACE) ++#define IS_HWSURFACE(flags) ((flags & SDL_HWSURFACE) == SDL_HWSURFACE) ++ ++static unsigned int list[4096] __attribute__((aligned(16))); ++ ++struct texVertex ++{ ++ unsigned short u, v; ++ short x, y, z; ++}; ++ ++struct rectVertex ++{ ++ short x, y, z; ++}; ++ ++/* Initialization/Query functions */ ++static int PSP_VideoInit(_THIS, SDL_PixelFormat *vformat); ++static SDL_Rect **PSP_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); ++static SDL_Surface *PSP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); ++static int PSP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); ++static void PSP_VideoQuit(_THIS); ++void PSP_EventInit(_THIS); ++void PSP_EventQuit(_THIS); ++ ++/* Hardware surface functions */ ++static int PSP_AllocHWSurface(_THIS, SDL_Surface *surface); ++static int PSP_LockHWSurface(_THIS, SDL_Surface *surface); ++static void PSP_UnlockHWSurface(_THIS, SDL_Surface *surface); ++static void PSP_FreeHWSurface(_THIS, SDL_Surface *surface); ++static int PSP_FlipHWSurface(_THIS, SDL_Surface *surface); ++static void PSP_UpdateRects(_THIS, int numrects, SDL_Rect *rects); ++static void PSP_GuInit(_THIS, SDL_Surface *current, int bpp); ++static int PSP_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst); ++static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, ++ SDL_Surface *dst, SDL_Rect *dstrect); ++static int PSP_GuStretchBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Rect *dstrect); ++static int PSP_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color); ++ ++/* Software surface function */ ++static void PSP_GuUpdateRects(_THIS, int numrects, SDL_Rect *rects); ++ ++/* return a suitable psm value for a particular bpp */ ++static inline int psm_value(int bpp) { ++ if (bpp == 15) ++ return GU_PSM_5551; ++ if (bpp == 16) ++ return GU_PSM_5650; ++ return GU_PSM_8888; ++} ++ ++/* PSP driver bootstrap functions */ ++ ++static int PSP_Available(void) ++{ ++ return 1; ++} ++ ++static void PSP_DeleteDevice(SDL_VideoDevice *device) ++{ ++ if (device) { ++ if (device->hidden) { ++ free(device->hidden); ++ } ++#ifdef HAVE_OPENGL ++ if (device->gl_data) { ++ free(device->gl_data); ++ } ++#endif ++ free(device); ++ } ++} ++ ++static SDL_VideoDevice *PSP_CreateDevice(int devindex) ++{ ++ SDL_VideoDevice *device; ++ ++ /* Initialize all variables that we clean on shutdown */ ++ device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); ++ if ( device ) { ++ memset(device, 0, (sizeof *device)); ++ device->hidden = (struct SDL_PrivateVideoData *) ++ malloc((sizeof *device->hidden)); ++#ifdef HAVE_OPENGL ++ device->gl_data = (struct SDL_PrivateGLData *) ++ malloc((sizeof *device->gl_data)); ++#endif ++ } ++ if ( (device == NULL) || (device->hidden == NULL) ++#ifdef HAVE_OPENGL ++ || (device->gl_data == NULL) ++#endif ++ ) { ++ SDL_OutOfMemory(); ++ if ( device ) { ++ free(device); ++ } ++ return(0); ++ } ++ memset(device->hidden, 0, (sizeof *device->hidden)); ++#ifdef HAVE_OPENGL ++ memset(device->gl_data, 0, (sizeof *device->gl_data)); ++#endif ++ ++ /* Set the function pointers */ ++ device->VideoInit = PSP_VideoInit; ++ device->ListModes = PSP_ListModes; ++ device->SetVideoMode = PSP_SetVideoMode; ++ device->CreateYUVOverlay = NULL; ++ device->SetColors = PSP_SetColors; ++ device->UpdateRects = PSP_UpdateRects; ++ device->VideoQuit = PSP_VideoQuit; ++ device->AllocHWSurface = PSP_AllocHWSurface; ++ device->CheckHWBlit = PSP_CheckHWBlit; ++ device->FillHWRect = PSP_FillHWRect; ++ device->SetHWColorKey = NULL; ++ device->SetHWAlpha = NULL; ++ device->LockHWSurface = PSP_LockHWSurface; ++ device->UnlockHWSurface = PSP_UnlockHWSurface; ++ device->FlipHWSurface = PSP_FlipHWSurface; ++ device->FreeHWSurface = PSP_FreeHWSurface; ++#ifdef HAVE_OPENGL ++ device->GL_GetProcAddress = PSP_GL_GetProcAddress; ++ device->GL_GetAttribute = PSP_GL_GetAttribute; ++ device->GL_MakeCurrent = PSP_GL_MakeCurrent; ++ device->GL_SwapBuffers = PSP_GL_SwapBuffers; ++#endif ++ device->SetCaption = NULL; ++ device->SetIcon = NULL; ++ device->IconifyWindow = NULL; ++ device->GrabInput = NULL; ++ device->GetWMInfo = NULL; ++ device->InitOSKeymap = PSP_InitOSKeymap; ++ device->PumpEvents = PSP_PumpEvents; ++ ++ device->free = PSP_DeleteDevice; ++ ++ return device; ++} ++ ++VideoBootStrap PSP_bootstrap = { ++ PSPVID_DRIVER_NAME, "PSP video driver", ++ PSP_Available, PSP_CreateDevice ++}; ++ ++const static SDL_Rect RECT_480x272 = { .x = 0, .y = 0, .w = 480, .h = 272 }; ++const static SDL_Rect *modelist[] = { ++ &RECT_480x272, ++ NULL ++}; ++ ++int PSP_VideoInit(_THIS, SDL_PixelFormat *vformat) ++{ ++ /* Default for pspsdk is 8888 ABGR */ ++ vformat->BitsPerPixel = 32; ++ vformat->BytesPerPixel = 4; ++ ++ this->info.wm_available = 0; ++ this->info.hw_available = 1; ++ this->info.blit_fill = 0; /* todo: fixme */ ++ this->info.blit_hw = 1; ++ this->info.blit_hw_CC = 1; ++ this->info.blit_hw_A = 0; /* todo: implement me */ ++ ++ PSP_EventInit(this); ++ ++ return(0); ++} ++ ++SDL_Rect **PSP_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) ++{ ++ /* x dimension should be a multiple of PSP_SLICE_SIZE */ ++ if (IS_SWSURFACE(flags)) ++ return (SDL_Rect **)-1; ++ ++ switch(format->BitsPerPixel) { ++ case 8: /* proxied by a shadow surface */ ++ case 15: ++ case 16: ++ case 32: ++ return (SDL_Rect **)modelist; ++ default: ++ return NULL; ++ } ++} ++ ++static void PSP_GuInit(_THIS, SDL_Surface *current, int bpp) { ++ void *dispbuffer = (void*) 0; ++ void *drawbuffer = (void*) this->hidden->frame_offset; ++ ++ sceGuInit(); ++ sceGuStart(GU_DIRECT, list); ++ sceGuDispBuffer(SCREEN_WIDTH, SCREEN_HEIGHT, dispbuffer, PSP_LINE_SIZE); ++ if (IS_SWSURFACE(current->flags) || (current->flags & SDL_HWPALETTE)) { ++ sceGuClutMode(GU_PSM_8888, 0, 255, 0); ++ sceGuDrawBuffer(GU_PSM_8888, drawbuffer, PSP_LINE_SIZE); ++ } else { ++ sceGuDrawBuffer(psm_value(bpp), drawbuffer, PSP_LINE_SIZE); ++ } ++ sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT); ++ sceGuOffset(2048 - (SCREEN_WIDTH / 2), 2048 - (SCREEN_HEIGHT / 2)); ++ sceGuViewport(2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT); ++ sceGuScissor(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); ++ sceGuEnable(GU_SCISSOR_TEST); ++ sceGuFrontFace(GU_CW); ++ ++ sceGuFinish(); ++ sceGuSync(0, 0); ++ ++ sceDisplayWaitVblankStart(); ++ sceGuDisplay(1); ++} ++ ++/* ++vidmem handling from Holger Waechtler's pspgl ++*/ ++struct vidmem_chunk { ++ void *ptr; ++ unsigned long len; ++}; ++ ++ ++static struct vidmem_chunk *vidmem_map = NULL; ++static unsigned long vidmem_map_len = 0; ++ ++static ++void *vidmem_map_insert_new (unsigned long idx, unsigned long adr, unsigned long size) ++{ ++ void *tmp = realloc(vidmem_map, (vidmem_map_len + 1) * sizeof(vidmem_map[0])); ++ ++ if (!tmp) ++ return NULL; ++ ++ vidmem_map = tmp; ++ memmove(&vidmem_map[idx+1], &vidmem_map[idx], (vidmem_map_len-idx) * sizeof(vidmem_map[0])); ++ vidmem_map_len++; ++ vidmem_map[idx].ptr = (void*) adr; ++ vidmem_map[idx].len = size; ++ ++ return vidmem_map[idx].ptr; ++} ++ ++ ++void* vidmem_alloc (unsigned long size) ++{ ++ unsigned long start = (unsigned long) sceGeEdramGetAddr(); ++ unsigned long adr = start; ++ unsigned long i; ++ ++ /* round the size up to the nearest 16 bytes and all hwsurfaces are safe to ++ use as textures */ ++ if (size % 16 != 0) ++ size += 16 - (size % 16); ++ ++ for (i=0; i<vidmem_map_len; i++) { ++ if (vidmem_map[i].ptr != NULL) { ++ unsigned long new_adr = (unsigned long) vidmem_map[i].ptr; ++ if (size <= new_adr - adr) ++ return vidmem_map_insert_new(i, adr, size); ++ adr = new_adr + vidmem_map[i].len; ++ } ++ } ++ ++ if (adr + size > start + sceGeEdramGetSize()) ++ return NULL; ++ ++ return vidmem_map_insert_new(vidmem_map_len, adr, size); ++} ++ ++ ++void vidmem_free (void * ptr) ++{ ++ int i; ++ ++ for (i=0; i<vidmem_map_len; i++) { ++ if (vidmem_map[i].ptr == ptr) { ++ void *tmp; ++ ++ vidmem_map_len--; ++ memmove(&vidmem_map[i], &vidmem_map[i+1], (vidmem_map_len-i) * sizeof(vidmem_map[0])); ++ tmp = realloc(vidmem_map, vidmem_map_len * sizeof(vidmem_map[0])); ++ if (tmp) ++ vidmem_map = tmp; ++ } ++ } ++} ++ ++static inline int roundUpToPowerOfTwo (int x) ++{ ++ return 1 << (32 - __builtin_allegrex_clz(x - 1)); ++} ++ ++SDL_Surface *PSP_SetVideoMode(_THIS, SDL_Surface *current, ++ int width, int height, int bpp, Uint32 flags) ++{ ++ int disp_pitch = 512, draw_pitch = 512, pixel_format; ++ Uint32 Amask, Rmask, Gmask, Bmask; ++ ++ if (IS_HWSURFACE(flags) && ++ (width != SCREEN_WIDTH || height != SCREEN_HEIGHT)) ++ { ++ SDL_SetError("Couldn't find requested mode"); ++ return NULL; ++ } ++ ++ switch(bpp) { ++ case 8: /* indexed, uses a shadow buffer for hwsurfaces */ ++ disp_pitch *= 4; ++ Amask = 0; ++ Rmask = 0; ++ Gmask = 0; ++ Bmask = 0; ++ pixel_format = PSP_DISPLAY_PIXEL_FORMAT_8888; ++ break; ++ case 15: /* 5-5-5-1 */ ++ disp_pitch *= 2; ++ draw_pitch *= 2; ++ Amask = 0x00008000; ++ Rmask = 0x0000001f; ++ Gmask = 0x000003e0; ++ Bmask = 0x00007c00; ++ pixel_format = PSP_DISPLAY_PIXEL_FORMAT_5551; ++ break; ++ case 16: /* 5-6-5 */ ++ disp_pitch *= 2; ++ draw_pitch *= 2; ++ Amask = 0; ++ Rmask = 0x0000001f; ++ Gmask = 0x000007e0; ++ Bmask = 0x0000f800; ++ pixel_format = PSP_DISPLAY_PIXEL_FORMAT_565; ++ break; ++ case 32: /* 8-8-8-8 */ ++ disp_pitch *= 4; ++ draw_pitch *= 4; ++ Amask = 0xff000000; ++ Rmask = 0x000000ff; ++ Gmask = 0x0000ff00; ++ Bmask = 0x00ff0000; ++ pixel_format = PSP_DISPLAY_PIXEL_FORMAT_8888; ++ break; ++ default: ++ SDL_SetError("Couldn't find requested mode"); ++ return(NULL); ++ } ++ ++ if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0/*Amask*/) ) { ++ SDL_SetError("Couldn't allocate color format"); ++ return(NULL); ++ } ++ ++ current->flags = flags | SDL_FULLSCREEN; ++ current->w = width; ++ current->h = height; ++ ++#ifdef HAVE_OPENGL ++ if (flags & SDL_OPENGL) ++ { ++ this->gl_config.driver_loaded = 1; ++ current->flags = SDL_FULLSCREEN | SDL_OPENGL; ++ /* HACK: What does this need to be? */ ++ current->pixels = memalign(16, draw_pitch * height); ++ ++ if (!PSP_GL_Init(this)) ++ { ++ /* Don't set an error here as PSP_GL_Init() will set one. */ ++ return NULL; ++ } ++ return current; ++ } ++#endif ++ ++ this->hidden->psm = psm_value(bpp); ++ this->hidden->tpsm = this->hidden->psm; ++ this->hidden->pixel_format = pixel_format; ++ this->hidden->frame = 0; ++ this->hidden->frame_offset = 0; ++ ++ /* allocate display buffer */ ++ this->hidden->vram_base = vidmem_alloc(disp_pitch * SCREEN_HEIGHT); ++ ++ sceDisplaySetMode(0, SCREEN_WIDTH, SCREEN_HEIGHT); ++ sceDisplaySetFrameBuf(this->hidden->vram_base, 512, pixel_format, ++ PSP_DISPLAY_SETBUF_NEXTFRAME); ++ ++ if (IS_HWSURFACE(flags)) { ++ ++ current->pitch = draw_pitch; ++ ++ if (flags & SDL_DOUBLEBUF) { ++ this->hidden->frame_offset = disp_pitch * height; ++ ++ /* Set the draw buffer to the second frame. */ ++ this->hidden->frame = 1; ++ ++ /* allocate drawbuffer */ ++ vidmem_alloc(disp_pitch * height); ++ } ++ ++ if (bpp == 8) { ++ /* create a shadow surface */ ++ current->pixels = memalign(16, current->pitch * height); ++ ++ /* can't hwaccel 8bpp hwsurface */ ++ this->info.blit_fill = 0; ++ this->info.blit_hw = 0; ++ } else { ++ current->pixels = (void *) ((Uint32) this->hidden->vram_base + ++ this->hidden->frame_offset); ++ current->flags |= SDL_PREALLOC; /* so SDL doesn't free ->pixels */ ++ } ++ ++ } else if (IS_SWSURFACE(flags)) { ++ char *aspect_ratio; ++ ++ aspect_ratio = getenv("SDL_ASPECT_RATIO"); ++ ++ if (aspect_ratio && !strcmp(aspect_ratio, "4:3")) { ++ this->hidden->hw_rect.w = 360; ++ this->hidden->hw_rect.h = 272; ++ this->hidden->hw_rect.x = 60; ++ this->hidden->hw_rect.y = 0; ++ } else { ++ this->hidden->hw_rect.w = 480; ++ this->hidden->hw_rect.h = 272; ++ this->hidden->hw_rect.x = 0; ++ this->hidden->hw_rect.y = 0; ++ } ++ ++ this->hidden->sw_rect.x = 0; ++ this->hidden->sw_rect.y = 0; ++ this->hidden->sw_rect.w = width; ++ this->hidden->sw_rect.h = height; ++ ++ current->pitch = (width > 512) ? width * (bpp/8) : 512 * (bpp/8); ++ current->pixels = memalign(16, current->pitch * height); ++ ++ this->UpdateRects = PSP_GuUpdateRects; ++ } ++ ++ PSP_GuInit(this, current, bpp); ++ ++ /* We're done */ ++ return(current); ++} ++ ++static int PSP_AllocHWSurface(_THIS, SDL_Surface *surface) ++{ ++ int pitch; ++ ++ pitch = roundUpToPowerOfTwo(surface->pitch); ++ surface->pixels = vidmem_alloc(pitch * surface->h); ++ ++ if (!surface->pixels) ++ return -1; ++ ++ surface->pitch = pitch; ++ surface->flags |= SDL_HWSURFACE; ++ surface->hwdata = (void*)1; /* Hack to make SDL realize it's a HWSURFACE when freeing */ ++ return 0; ++} ++static void PSP_FreeHWSurface(_THIS, SDL_Surface *surface) ++{ ++ vidmem_free(surface->pixels); ++ surface->pixels = NULL; ++ return; ++} ++ ++/* We need to wait for vertical retrace on page flipped displays */ ++static int PSP_LockHWSurface(_THIS, SDL_Surface *surface) ++{ ++ return(0); ++} ++ ++static void PSP_UnlockHWSurface(_THIS, SDL_Surface *surface) ++{ ++ /* Flush video RAM */ ++ sceKernelDcacheWritebackAll(); ++ ++ return; ++} ++ ++/* Show the draw buffer as the display buffer, and setup the next draw buffer. */ ++static int PSP_FlipHWSurface(_THIS, SDL_Surface *surface) ++{ ++ void *new_pixels; ++ ++ sceKernelDcacheWritebackAll(); ++ if (surface->format->BitsPerPixel == 8) { ++ /* blit the shadow surface */ ++ PSP_GuStretchBlit(surface, (SDL_Rect *)&RECT_480x272, (SDL_Rect *)&RECT_480x272); ++ sceGuSync(0, 0); ++ } else { ++ this->hidden->frame ^= 1; ++ new_pixels = (void *) ((Uint32) this->hidden->vram_base + ++ (this->hidden->frame_offset * this->hidden->frame)); ++ surface->pixels = new_pixels; ++ } ++ sceGuSwapBuffers(); ++ ++ return 0; ++} ++ ++static void PSP_UpdateRects(_THIS, int numrects, SDL_Rect *rects) ++{ ++} ++ ++static int PSP_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) ++{ ++ src->flags |= SDL_HWACCEL; ++ src->map->hw_blit = HWAccelBlit; ++ return 1; ++} ++ ++static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, ++ SDL_Surface *dst, SDL_Rect *dstrect) ++{ ++ sceKernelDcacheWritebackAll(); ++ ++ /* when rendering to the screen from a 16 byte aligned address, ++ use GuStretchBlit without stretching */ ++ if ((dst == current_video->screen) && IS_HWSURFACE(src->flags)) { ++ ++ PSP_GuStretchBlit(src, srcrect, dstrect); ++ ++ } else { ++ ++ sceGuStart(GU_DIRECT,list); ++ ++ sceGuCopyImage(current_video->hidden->psm, ++ srcrect->x, srcrect->y, srcrect->w, srcrect->h, ++ src->pitch / src->format->BytesPerPixel, src->pixels, ++ dstrect->x, dstrect->y, dst->pitch / dst->format->BytesPerPixel, ++ dst->pixels); ++ ++ sceGuFinish(); ++ ++ } ++ ++ sceGuSync(0, 0); ++ ++ return 0; ++} ++ ++/** ++ * update screen from 16 byte aligned src surface ++ */ ++static int PSP_GuStretchBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Rect *dstrect) ++{ ++ unsigned short old_slice = 0; /* set when we load 2nd tex */ ++ unsigned int slice, num_slices, width, height, tbw, off_x, off_bytes; ++ struct texVertex *vertices; ++ void *pixels; ++ ++ off_bytes = (int)(src->pixels + srcrect->x * src->format->BytesPerPixel) & 0xf; ++ off_x = off_bytes / src->format->BytesPerPixel; ++ width = roundUpToPowerOfTwo(srcrect->w + off_bytes); ++ height = roundUpToPowerOfTwo(srcrect->h); ++ tbw = src->pitch / src->format->BytesPerPixel; ++ ++ /* Align the texture prior to srcrect->x */ ++ pixels = src->pixels + (srcrect->x - off_x) * src->format->BytesPerPixel + ++ src->pitch * srcrect->y; ++ num_slices = (srcrect->w + (PSP_SLICE_SIZE - 1)) / PSP_SLICE_SIZE; ++ ++ /* GE doesn't appreciate textures wider than 512 */ ++ if (width > 512) ++ width = 512; ++ ++ sceGuStart(GU_DIRECT,list); ++ sceGuEnable(GU_TEXTURE_2D); ++ sceGuTexMode(current_video->hidden->tpsm,0,0,0); ++ sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB); ++ sceGuTexFilter(GU_LINEAR, GU_LINEAR); ++ sceGuTexImage(0, width, height, tbw, pixels); ++ sceGuTexSync(); ++ ++ for (slice = 0; slice < num_slices; slice++) { ++ ++ vertices = (struct texVertex*)sceGuGetMemory(2 * sizeof(struct texVertex)); ++ ++ if ((slice * PSP_SLICE_SIZE) < width) { ++ vertices[0].u = slice * PSP_SLICE_SIZE + off_x; ++ } else { ++ if (!old_slice) { ++ /* load another texture (src width > 512) */ ++ pixels += width * src->format->BytesPerPixel; ++ sceGuTexImage(0, roundUpToPowerOfTwo(srcrect->w - width), ++ height, tbw, pixels); ++ sceGuTexSync(); ++ old_slice = slice; ++ } ++ vertices[0].u = (slice - old_slice) * PSP_SLICE_SIZE + off_x; ++ } ++ vertices[1].u = vertices[0].u + PSP_SLICE_SIZE; ++ if (vertices[1].u > (off_x + srcrect->w)) ++ vertices[1].u = off_x + srcrect->w; ++ ++ vertices[0].v = 0; ++ vertices[1].v = vertices[0].v + srcrect->h; ++ ++ vertices[0].x = dstrect->x + slice * PSP_SLICE_SIZE * dstrect->w / srcrect->w; ++ vertices[1].x = vertices[0].x + PSP_SLICE_SIZE * dstrect->w / srcrect->w; ++ if (vertices[1].x > (dstrect->x + dstrect->w)) ++ vertices[1].x = dstrect->x + dstrect->w; ++ ++ vertices[0].y = dstrect->y; ++ vertices[1].y = vertices[0].y + dstrect->h; ++ ++ vertices[0].z = 0; ++ vertices[1].z = 0; ++ ++ sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D, ++ 2,0,vertices); ++ } ++ ++ sceGuFinish(); ++ ++ return 0; ++} ++ ++static int PSP_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) ++{ ++ struct rectVertex *vertices; ++ void *gu_offset; ++ ++ gu_offset = (void *)((int)current_video->screen->pixels & 0x00ffffff); ++ ++ sceGuStart(GU_DIRECT,list); ++ ++ vertices = sceGuGetMemory(2 * sizeof(struct rectVertex)); ++ ++ vertices[0].x = rect->x; ++ vertices[1].x = rect->x + rect->w; ++ vertices[0].y = rect->y; ++ vertices[1].y = rect->y + rect->h; ++ ++ sceGuDrawBuffer(psm_value(dst->format->BitsPerPixel), ++ (void *)((int)dst->pixels & 0x00ffffff), ++ dst->pitch / dst->format->BytesPerPixel); ++ ++ sceGuColor(color); ++ sceGuDrawArray(GU_SPRITES,GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices); ++ ++ sceGuDrawBuffer(this->hidden->psm, gu_offset, PSP_LINE_SIZE); ++ ++ sceGuFinish(); ++ sceGuSync(0, 0); ++ ++ return 0; ++} ++ ++/** ++ * Update the screen from SDL_SWSURFACE (and scale). ++ */ ++static void PSP_GuUpdateRects(_THIS, int numrects, SDL_Rect *rects) ++{ ++ SDL_Surface *src = SDL_VideoSurface; ++ ++ sceKernelDcacheWritebackAll(); ++ ++ /* if the screen dimensions are unusual, do a single update */ ++ if ((src->w != 480) || (src->h != 272)) { ++ ++ PSP_GuStretchBlit(src, &this->hidden->sw_rect, &this->hidden->hw_rect); ++ ++ } else { ++ /* update the specified rects */ ++ while(numrects--) { ++ PSP_GuStretchBlit(src, rects, rects); ++ rects++; ++ } ++ } ++ ++ sceGuSync(0, 0); ++} ++ ++int PSP_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) ++{ ++ int i, j, ret = 1; ++ unsigned int *palette; ++ ++ if (ncolors > 256) { ++ ncolors = 256; ++ ret = 0; ++ } ++ ++ if (this->hidden->gu_palette == NULL) { ++ this->hidden->gu_palette = memalign(16, 4 * 256); ++ this->hidden->tpsm = GU_PSM_T8; ++ } ++ ++ palette = this->hidden->gu_palette; ++ ++ for (i=firstcolor, j=0; j < ncolors; i++, j++) { ++ palette[i] = (colors[j].b << 16) | (colors[j].g << 8) | (colors[j].r); ++ } ++ ++ sceKernelDcacheWritebackAll(); ++ sceGuStart(GU_DIRECT, list); ++ sceGuClutLoad(32, this->hidden->gu_palette); ++ sceGuFinish(); ++ sceGuSync(0,0); ++ ++ return ret; ++} ++ ++/* Note: If we are terminated, this could be called in the middle of ++ another SDL video routine -- notably UpdateRects. ++*/ ++void PSP_VideoQuit(_THIS) ++{ ++ if (this->hidden->gu_palette != NULL) { ++ free(this->hidden->gu_palette); ++ this->hidden->gu_palette = NULL; ++ } ++ ++ sceGuTerm(); ++ ++ PSP_EventQuit(this); ++ ++ vidmem_free(this->hidden->vram_base); ++ ++ if (this->screen->flags & SDL_DOUBLEBUF) ++ vidmem_free(this->hidden->vram_base + this->hidden->frame_offset); ++ ++ return; ++} ++ ++/* vim: ts=4 sw=4 ++ */ +diff -burN SDL-1.2.15/src/video/psp/SDL_pspvideo.h SDL-1.2.15-PSP/src/video/psp/SDL_pspvideo.h +--- SDL-1.2.15/src/video/psp/SDL_pspvideo.h 1970-01-01 01:00:00.000000000 +0100 ++++ SDL-1.2.15-PSP/src/video/psp/SDL_pspvideo.h 2012-06-06 12:55:07.482588936 +0200 +@@ -0,0 +1,73 @@ ++/* ++ SDL - Simple DirectMedia Layer ++ Copyright (C) 1997-2004 Sam Lantinga ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, write to the Free ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ Sam Lantinga ++ slouken@libsdl.org ++*/ ++ ++/* ++ PSP port contributed by: ++ Marcus R. Brown <mrbrown@ocgnet.org> ++ Jim Paris <jim@jtan.com> ++*/ ++ ++#ifdef SAVE_RCSID ++static char rcsid = ++ "@(#) $Id: SDL_nullvideo.h,v 1.4 2004/01/04 16:49:24 slouken Exp $"; ++#endif ++ ++#ifndef _SDL_pspvideo_h ++#define _SDL_pspvideo_h ++ ++#include "SDL_mouse.h" ++#include "../SDL_sysvideo.h" ++#include "SDL_mutex.h" ++ ++#include <psptypes.h> ++#include <pspge.h> ++#include <pspkernel.h> ++#include <psputils.h> ++#include <pspdisplay.h> ++#include <pspgu.h> ++ ++/* Hidden "this" pointer for the video functions */ ++#define _THIS SDL_VideoDevice *this ++ ++ ++/* Private display data */ ++ ++struct SDL_PrivateVideoData { ++ void *vram_base; ++ /* Current display's pixel format. */ ++ int pixel_format; ++ /* The current draw frame for double-buffered displays. */ ++ int frame; ++ /* Byte offset of the start of the second frame. */ ++ unsigned int frame_offset; ++ /* Screen format */ ++ int psm; ++ /* Texture format */ ++ int tpsm; ++ /* Pointer to the CLUT. */ ++ void *gu_palette; ++ /* Dimensions for stretched blit */ ++ SDL_Rect hw_rect; ++ SDL_Rect sw_rect; ++}; ++ ++#endif /* _SDL_pspvideo_h */ +diff -burN SDL-1.2.15/src/video/SDL_sysvideo.h SDL-1.2.15-PSP/src/video/SDL_sysvideo.h +--- SDL-1.2.15/src/video/SDL_sysvideo.h 2012-01-19 07:30:06.000000000 +0100 ++++ SDL-1.2.15-PSP/src/video/SDL_sysvideo.h 2012-06-06 12:55:07.482588936 +0200 +@@ -413,6 +413,9 @@ + #if SDL_VIDEO_DRIVER_DUMMY + extern VideoBootStrap DUMMY_bootstrap; + #endif ++#if SDL_VIDEO_DRIVER_PSP ++extern VideoBootStrap PSP_bootstrap; ++#endif + + /* This is the current video device */ + extern SDL_VideoDevice *current_video; +diff -burN SDL-1.2.15/src/video/SDL_video.c SDL-1.2.15-PSP/src/video/SDL_video.c +--- SDL-1.2.15/src/video/SDL_video.c 2012-01-19 07:30:06.000000000 +0100 ++++ SDL-1.2.15-PSP/src/video/SDL_video.c 2012-06-06 12:55:07.484588936 +0200 +@@ -129,6 +129,9 @@ + #if SDL_VIDEO_DRIVER_DUMMY + &DUMMY_bootstrap, + #endif ++#if SDL_VIDEO_DRIVER_PSP ++ &PSP_bootstrap, ++#endif + NULL + }; + +diff -burN SDL-1.2.15/test/configure.in SDL-1.2.15-PSP/test/configure.in +--- SDL-1.2.15/test/configure.in 2012-01-19 07:30:06.000000000 +0100 ++++ SDL-1.2.15-PSP/test/configure.in 2012-06-06 12:55:07.485588936 +0200 +@@ -13,6 +13,28 @@ + + AC_C_CONST + ++dnl Check for a valid PSPSDK installation ++CheckPSPSDK() ++{ ++ AC_CHECK_PROG(psp_config, psp-config, psp-config, no) ++ if test x$psp_config = xno; then ++ AC_MSG_ERROR(Couldn't locate psp-config.) ++ fi ++ ++ AC_MSG_CHECKING(for PSPSDK) ++ pspsdk_path=`$psp_config --pspsdk-path` ++ psp_prefix=`$psp_config --psp-prefix` ++ if test ! -d $pspsdk_path -o -z $pspsdk_path; then ++ AC_MSG_RESULT(not found) ++ AC_MSG_ERROR(Couldn't locate PSPSDK.) ++ fi ++ AC_MSG_RESULT($pspsdk_path) ++ ++ # Compile SDL with -G0 to disable the $gp register. ++ CFLAGS="$CFLAGS -G0 -I\"${pspsdk_path}/include\" -I\"${psp_prefix}/include\"" ++ BUILD_PREFIX="psp-" ++} ++ + dnl Figure out which math library to use + case "$host" in + *-*-cygwin* | *-*-mingw32*) +@@ -50,6 +72,10 @@ + SYS_GL_LIBS="-lOSMesa" + fi + ;; ++ *-psp-*) ++ ARCH=psp ++ CheckPSPSDK ++ ;; + *) + EXE="" + MATHLIB="-lm" +diff -burN SDL-1.2.15/test/testsprite.c SDL-1.2.15-PSP/test/testsprite.c +--- SDL-1.2.15/test/testsprite.c 2012-01-19 07:30:06.000000000 +0100 ++++ SDL-1.2.15-PSP/test/testsprite.c 2012-06-06 12:55:07.486588936 +0200 +@@ -12,6 +12,13 @@ + #define NUM_SPRITES 100 + #define MAX_SPEED 1 + ++#ifdef PSP ++#include <pspdebug.h> ++ ++#define fprintf(x, args...) pspDebugScreenPrintf(args) ++#define printf(args...) pspDebugScreenPrintf(args) ++#endif /* PSP */ ++ + SDL_Surface *sprite; + int numsprites; + SDL_Rect *sprite_rects; |