aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/events/psp2sdl/psp2sdl-events.cpp323
-rw-r--r--backends/events/psp2sdl/psp2sdl-events.h39
-rw-r--r--backends/fs/posix/posix-fs.cpp7
-rw-r--r--backends/fs/psp2/psp2-dirent.cpp241
-rw-r--r--backends/fs/psp2/psp2-dirent.h59
-rw-r--r--backends/fs/psp2/psp2-fs-factory.cpp45
-rw-r--r--backends/fs/psp2/psp2-fs-factory.h41
-rw-r--r--backends/graphics/graphics.h7
-rw-r--r--backends/graphics/psp2sdl/psp2sdl-graphics.cpp522
-rw-r--r--backends/graphics/psp2sdl/psp2sdl-graphics.h55
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.cpp69
-rw-r--r--backends/graphics/surfacesdl/surfacesdl-graphics.h9
-rw-r--r--backends/mixer/sdl/sdl-mixer.cpp2
-rw-r--r--backends/modular-backend.cpp12
-rw-r--r--backends/modular-backend.h3
-rw-r--r--backends/module.mk9
-rw-r--r--backends/platform/sdl/module.mk7
-rw-r--r--backends/platform/sdl/posix/posix-main.cpp2
-rw-r--r--backends/platform/sdl/psp2/psp2-main.cpp66
-rw-r--r--backends/platform/sdl/psp2/psp2.cpp143
-rw-r--r--backends/platform/sdl/psp2/psp2.h52
-rw-r--r--backends/platform/sdl/psp2/psp2.mk26
22 files changed, 1730 insertions, 9 deletions
diff --git a/backends/events/psp2sdl/psp2sdl-events.cpp b/backends/events/psp2sdl/psp2sdl-events.cpp
new file mode 100644
index 0000000000..e58e49d9a8
--- /dev/null
+++ b/backends/events/psp2sdl/psp2sdl-events.cpp
@@ -0,0 +1,323 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#if defined(PSP2)
+
+#include <psp2/kernel/processmgr.h>
+#include "backends/platform/sdl/psp2/psp2.h"
+#include "backends/events/psp2sdl/psp2sdl-events.h"
+#include "backends/platform/sdl/sdl.h"
+#include "engines/engine.h"
+
+#include "common/util.h"
+#include "common/events.h"
+#include "common/config-manager.h"
+
+#include "math.h"
+
+#define JOY_DEADZONE 2000
+#define JOY_ANALOG
+#define JOY_XAXIS 0
+#define JOY_YAXIS 1
+#define JOY_XAXISR 2
+#define JOY_YAXISR 3
+
+enum {
+ BTN_LEFT = 7,
+ BTN_DOWN = 6,
+ BTN_RIGHT = 9,
+ BTN_UP = 8,
+
+ BTN_START = 11,
+ BTN_SELECT = 10,
+
+ BTN_SQUARE = 3,
+ BTN_CROSS = 2,
+ BTN_CIRCLE = 1,
+ BTN_TRIANGLE = 0,
+
+ BTN_R1 = 5,
+ BTN_L1 = 4
+};
+
+bool PSP2EventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
+
+ event.kbd.flags = 0;
+
+ switch (ev.jbutton.button) {
+// Dpad
+ case BTN_LEFT: // Left (+R_trigger: Up+Left)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_KP4;
+ event.kbd.ascii = mapKey(SDLK_KP4, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_KP7;
+ event.kbd.ascii = mapKey(SDLK_KP7, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+ case BTN_RIGHT: // Right (+R_trigger: Down+Right)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_KP6;
+ event.kbd.ascii = mapKey(SDLK_KP6, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_KP3;
+ event.kbd.ascii = mapKey(SDLK_KP3, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+ case BTN_UP: // Up (+R_trigger: Up+Right)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_KP8;
+ event.kbd.ascii = mapKey(SDLK_KP8, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_KP9;
+ event.kbd.ascii = mapKey(SDLK_KP9, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+ case BTN_DOWN: // Down (+R_trigger: Down+Left)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_KP2;
+ event.kbd.ascii = mapKey(SDLK_KP2, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_KP1;
+ event.kbd.ascii = mapKey(SDLK_KP1, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+// Buttons
+ case BTN_CROSS: // Left mouse button
+ event.type = Common::EVENT_LBUTTONDOWN;
+ processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ break;
+ case BTN_CIRCLE: // Right mouse button
+ event.type = Common::EVENT_RBUTTONDOWN;
+ processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ break;
+ case BTN_TRIANGLE: // Escape (+R_trigger: Return)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_ESCAPE;
+ event.kbd.ascii = mapKey(SDLK_ESCAPE, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_RETURN;
+ event.kbd.ascii = mapKey(SDLK_RETURN, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+ case BTN_SQUARE: // Period (+R_trigger: Space)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_PERIOD;
+ event.kbd.ascii = mapKey(SDLK_PERIOD, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_SPACE;
+ event.kbd.ascii = mapKey(SDLK_SPACE, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+ case BTN_L1: // Game menu
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_F5;
+ event.kbd.ascii = mapKey(SDLK_F5, (SDLMod) ev.key.keysym.mod, 0);
+ break;
+ case BTN_R1: // Modifier + Shift
+ _km.modifier=true; // slow mouse
+ event.type = Common::EVENT_KEYDOWN;
+ event.kbd.keycode = Common::KEYCODE_INVALID;
+ event.kbd.ascii = 0;
+ event.kbd.flags = Common::KBD_SHIFT;
+ break;
+ case BTN_START: // ScummVM in game menu
+ event.type = Common::EVENT_MAINMENU;
+ break;
+ case BTN_SELECT: // Virtual keyboard (+R_trigger: Predictive Input Dialog)
+ if (!_km.modifier) {
+#ifdef ENABLE_VKEYBD
+ event.type = Common::EVENT_VIRTUAL_KEYBOARD;
+#endif
+ } else {
+ event.type = Common::EVENT_PREDICTIVE_DIALOG;
+ }
+ break;
+ }
+ return true;
+}
+
+bool PSP2EventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
+
+ event.kbd.flags = 0;
+
+ switch (ev.jbutton.button) {
+// Dpad
+ case BTN_LEFT: // Left (+R_trigger: Up+Left)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_KP4;
+ event.kbd.ascii = mapKey(SDLK_KP4, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_KP7;
+ event.kbd.ascii = mapKey(SDLK_KP7, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+ case BTN_RIGHT: // Right (+R_trigger: Down+Right)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_KP6;
+ event.kbd.ascii = mapKey(SDLK_KP6, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_KP3;
+ event.kbd.ascii = mapKey(SDLK_KP3, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+ case BTN_UP: // Up (+R_trigger: Up+Right)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_KP8;
+ event.kbd.ascii = mapKey(SDLK_KP8, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_KP9;
+ event.kbd.ascii = mapKey(SDLK_KP9, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+ case BTN_DOWN: // Down (+R_trigger: Down+Left)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_KP2;
+ event.kbd.ascii = mapKey(SDLK_KP2, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_KP1;
+ event.kbd.ascii = mapKey(SDLK_KP1, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+// Buttons
+ case BTN_CROSS: // Left mouse button
+ event.type = Common::EVENT_LBUTTONUP;
+ processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ break;
+ case BTN_CIRCLE: // Right mouse button
+ event.type = Common::EVENT_RBUTTONUP;
+ processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ break;
+ case BTN_TRIANGLE: // Escape (+R_trigger: Return)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_ESCAPE;
+ event.kbd.ascii = mapKey(SDLK_ESCAPE, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_RETURN;
+ event.kbd.ascii = mapKey(SDLK_RETURN, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+ case BTN_SQUARE: // Period (+R_trigger: Space)
+ if (!_km.modifier) {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_PERIOD;
+ event.kbd.ascii = mapKey(SDLK_PERIOD, (SDLMod) ev.key.keysym.mod, 0);
+ } else {
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_SPACE;
+ event.kbd.ascii = mapKey(SDLK_SPACE, (SDLMod) ev.key.keysym.mod, 0);
+ }
+ break;
+ case BTN_L1: // Game menu
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_F5;
+ event.kbd.ascii = mapKey(SDLK_F5, (SDLMod) ev.key.keysym.mod, 0);
+ break;
+ case BTN_R1: // Modifier + SHIFT Key
+ _km.modifier = false; // slow mouse
+ event.type = Common::EVENT_KEYUP;
+ event.kbd.keycode = Common::KEYCODE_INVALID;
+ event.kbd.ascii = 0;
+ event.kbd.flags = 0;
+ break;
+ case BTN_START: // ScummVM in game menu
+ // Handled in key down
+ break;
+ case BTN_SELECT: // Virtual keyboard (+R_trigger: Predictive Input Dialog)
+ // Handled in key down
+ break;
+ }
+ return true;
+}
+
+bool PSP2EventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
+
+ int axis = ev.jaxis.value;
+
+ // conversion factor between keyboard mouse and joy axis value
+ int vel_to_axis = (1500 / MULTIPLIER);
+
+ if (ev.jaxis.axis == JOY_XAXIS) {
+ _km.joy_x = axis;
+ } else if (ev.jaxis.axis == JOY_YAXIS) {
+ axis = -axis;
+ _km.joy_y = -axis;
+ }
+
+ // radial and scaled deadzone
+
+ float analogX = (float)_km.joy_x;
+ float analogY = (float)_km.joy_y;
+ float deadZone = (float)JOY_DEADZONE;
+ if (g_system->hasFeature(OSystem::kFeatureJoystickDeadzone))
+ deadZone = (float)ConfMan.getInt("joystick_deadzone") * 1000.0f;
+ float scalingFactor = 1.0f;
+ float magnitude = 0.0f;
+
+ magnitude = sqrt(analogX * analogX + analogY * analogY);
+
+ if (magnitude >= deadZone) {
+ _km.x_down_count = 0;
+ _km.y_down_count = 0;
+ scalingFactor = 1.0f / magnitude * (magnitude - deadZone) / (32769.0f - deadZone);
+ _km.x_vel = (int16)(analogX * scalingFactor * 32768.0f / (float) vel_to_axis);
+ _km.y_vel = (int16)(analogY * scalingFactor * 32768.0f / (float) vel_to_axis);
+ } else {
+ _km.x_vel = 0;
+ _km.y_vel = 0;
+ }
+
+ return false;
+}
+
+void PSP2EventSource::preprocessEvents(SDL_Event *event) {
+
+ // prevent suspend (scummvm games contains a lot of cutscenes..)
+ sceKernelPowerTick(SCE_KERNEL_POWER_TICK_DISABLE_AUTO_SUSPEND);
+ sceKernelPowerTick(SCE_KERNEL_POWER_TICK_DISABLE_OLED_OFF);
+}
+
+#endif
diff --git a/backends/events/psp2sdl/psp2sdl-events.h b/backends/events/psp2sdl/psp2sdl-events.h
new file mode 100644
index 0000000000..001312e1d5
--- /dev/null
+++ b/backends/events/psp2sdl/psp2sdl-events.h
@@ -0,0 +1,39 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#if !defined(DISABLE_DEFAULT_EVENTMANAGER)
+#define BACKEND_EVENTS_PSP2_H
+
+#include "backends/events/sdl/sdl-events.h"
+
+/**
+ * SDL Events manager for the PSP2.
+ */
+class PSP2EventSource : public SdlEventSource {
+protected:
+ bool handleJoyButtonDown(SDL_Event &ev, Common::Event &event);
+ bool handleJoyButtonUp(SDL_Event &ev, Common::Event &event);
+ bool handleJoyAxisMotion(SDL_Event &ev, Common::Event &event);
+ void preprocessEvents(SDL_Event *event);
+};
+
+#endif /* BACKEND_EVENTS_PSP2_H */
diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp
index 4434bcba97..3f90fc1a19 100644
--- a/backends/fs/posix/posix-fs.cpp
+++ b/backends/fs/posix/posix-fs.cpp
@@ -20,7 +20,7 @@
*
*/
-#if defined(POSIX) || defined(PLAYSTATION3)
+#if defined(POSIX) || defined(PLAYSTATION3) || defined(PSP2)
// Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h.
// Also with clock() in sys/time.h in some Mac OS X SDKs.
@@ -36,7 +36,12 @@
#include <sys/param.h>
#include <sys/stat.h>
+#ifdef PSP2
+#include "backends/fs/psp2/psp2-dirent.h"
+#define mkdir sceIoMkdir
+#else
#include <dirent.h>
+#endif
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
diff --git a/backends/fs/psp2/psp2-dirent.cpp b/backends/fs/psp2/psp2-dirent.cpp
new file mode 100644
index 0000000000..aefd1a067d
--- /dev/null
+++ b/backends/fs/psp2/psp2-dirent.cpp
@@ -0,0 +1,241 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+
+Copyright (C) 2016, David "Davee" Morgan
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "psp2-dirent.h"
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+
+#include <psp2/types.h>
+#include <psp2/io/dirent.h>
+#include <psp2/kernel/threadmgr.h>
+
+#define SCE_ERRNO_MASK 0xFF
+
+
+struct DIR_ {
+ SceUID uid;
+ struct dirent dir;
+ int refcount;
+ char *dirname;
+ int index;
+};
+
+static inline void grab_dir(DIR *dirp) {
+ __sync_add_and_fetch(&dirp->refcount, 1);
+}
+
+static inline void drop_dir(DIR *dirp) {
+ if (__sync_add_and_fetch(&dirp->refcount, 1) == 0) {
+ free(dirp->dirname);
+ free(dirp);
+ }
+}
+
+static inline void release_drop_dir(DIR *dirp) {
+ if (__sync_add_and_fetch(&dirp->refcount, 2) == 0) {
+ free(dirp->dirname);
+ free(dirp);
+ }
+}
+
+static inline void atomic_exchange(int *obj, int desired) {
+ __sync_synchronize();
+ __sync_lock_test_and_set(obj, desired);
+}
+
+#ifdef F_closedir
+int closedir(DIR *dirp) {
+ if (!dirp) {
+ errno = EBADF;
+ return -1;
+ }
+
+ grab_dir(dirp);
+
+ int res = sceIoDclose(dirp->uid);
+
+ if (res < 0) {
+ errno = res & SCE_ERRNO_MASK;
+ drop_dir(dirp);
+ return -1;
+ }
+
+ release_drop_dir(dirp);
+
+ errno = 0;
+ return 0;
+}
+#endif
+
+#if F_opendir
+DIR *opendir(const char *dirname) {
+ SceUID uid = sceIoDopen(dirname);
+
+ if (uid < 0) {
+ errno = uid & SCE_ERRNO_MASK;
+ return NULL;
+ }
+
+ DIR *dirp = (DIR *)calloc(1, sizeof(DIR));
+
+ if (!dirp) {
+ sceIoDclose(uid);
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ dirp->refcount = 1;
+ dirp->uid = uid;
+ dirp->dirname = strdup(dirname);
+ dirp->index = 0;
+
+ errno = 0;
+ return dirp;
+}
+#endif
+
+#ifdef F_readdir
+struct dirent *readdir(DIR *dirp) {
+ if (!dirp) {
+ errno = EBADF;
+ return NULL;
+ }
+
+ grab_dir(dirp);
+
+ int res = sceIoDread(dirp->uid, (SceIoDirent *)&dirp->dir);
+
+ if (res < 0) {
+ errno = res & SCE_ERRNO_MASK;
+ drop_dir(dirp);
+ return NULL;
+ }
+
+ if (res == 0) {
+ errno = 0;
+ drop_dir(dirp);
+ return NULL;
+ }
+
+ __sync_add_and_fetch(&dirp->index, 1);
+
+ struct dirent *dir = &dirp->dir;
+ drop_dir(dirp);
+ return dir;
+}
+#endif
+#ifdef F_readdir_r
+int readdir_r(DIR *dirp, struct dirent *x, struct dirent **y) {
+ errno = ENOSYS;
+ return -1;
+}
+#endif
+
+#ifdef F_rewinddir
+void rewinddir(DIR *dirp) {
+ if (!dirp) {
+ errno = EBADF;
+ return;
+ }
+
+ grab_dir(dirp);
+
+ SceUID dirfd = sceIoDopen(dirp->dirname);
+
+ if (dirfd < 0) {
+ errno = dirfd & SCE_ERRNO_MASK;
+ drop_dir(dirp);
+ return;
+ }
+
+ sceIoDclose(dirp->uid);
+ atomic_exchange(&dirp->uid, dirfd);
+ atomic_exchange(&dirp->index, 0);
+
+ drop_dir(dirp);
+}
+#endif
+
+#ifdef F_seekdir
+void seekdir(DIR *dirp, long int index) {
+ if (!dirp) {
+ errno = EBADF;
+ return;
+ }
+
+ grab_dir(dirp);
+
+ if (index < dirp->index)
+ rewinddir(dirp);
+
+ if (index < dirp->index) {
+ drop_dir(dirp);
+ return;
+ }
+
+ while (index != dirp->index) {
+ if (!readdir(dirp)) {
+ errno = ENOENT;
+ drop_dir(dirp);
+ return;
+ }
+ }
+
+ drop_dir(dirp);
+}
+#endif
+
+#ifdef F_telldir
+long int telldir(DIR *dirp) {
+ if (!dirp) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return dirp->index;
+}
+#endif
diff --git a/backends/fs/psp2/psp2-dirent.h b/backends/fs/psp2/psp2-dirent.h
new file mode 100644
index 0000000000..0e56976404
--- /dev/null
+++ b/backends/fs/psp2/psp2-dirent.h
@@ -0,0 +1,59 @@
+/*
+
+Copyright (C) 2016, David "Davee" Morgan
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef _PSP2_DIRENT_H_
+#define _PSP2_DIRENT_H_
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <psp2/io/dirent.h>
+
+#define F_opendir 1
+#define F_readdir 1
+#define F_closedir 1
+
+struct dirent
+{
+ /** File status. */
+ SceIoStat d_stat;
+ /** File name. */
+ char d_name[256];
+ /** Device-specific data. */
+ void *d_private;
+ int dummy;
+};
+
+struct DIR_;
+typedef struct DIR_ DIR;
+
+int closedir(DIR *);
+DIR *opendir(const char *);
+struct dirent *readdir(DIR *);
+int readdir_r(DIR *, struct dirent *, struct dirent **);
+void rewinddir(DIR *);
+void seekdir(DIR *, long int);
+long int telldir(DIR *);
+
+#endif /* _PSP2_DIRENT_H_ */
diff --git a/backends/fs/psp2/psp2-fs-factory.cpp b/backends/fs/psp2/psp2-fs-factory.cpp
new file mode 100644
index 0000000000..68d91122b8
--- /dev/null
+++ b/backends/fs/psp2/psp2-fs-factory.cpp
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h.
+// Also with clock() in sys/time.h in some Mac OS X SDKs.
+#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
+#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
+#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir
+#define FORBIDDEN_SYMBOL_EXCEPTION_exit //Needed for IRIX's unistd.h
+
+#include "backends/fs/posix/posix-fs-factory.h"
+#include "backends/fs/posix/posix-fs.h"
+#include "backends/fs/psp2/psp2-fs-factory.h"
+
+AbstractFSNode *PSP2FilesystemFactory::makeRootFileNode() const {
+ return new POSIXFilesystemNode("ux0:");
+}
+
+AbstractFSNode *PSP2FilesystemFactory::makeCurrentDirectoryFileNode() const {
+ return makeRootFileNode();
+}
+
+AbstractFSNode *PSP2FilesystemFactory::makeFileNodePath(const Common::String &path) const {
+ assert(!path.empty());
+ return new POSIXFilesystemNode(path);
+}
diff --git a/backends/fs/psp2/psp2-fs-factory.h b/backends/fs/psp2/psp2-fs-factory.h
new file mode 100644
index 0000000000..3429b815ae
--- /dev/null
+++ b/backends/fs/psp2/psp2-fs-factory.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef PSP2_FILESYSTEM_FACTORY_H
+#define PSP2_FILESYSTEM_FACTORY_H
+
+#include "backends/fs/posix/posix-fs-factory.h"
+
+/**
+ * Creates PSP2FilesystemFactory objects.
+ *
+ * Parts of this class are documented in the base interface class, FilesystemFactory.
+ */
+
+class PSP2FilesystemFactory : public FilesystemFactory {
+protected:
+ virtual AbstractFSNode *makeRootFileNode() const;
+ virtual AbstractFSNode *makeCurrentDirectoryFileNode() const;
+ virtual AbstractFSNode *makeFileNodePath(const Common::String &path) const;
+};
+
+#endif /*PSP2_FILESYSTEM_FACTORY_H*/
diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index db8b6a920b..f6b0058fac 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -46,6 +46,13 @@ public:
virtual bool setGraphicsMode(int mode) = 0;
virtual void resetGraphicsScale() = 0;
virtual int getGraphicsMode() const = 0;
+ virtual const OSystem::GraphicsMode *getSupportedShaders() const {
+ static const OSystem::GraphicsMode no_shader[2] = {{"NONE", "Normal (no shader)", 0}, {0, 0, 0}};
+ return no_shader;
+ };
+ virtual bool setShader(int id) { return false; }
+ virtual int getShader() { return 0; }
+
#ifdef USE_RGB_COLOR
virtual Graphics::PixelFormat getScreenFormat() const = 0;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const = 0;
diff --git a/backends/graphics/psp2sdl/psp2sdl-graphics.cpp b/backends/graphics/psp2sdl/psp2sdl-graphics.cpp
new file mode 100644
index 0000000000..fa2adc85e4
--- /dev/null
+++ b/backends/graphics/psp2sdl/psp2sdl-graphics.cpp
@@ -0,0 +1,522 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+#include "common/scummsys.h"
+
+#if defined(SDL_BACKEND)
+
+#include "backends/graphics/psp2sdl/psp2sdl-graphics.h"
+#include "backends/events/sdl/sdl-events.h"
+#include "backends/platform/sdl/sdl.h"
+#include "common/config-manager.h"
+#include "common/mutex.h"
+#include "common/textconsole.h"
+#include "common/translation.h"
+#include "common/util.h"
+#include "common/frac.h"
+#ifdef USE_RGB_COLOR
+#include "common/list.h"
+#endif
+#include "graphics/font.h"
+#include "graphics/fontman.h"
+#include "graphics/scaler.h"
+#include "graphics/scaler/aspect.h"
+#include "graphics/surface.h"
+#include "gui/EventRecorder.h"
+
+#include <vita2d_fbo.h>
+#include <lcd3x_v.h>
+#include <lcd3x_f.h>
+#include <texture_v.h>
+#include <texture_f.h>
+#include <advanced_aa_v.h>
+#include <advanced_aa_f.h>
+#include <scale2x_f.h>
+#include <scale2x_v.h>
+#include <sharp_bilinear_f.h>
+#include <sharp_bilinear_v.h>
+#include <sharp_bilinear_simple_f.h>
+#include <sharp_bilinear_simple_v.h>
+
+#define GFX_SHADER_NONE 0
+#define GFX_SHADER_LCD3X 1
+#define GFX_SHADER_SHARP 2
+#define GFX_SHADER_SHARP_SCAN 3
+#define GFX_SHADER_AAA 4
+#define GFX_SHADER_SCALE2X 5
+
+static const OSystem::GraphicsMode s_supportedShadersPSP2[] = {
+ {"NONE", "Normal (no shader)", GFX_SHADER_NONE},
+ {"LCD", "LCD", GFX_SHADER_LCD3X},
+ {"Sharp", "Sharp", GFX_SHADER_SHARP},
+ {"Scan", "Scan", GFX_SHADER_SHARP_SCAN},
+ {"AAA", "Super2xSAI", GFX_SHADER_AAA},
+ {"Scale", "Scale", GFX_SHADER_SCALE2X},
+ {0, 0, 0}
+};
+
+PSP2SdlGraphicsManager::PSP2SdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window)
+ :
+ SurfaceSdlGraphicsManager(sdlEventSource, window),
+ _vitatex_hwscreen(nullptr),
+ _sdlpixels_hwscreen(nullptr) {
+
+ // do aspect ratio correction in hardware on the Vita
+ if (_videoMode.aspectRatioCorrection == true) {
+ _hardwareAspectRatioCorrection = true;
+ } else {
+ _hardwareAspectRatioCorrection = false;
+ }
+ _videoMode.aspectRatioCorrection = false;
+
+ if (g_system->hasFeature(OSystem::kFeatureShader)) {
+ // shader number 0 is the entry NONE (no shader)
+ const OSystem::GraphicsMode *p = s_supportedShadersPSP2;
+ _numShaders = 0;
+ while (p->name) {
+ _numShaders++;
+ p++;
+ }
+ _currentShader = ConfMan.getInt("shader");
+ if (_currentShader < 0 || _currentShader >= _numShaders) {
+ _currentShader = 0;
+ }
+ } else {
+ _numShaders = 1;
+ _currentShader = 0;
+ }
+
+ _shaders[0] = NULL;
+}
+
+PSP2SdlGraphicsManager::~PSP2SdlGraphicsManager() {
+ if (_vitatex_hwscreen) {
+ vita2d_free_texture(_vitatex_hwscreen);
+ for (int i = 0; i < 6; i++) {
+ vita2d_free_shader(_shaders[i]);
+ _shaders[i] = NULL;
+ }
+ _vitatex_hwscreen = NULL;
+ }
+ if (_hwscreen) {
+ _hwscreen->pixels = _sdlpixels_hwscreen;
+ }
+ _sdlpixels_hwscreen = nullptr;
+}
+
+OSystem::TransactionError PSP2SdlGraphicsManager::endGFXTransaction() {
+ OSystem::TransactionError returnValue = SurfaceSdlGraphicsManager::endGFXTransaction();
+
+ // force update of filtering on Vita
+ PSP2_UpdateFiltering();
+
+ return returnValue;
+}
+
+void PSP2SdlGraphicsManager::setGraphicsModeIntern() {
+ SurfaceSdlGraphicsManager::setGraphicsModeIntern();
+ PSP2_UpdateFiltering();
+}
+
+void PSP2SdlGraphicsManager::PSP2_UpdateFiltering() {
+ if (_vitatex_hwscreen) {
+ if (_videoMode.filtering) {
+ vita2d_texture_set_filters(_vitatex_hwscreen, SCE_GXM_TEXTURE_FILTER_LINEAR, SCE_GXM_TEXTURE_FILTER_LINEAR);
+ } else {
+ vita2d_texture_set_filters(_vitatex_hwscreen, SCE_GXM_TEXTURE_FILTER_POINT, SCE_GXM_TEXTURE_FILTER_POINT);
+ }
+ }
+}
+
+const OSystem::GraphicsMode *PSP2SdlGraphicsManager::getSupportedShaders() const {
+ return s_supportedShadersPSP2;
+}
+
+void PSP2SdlGraphicsManager::unloadGFXMode() {
+ if (_screen) {
+ SDL_FreeSurface(_screen);
+ _screen = NULL;
+ }
+
+ deinitializeRenderer();
+
+ if (_hwscreen) {
+ if (_vitatex_hwscreen) {
+ vita2d_free_texture(_vitatex_hwscreen);
+ for (int i = 0; i < 6; i++) {
+ vita2d_free_shader(_shaders[i]);
+ _shaders[i] = NULL;
+ }
+ _vitatex_hwscreen = NULL;
+ }
+ _hwscreen->pixels = _sdlpixels_hwscreen;
+ }
+ SurfaceSdlGraphicsManager::unloadGFXMode();
+}
+
+bool PSP2SdlGraphicsManager::hotswapGFXMode() {
+ if (!_screen)
+ return false;
+
+ // Release the HW screen surface
+ if (_hwscreen) {
+ if (_vitatex_hwscreen) {
+ vita2d_free_texture(_vitatex_hwscreen);
+ for (int i = 0; i < 6; i++) {
+ vita2d_free_shader(_shaders[i]);
+ _shaders[i] = NULL;
+ }
+ _vitatex_hwscreen = NULL;
+ }
+ _hwscreen->pixels = _sdlpixels_hwscreen;
+ }
+ return SurfaceSdlGraphicsManager::hotswapGFXMode();
+}
+
+void PSP2SdlGraphicsManager::updateShader() {
+// shader init code goes here
+// currently only used on Vita port
+// the user-selected shaderID should be obtained via ConfMan.getInt("shader")
+// and the corresponding shader should then be activated here
+// this way the user can combine any software scaling (scalers)
+// with any hardware shading (shaders). The shaders could provide
+// scanline masks, overlays, but could also serve for
+// hardware-based up-scaling (sharp-bilinear-simple, etc.)
+ if (_vitatex_hwscreen) {
+ if (_shaders[0] == NULL) {
+ // load shaders
+ _shaders[GFX_SHADER_NONE] = vita2d_create_shader((const SceGxmProgram *)texture_v, (const SceGxmProgram *)texture_f);
+ _shaders[GFX_SHADER_LCD3X] = vita2d_create_shader((const SceGxmProgram *)lcd3x_v, (const SceGxmProgram *)lcd3x_f);
+ _shaders[GFX_SHADER_SHARP] = vita2d_create_shader((const SceGxmProgram *)sharp_bilinear_simple_v, (const SceGxmProgram *)sharp_bilinear_simple_f);
+ _shaders[GFX_SHADER_SHARP_SCAN] = vita2d_create_shader((const SceGxmProgram *)sharp_bilinear_v, (const SceGxmProgram *)sharp_bilinear_f);
+ _shaders[GFX_SHADER_AAA] = vita2d_create_shader((const SceGxmProgram *)advanced_aa_v, (const SceGxmProgram *)advanced_aa_f);
+ _shaders[GFX_SHADER_SCALE2X] = vita2d_create_shader((const SceGxmProgram *)scale2x_v, (const SceGxmProgram *)scale2x_f);
+ }
+ if (_currentShader >= 0 && _currentShader < _numShaders) {
+ vita2d_texture_set_program(_shaders[_currentShader]->vertexProgram, _shaders[_currentShader]->fragmentProgram);
+ vita2d_texture_set_wvp(_shaders[_currentShader]->wvpParam);
+ vita2d_texture_set_vertexInput(&_shaders[_currentShader]->vertexInput);
+ vita2d_texture_set_fragmentInput(&_shaders[_currentShader]->fragmentInput);
+ }
+ }
+}
+
+void PSP2SdlGraphicsManager::internUpdateScreen() {
+ SDL_Surface *srcSurf, *origSurf;
+ int height, width;
+ ScalerProc *scalerProc;
+ int scale1;
+
+ // definitions not available for non-DEBUG here. (needed this to compile in SYMBIAN32 & linux?)
+#if defined(DEBUG)
+ assert(_hwscreen != NULL);
+ assert(_hwscreen->map->sw_data != NULL);
+#endif
+
+ // If the shake position changed, fill the dirty area with blackness
+ if (_currentShakePos != _newShakePos ||
+ (_mouseNeedsRedraw && _mouseBackup.y <= _currentShakePos)) {
+ SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_newShakePos * _videoMode.scaleFactor)};
+
+ if (_videoMode.aspectRatioCorrection && !_overlayVisible)
+ blackrect.h = real2Aspect(blackrect.h - 1) + 1;
+
+ SDL_FillRect(_hwscreen, &blackrect, 0);
+
+ _currentShakePos = _newShakePos;
+
+ _forceFull = true;
+ }
+
+ // Check whether the palette was changed in the meantime and update the
+ // screen surface accordingly.
+ if (_screen && _paletteDirtyEnd != 0) {
+ SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart,
+ _paletteDirtyStart,
+ _paletteDirtyEnd - _paletteDirtyStart);
+
+ _paletteDirtyEnd = 0;
+
+ _forceFull = true;
+ }
+
+ if (!_overlayVisible) {
+ origSurf = _screen;
+ srcSurf = _tmpscreen;
+ width = _videoMode.screenWidth;
+ height = _videoMode.screenHeight;
+ scalerProc = _scalerProc;
+ scale1 = _videoMode.scaleFactor;
+ } else {
+ origSurf = _overlayscreen;
+ srcSurf = _tmpscreen2;
+ width = _videoMode.overlayWidth;
+ height = _videoMode.overlayHeight;
+ scalerProc = Normal1x;
+
+ scale1 = 1;
+ }
+
+ // Add the area covered by the mouse cursor to the list of dirty rects if
+ // we have to redraw the mouse.
+ if (_mouseNeedsRedraw)
+ undrawMouse();
+
+#ifdef USE_OSD
+ updateOSD();
+#endif
+
+ // Force a full redraw if requested
+ if (_forceFull) {
+ _numDirtyRects = 1;
+ _dirtyRectList[0].x = 0;
+ _dirtyRectList[0].y = 0;
+ _dirtyRectList[0].w = width;
+ _dirtyRectList[0].h = height;
+ }
+
+ // Only draw anything if necessary
+ if (_numDirtyRects > 0 || _mouseNeedsRedraw) {
+ SDL_Rect *r;
+ SDL_Rect dst;
+ uint32 srcPitch, dstPitch;
+ SDL_Rect *lastRect = _dirtyRectList + _numDirtyRects;
+
+ for (r = _dirtyRectList; r != lastRect; ++r) {
+ dst = *r;
+ dst.x++; // Shift rect by one since 2xSai needs to access the data around
+ dst.y++; // any pixel to scale it, and we want to avoid mem access crashes.
+
+ if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
+ error("SDL_BlitSurface failed: %s", SDL_GetError());
+ }
+
+ SDL_LockSurface(srcSurf);
+ srcPitch = srcSurf->pitch;
+ dstPitch = _hwscreen->pitch;
+
+ for (r = _dirtyRectList; r != lastRect; ++r) {
+ register int dst_y = r->y + _currentShakePos;
+ register int dst_h = 0;
+#ifdef USE_SCALERS
+ register int orig_dst_y = 0;
+#endif
+ register int rx1 = r->x * scale1;
+
+ if (dst_y < height) {
+ dst_h = r->h;
+ if (dst_h > height - dst_y)
+ dst_h = height - dst_y;
+
+#ifdef USE_SCALERS
+ orig_dst_y = dst_y;
+#endif
+ dst_y = dst_y * scale1;
+
+ if (_videoMode.aspectRatioCorrection && !_overlayVisible)
+ dst_y = real2Aspect(dst_y);
+
+ assert(scalerProc != NULL);
+ scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
+ (byte *)_hwscreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
+ }
+
+ r->x = rx1;
+ r->y = dst_y;
+ r->w = r->w * scale1;
+ r->h = dst_h * scale1;
+
+#ifdef USE_SCALERS
+ if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible)
+ r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
+#endif
+ }
+ SDL_UnlockSurface(srcSurf);
+ // Readjust the dirty rect list in case we are doing a full update.
+ // This is necessary if shaking is active.
+ if (_forceFull) {
+ _dirtyRectList[0].y = 0;
+ _dirtyRectList[0].h = effectiveScreenHeight();
+ }
+
+ drawMouse();
+
+#ifdef USE_OSD
+ drawOSD();
+#endif
+
+#ifdef USE_SDL_DEBUG_FOCUSRECT
+ // We draw the focus rectangle on top of everything, to assure it's easily visible.
+ // Of course when the overlay is visible we do not show it, since it is only for game
+ // specific focus.
+ if (_enableFocusRect && !_overlayVisible) {
+ int y = _focusRect.top + _currentShakePos;
+ int h = 0;
+ int x = _focusRect.left * scale1;
+ int w = _focusRect.width() * scale1;
+
+ if (y < height) {
+ h = _focusRect.height();
+ if (h > height - y)
+ h = height - y;
+
+ y *= scale1;
+
+ if (_videoMode.aspectRatioCorrection && !_overlayVisible)
+ y = real2Aspect(y);
+
+ if (h > 0 && w > 0) {
+ // Use white as color for now.
+ Uint32 rectColor = SDL_MapRGB(_hwscreen->format, 0xFF, 0xFF, 0xFF);
+
+ // First draw the top and bottom lines
+ // then draw the left and right lines
+ if (_hwscreen->format->BytesPerPixel == 2) {
+ uint16 *top = (uint16 *)((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 2);
+ uint16 *bottom = (uint16 *)((byte *)_hwscreen->pixels + (y + h) * _hwscreen->pitch + x * 2);
+ byte *left = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 2);
+ byte *right = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + (x + w - 1) * 2);
+
+ while (w--) {
+ *top++ = rectColor;
+ *bottom++ = rectColor;
+ }
+
+ while (h--) {
+ *(uint16 *)left = rectColor;
+ *(uint16 *)right = rectColor;
+
+ left += _hwscreen->pitch;
+ right += _hwscreen->pitch;
+ }
+ } else if (_hwscreen->format->BytesPerPixel == 4) {
+ uint32 *top = (uint32 *)((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 4);
+ uint32 *bottom = (uint32 *)((byte *)_hwscreen->pixels + (y + h) * _hwscreen->pitch + x * 4);
+ byte *left = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 4);
+ byte *right = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + (x + w - 1) * 4);
+
+ while (w--) {
+ *top++ = rectColor;
+ *bottom++ = rectColor;
+ }
+
+ while (h--) {
+ *(uint32 *)left = rectColor;
+ *(uint32 *)right = rectColor;
+
+ left += _hwscreen->pitch;
+ right += _hwscreen->pitch;
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ // Finally, blit all our changes to the screen
+ if (!_displayDisabled) {
+ PSP2_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList);
+ }
+ }
+
+ _numDirtyRects = 0;
+ _forceFull = false;
+ _mouseNeedsRedraw = false;
+}
+
+void PSP2SdlGraphicsManager::setAspectRatioCorrection(bool enable) {
+ Common::StackLock lock(_graphicsMutex);
+
+ if (_oldVideoMode.setup && _hardwareAspectRatioCorrection == enable)
+ return;
+
+ if (_transactionMode == kTransactionActive) {
+ _videoMode.aspectRatioCorrection = false;
+ _hardwareAspectRatioCorrection = enable;
+ // erase the screen for both buffers
+ if (_vitatex_hwscreen) {
+ for (int i = 0; i <= 10; i++) {
+ vita2d_start_drawing();
+ vita2d_clear_screen();
+ vita2d_end_drawing();
+ vita2d_swap_buffers();
+ }
+ }
+ }
+}
+
+SDL_Surface *PSP2SdlGraphicsManager::SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) {
+ SDL_Surface *screen = SurfaceSdlGraphicsManager::SDL_SetVideoMode(width, height, bpp, flags);
+
+ if (screen != nullptr) {
+ vita2d_set_vblank_wait(true);
+ _vitatex_hwscreen = vita2d_create_empty_texture_format(width, height, SCE_GXM_TEXTURE_FORMAT_R5G6B5);
+ _sdlpixels_hwscreen = screen->pixels; // for SDL_FreeSurface...
+ screen->pixels = vita2d_texture_get_datap(_vitatex_hwscreen);
+ updateShader();
+ }
+ return screen;
+}
+
+void PSP2SdlGraphicsManager::PSP2_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects) {
+ int x, y, w, h;
+ float sx, sy;
+ float ratio = (float)screen->w / (float)screen->h;
+
+ if ((_videoMode.screenHeight == 200 || _videoMode.screenHeight == 400) && _hardwareAspectRatioCorrection) {
+ ratio = ratio * (200.0f / 240.0f);
+ }
+
+ if (_videoMode.fullscreen || screen->h >= 544) {
+ h = 544;
+ w = h * ratio;
+ } else {
+ if (screen->h <= 277 && screen->w <= 480) {
+ // Use Vita hardware 2x scaling if the picture is really small
+ // this uses the current shader and filtering mode
+ h = screen->h * 2;
+ w = screen->w * 2;
+ } else {
+ h = screen->h;
+ w = screen->w;
+ }
+ if ((_videoMode.screenHeight == 200 || _videoMode.screenHeight == 400) && _hardwareAspectRatioCorrection) {
+ // stretch the height only if it fits, otherwise make the width smaller
+ if (((float)w * (1.0f / ratio)) <= 544.0f) {
+ h = w * (1.0f / ratio);
+ } else {
+ w = h * ratio;
+ }
+ }
+ }
+
+ x = (960 - w) / 2; y = (544 - h) / 2;
+ sx = (float)w / (float)screen->w;
+ sy = (float)h / (float)screen->h;
+ if (_vitatex_hwscreen) {
+ vita2d_start_drawing();
+ vita2d_draw_texture_scale(_vitatex_hwscreen, x, y, sx, sy);
+ vita2d_end_drawing();
+ vita2d_swap_buffers();
+ }
+}
+
+#endif
diff --git a/backends/graphics/psp2sdl/psp2sdl-graphics.h b/backends/graphics/psp2sdl/psp2sdl-graphics.h
new file mode 100644
index 0000000000..638437c9a6
--- /dev/null
+++ b/backends/graphics/psp2sdl/psp2sdl-graphics.h
@@ -0,0 +1,55 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_PSP2SDL_GRAPHICS_H
+#define BACKENDS_GRAPHICS_PSP2SDL_GRAPHICS_H
+
+#include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
+#include <vita2d_fbo.h>
+
+class PSP2SdlGraphicsManager : public SurfaceSdlGraphicsManager {
+public:
+ PSP2SdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window);
+ virtual ~PSP2SdlGraphicsManager();
+
+ virtual OSystem::TransactionError endGFXTransaction();
+ virtual const OSystem::GraphicsMode *getSupportedShaders() const;
+
+protected:
+ virtual void setGraphicsModeIntern();
+ virtual void unloadGFXMode();
+ virtual bool hotswapGFXMode();
+
+ virtual void internUpdateScreen();
+ virtual void updateShader();
+ virtual void setAspectRatioCorrection(bool enable);
+ virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
+ void PSP2_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
+ void PSP2_UpdateFiltering();
+
+ bool _hardwareAspectRatioCorrection;
+ vita2d_texture *_vitatex_hwscreen;
+ void *_sdlpixels_hwscreen;
+ vita2d_shader *_shaders[6];
+};
+
+#endif
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 6cd5a47e1c..4eb63fd303 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -43,6 +43,11 @@
#include "graphics/surface.h"
#include "gui/EventRecorder.h"
+static const OSystem::GraphicsMode s_supportedShaders[] = {
+ {"NONE", "Normal (no shader)", 0},
+ {0, 0, 0}
+};
+
static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
{"1x", _s("Normal (no scaling)"), GFX_NORMAL},
#ifdef USE_SCALERS
@@ -194,6 +199,23 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
#if SDL_VERSION_ATLEAST(2, 0, 0)
_videoMode.filtering = ConfMan.getBool("filtering");
#endif
+
+ if (g_system->hasFeature(OSystem::kFeatureShader)) {
+ // shader number 0 is the entry NONE (no shader)
+ const OSystem::GraphicsMode *p = s_supportedShaders;
+ _numShaders = 0;
+ while (p->name) {
+ _numShaders++;
+ p++;
+ }
+ _currentShader = ConfMan.getInt("shader");
+ if (_currentShader < 0 || _currentShader >= _numShaders) {
+ _currentShader = 0;
+ }
+ } else {
+ _numShaders = 1;
+ _currentShader = 0;
+ }
}
SurfaceSdlGraphicsManager::~SurfaceSdlGraphicsManager() {
@@ -602,6 +624,8 @@ void SurfaceSdlGraphicsManager::setGraphicsModeIntern() {
Common::StackLock lock(_graphicsMutex);
ScalerProc *newScalerProc = 0;
+ updateShader();
+
switch (_videoMode.mode) {
case GFX_NORMAL:
newScalerProc = Normal1x;
@@ -676,6 +700,21 @@ int SurfaceSdlGraphicsManager::getGraphicsMode() const {
return _videoMode.mode;
}
+const OSystem::GraphicsMode *SurfaceSdlGraphicsManager::getSupportedShaders() const {
+ return s_supportedShaders;
+}
+
+int SurfaceSdlGraphicsManager::getShader() {
+ return _currentShader;
+}
+
+bool SurfaceSdlGraphicsManager::setShader(int id) {
+ assert(id >= 0 && id < _numShaders);
+ _currentShader = id;
+ updateShader();
+ return true;
+}
+
void SurfaceSdlGraphicsManager::initSize(uint w, uint h, const Graphics::PixelFormat *format) {
assert(_transactionMode == kTransactionActive);
@@ -996,10 +1035,18 @@ bool SurfaceSdlGraphicsManager::hotswapGFXMode() {
_overlayscreen = NULL;
// Release the HW screen surface
- SDL_FreeSurface(_hwscreen); _hwscreen = NULL;
-
- SDL_FreeSurface(_tmpscreen); _tmpscreen = NULL;
- SDL_FreeSurface(_tmpscreen2); _tmpscreen2 = NULL;
+ if (_hwscreen) {
+ SDL_FreeSurface(_hwscreen);
+ _hwscreen = NULL;
+ }
+ if (_tmpscreen) {
+ SDL_FreeSurface(_tmpscreen);
+ _tmpscreen = NULL;
+ }
+ if (_tmpscreen2) {
+ SDL_FreeSurface(_tmpscreen2);
+ _tmpscreen2 = NULL;
+ }
// Setup the new GFX mode
if (!loadGFXMode()) {
@@ -1039,6 +1086,17 @@ void SurfaceSdlGraphicsManager::updateScreen() {
internUpdateScreen();
}
+void SurfaceSdlGraphicsManager::updateShader() {
+// shader init code goes here
+// currently only used on Vita port
+// the user-selected shaderID should be obtained via ConfMan.getInt("shader")
+// and the corresponding shader should then be activated here
+// this way the user can combine any software scaling (scalers)
+// with any hardware shading (shaders). The shaders could provide
+// scanline masks, overlays, but could also serve for
+// hardware-based up-scaling (sharp-bilinear-simple, etc.)
+}
+
void SurfaceSdlGraphicsManager::internUpdateScreen() {
SDL_Surface *srcSurf, *origSurf;
int height, width;
@@ -2554,7 +2612,8 @@ void SurfaceSdlGraphicsManager::deinitializeRenderer() {
SDL_DestroyRenderer(_renderer);
_renderer = nullptr;
- _window->destroyWindow();
+ if (_window)
+ _window->destroyWindow();
}
void SurfaceSdlGraphicsManager::setWindowResolution(int width, int height) {
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 975cbfe27b..ef41b90f6c 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -105,6 +105,9 @@ public:
virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; }
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
#endif
+ virtual const OSystem::GraphicsMode *getSupportedShaders() const;
+ virtual int getShader();
+ virtual bool setShader(int id);
virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
virtual int getScreenChangeID() const { return _screenChangeCount; }
@@ -200,7 +203,7 @@ protected:
void setWindowResolution(int width, int height);
void recreateScreenTexture();
- SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
+ virtual SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
void SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
#endif
@@ -302,6 +305,9 @@ protected:
int _screenChangeCount;
+ int _currentShader;
+ int _numShaders;
+
enum {
NUM_DIRTY_RECT = 100,
MAX_SCALING = 3
@@ -384,6 +390,7 @@ protected:
virtual void blitCursor();
virtual void internUpdateScreen();
+ virtual void updateShader();
virtual bool loadGFXMode();
virtual void unloadGFXMode();
diff --git a/backends/mixer/sdl/sdl-mixer.cpp b/backends/mixer/sdl/sdl-mixer.cpp
index 0ca3231892..3e65fbae97 100644
--- a/backends/mixer/sdl/sdl-mixer.cpp
+++ b/backends/mixer/sdl/sdl-mixer.cpp
@@ -32,7 +32,7 @@
#if defined(GP2X)
#define SAMPLES_PER_SEC 11025
-#elif defined(PLAYSTATION3)
+#elif defined(PLAYSTATION3) || defined(PSP2)
#define SAMPLES_PER_SEC 48000
#else
#define SAMPLES_PER_SEC 44100
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index 1fef5c5a48..1dab18d54e 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -81,6 +81,18 @@ int ModularBackend::getGraphicsMode() const {
return _graphicsManager->getGraphicsMode();
}
+const OSystem::GraphicsMode *ModularBackend::getSupportedShaders() const {
+ return _graphicsManager->getSupportedShaders();
+}
+
+bool ModularBackend::setShader(int id) {
+ return _graphicsManager->setShader(id);
+}
+
+int ModularBackend::getShader() const {
+ return _graphicsManager->getShader();
+}
+
void ModularBackend::resetGraphicsScale() {
_graphicsManager->resetGraphicsScale();
}
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index 23f0e2d547..d828c2dde6 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -66,6 +66,9 @@ public:
virtual int getDefaultGraphicsMode() const;
virtual bool setGraphicsMode(int mode);
virtual int getGraphicsMode() const;
+ virtual const GraphicsMode *getSupportedShaders() const;
+ virtual int getShader() const;
+ virtual bool setShader(int id);
virtual void resetGraphicsScale();
#ifdef USE_RGB_COLOR
virtual Graphics::PixelFormat getScreenFormat() const;
diff --git a/backends/module.mk b/backends/module.mk
index 158f9a3b7c..d8b518b59a 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -290,6 +290,15 @@ MODULE_OBJS += \
timer/psp/timer.o
endif
+ifeq ($(BACKEND),psp2)
+MODULE_OBJS += \
+ fs/posix/posix-fs.o \
+ fs/psp2/psp2-fs-factory.o \
+ fs/psp2/psp2-dirent.o \
+ events/psp2sdl/psp2sdl-events.o \
+ graphics/psp2sdl/psp2sdl-graphics.o
+endif
+
ifeq ($(BACKEND),samsungtv)
MODULE_OBJS += \
events/samsungtvsdl/samsungtvsdl-events.o \
diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk
index 84ce272d3c..7fde04037f 100644
--- a/backends/platform/sdl/module.mk
+++ b/backends/platform/sdl/module.mk
@@ -37,6 +37,13 @@ MODULE_OBJS += \
ps3/ps3.o
endif
+ifdef PSP2
+CC=arm-vita-eabi-gcc
+MODULE_OBJS += \
+ psp2/psp2-main.o \
+ psp2/psp2.o
+endif
+
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
OBJS := $(MODULE_OBJS) $(OBJS)
diff --git a/backends/platform/sdl/posix/posix-main.cpp b/backends/platform/sdl/posix/posix-main.cpp
index 5deebb0ae3..92354b273e 100644
--- a/backends/platform/sdl/posix/posix-main.cpp
+++ b/backends/platform/sdl/posix/posix-main.cpp
@@ -22,7 +22,7 @@
#include "common/scummsys.h"
-#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(ANDROIDSDL)
+#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(PSP2) && !defined(ANDROIDSDL)
#include "backends/platform/sdl/posix/posix.h"
#include "backends/plugins/sdl/sdl-provider.h"
diff --git a/backends/platform/sdl/psp2/psp2-main.cpp b/backends/platform/sdl/psp2/psp2-main.cpp
new file mode 100644
index 0000000000..0bdf0b34bc
--- /dev/null
+++ b/backends/platform/sdl/psp2/psp2-main.cpp
@@ -0,0 +1,66 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <psp2/kernel/processmgr.h>
+#include <psp2/power.h>
+
+#include "common/scummsys.h"
+#include "backends/platform/sdl/psp2/psp2.h"
+#include "backends/plugins/sdl/sdl-provider.h"
+#include "base/main.h"
+
+int _newlib_heap_size_user = 192 * 1024 * 1024;
+
+int main(int argc, char *argv[]) {
+
+#ifdef __PSP2_DEBUG__
+ psp2shell_init(3333, 10);
+#endif
+
+ scePowerSetArmClockFrequency(444);
+ scePowerSetBusClockFrequency(222);
+ scePowerSetGpuClockFrequency(222);
+ scePowerSetGpuXbarClockFrequency(166);
+
+ // Create our OSystem instance
+ g_system = new OSystem_PSP2();
+ assert(g_system);
+
+ // Pre initialize the backend
+ ((OSystem_PSP2 *)g_system)->init();
+
+#ifdef DYNAMIC_MODULES
+ PluginManager::instance().addPluginProvider(new SDLPluginProvider());
+#endif
+
+ // Invoke the actual ScummVM main entry point:
+ int res = scummvm_main(argc, argv);
+
+ // Free OSystem
+ delete (OSystem_PSP2 *)g_system;
+
+#ifdef __PSP2_DEBUG__
+ psp2shell_exit();
+#endif
+
+ return res;
+}
diff --git a/backends/platform/sdl/psp2/psp2.cpp b/backends/platform/sdl/psp2/psp2.cpp
new file mode 100644
index 0000000000..3c0cb9106d
--- /dev/null
+++ b/backends/platform/sdl/psp2/psp2.cpp
@@ -0,0 +1,143 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir
+#define FORBIDDEN_SYMBOL_EXCEPTION_time_h // sys/stat.h includes sys/time.h
+#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
+
+#include "common/scummsys.h"
+#include "common/config-manager.h"
+#include "common/debug-channels.h"
+#include "backends/platform/sdl/psp2/psp2.h"
+#include "backends/graphics/psp2sdl/psp2sdl-graphics.h"
+#include "backends/saves/default/default-saves.h"
+
+#include "backends/fs/psp2/psp2-fs-factory.h"
+#include "backends/events/psp2sdl/psp2sdl-events.h"
+#include "backends/fs/psp2/psp2-dirent.h"
+#include <sys/stat.h>
+
+#ifdef __PSP2_DEBUG__
+#include <psp2shell.h>
+#endif
+
+int access(const char *pathname, int mode) {
+ struct stat sb;
+
+ if (stat(pathname, &sb) == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+OSystem_PSP2::OSystem_PSP2(Common::String baseConfigName)
+ : _baseConfigName(baseConfigName) {
+}
+
+void OSystem_PSP2::init() {
+
+#if __PSP2_DEBUG__
+ gDebugLevel = 3;
+#endif
+
+ // Initialze File System Factory
+ sceIoMkdir("ux0:data", 0755);
+ sceIoMkdir("ux0:data/scummvm", 0755);
+ sceIoMkdir("ux0:data/scummvm/saves", 0755);
+ _fsFactory = new PSP2FilesystemFactory();
+
+ // Invoke parent implementation of this method
+ OSystem_SDL::init();
+}
+
+void OSystem_PSP2::initBackend() {
+
+ ConfMan.set("joystick_num", 0);
+ ConfMan.set("vkeybdpath", PREFIX "/data");
+ ConfMan.registerDefault("fullscreen", true);
+ ConfMan.registerDefault("aspect_ratio", false);
+ ConfMan.registerDefault("gfx_mode", "2x");
+ ConfMan.registerDefault("filtering", true);
+ ConfMan.registerDefault("kbdmouse_speed", 3);
+ ConfMan.registerDefault("joystick_deadzone", 2);
+ ConfMan.registerDefault("shader", 0);
+
+ if (!ConfMan.hasKey("fullscreen")) {
+ ConfMan.setBool("fullscreen", true);
+ }
+ if (!ConfMan.hasKey("aspect_ratio")) {
+ ConfMan.setBool("aspect_ratio", false);
+ }
+ if (!ConfMan.hasKey("gfx_mode")) {
+ ConfMan.set("gfx_mode", "2x");
+ }
+ if (!ConfMan.hasKey("filtering")) {
+ ConfMan.setBool("filtering", true);
+ }
+ if (!ConfMan.hasKey("kbdmouse_speed")) {
+ ConfMan.setInt("kbdmouse_speed", 3);
+ }
+ if (!ConfMan.hasKey("joystick_deadzone")) {
+ ConfMan.setInt("joystick_deadzone", 2);
+ }
+ if (!ConfMan.hasKey("shader")) {
+ ConfMan.setInt("shader", 0);
+ }
+
+ // Create the savefile manager
+ if (_savefileManager == 0)
+ _savefileManager = new DefaultSaveFileManager("ux0:data/scummvm/saves");
+
+ // Event source
+ if (_eventSource == 0)
+ _eventSource = new PSP2EventSource();
+
+ // Graphics Manager
+ if (_graphicsManager == 0)
+ _graphicsManager = new PSP2SdlGraphicsManager(_eventSource, _window);
+
+ // Invoke parent implementation of this method
+ OSystem_SDL::initBackend();
+}
+
+bool OSystem_PSP2::hasFeature(Feature f) {
+ return (f == kFeatureKbdMouseSpeed ||
+ f == kFeatureJoystickDeadzone ||
+ f == kFeatureShader ||
+ OSystem_SDL::hasFeature(f));
+}
+
+void OSystem_PSP2::logMessage(LogMessageType::Type type, const char *message) {
+#if __PSP2_DEBUG__
+ psp2shell_print(message);
+#endif
+}
+
+Common::String OSystem_PSP2::getDefaultConfigFileName() {
+ return "ux0:data/scummvm/" + _baseConfigName;
+}
+
+Common::WriteStream *OSystem_PSP2::createLogFile() {
+ Common::FSNode file("ux0:data/scummvm/scummvm.log");
+ return file.createWriteStream();
+}
diff --git a/backends/platform/sdl/psp2/psp2.h b/backends/platform/sdl/psp2/psp2.h
new file mode 100644
index 0000000000..65d98098be
--- /dev/null
+++ b/backends/platform/sdl/psp2/psp2.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef PLATFORM_SDL_PSP2_H
+#define PLATFORM_SDL_PSP2_H
+
+#include "backends/platform/sdl/sdl.h"
+#ifdef __PSP2_DEBUG__
+#include <psp2shell.h>
+#endif
+
+class OSystem_PSP2 : public OSystem_SDL {
+public:
+ // Let the subclasses be able to change _baseConfigName in the constructor
+ OSystem_PSP2(Common::String baseConfigName = "scummvm.ini");
+ virtual ~OSystem_PSP2() {}
+
+ virtual void init();
+ virtual void initBackend();
+ virtual bool hasFeature(Feature f);
+ virtual void logMessage(LogMessageType::Type type, const char *message);
+
+protected:
+ // Base string for creating the default path and filename
+ // for the configuration file
+ Common::String _baseConfigName;
+
+ virtual Common::String getDefaultConfigFileName();
+
+ virtual Common::WriteStream *createLogFile();
+};
+
+#endif
diff --git a/backends/platform/sdl/psp2/psp2.mk b/backends/platform/sdl/psp2/psp2.mk
new file mode 100644
index 0000000000..b719ed7acf
--- /dev/null
+++ b/backends/platform/sdl/psp2/psp2.mk
@@ -0,0 +1,26 @@
+DATE := $(shell date +%y-%m-%d)
+
+psp2vpk: $(EXECUTABLE)
+ rm -rf psp2pkg
+ rm -f $(EXECUTABLE)-$(DATE).vpk
+ mkdir -p psp2pkg/sce_sys/livearea/contents
+ mkdir -p psp2pkg/data/
+ mkdir -p psp2pkg/doc/
+ vita-elf-create $(EXECUTABLE) $(EXECUTABLE).velf
+ vita-make-fself -s -c $(EXECUTABLE).velf psp2pkg/eboot.bin
+ vita-mksfoex -s TITLE_ID=VSCU00001 "$(EXECUTABLE)" psp2pkg/sce_sys/param.sfo
+ cp $(srcdir)/dists/psp2/icon0.png psp2pkg/sce_sys/
+ cp $(srcdir)/dists/psp2/template.xml psp2pkg/sce_sys/livearea/contents/
+ cp $(srcdir)/dists/psp2/bg.png psp2pkg/sce_sys/livearea/contents/
+ cp $(srcdir)/dists/psp2/startup.png psp2pkg/sce_sys/livearea/contents/
+ cp $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip psp2pkg/data/
+ cp $(srcdir)/backends/vkeybd/packs/vkeybd_small.zip psp2pkg/data/
+ cp $(DIST_FILES_THEMES) psp2pkg/data/
+ifdef DIST_FILES_ENGINEDATA
+ cp $(DIST_FILES_ENGINEDATA) psp2pkg/data/
+endif
+ cp $(DIST_FILES_DOCS) psp2pkg/doc/
+ cp $(srcdir)/dists/psp2/readme-psp2.md psp2pkg/doc/
+ cd psp2pkg && zip -r ../$(EXECUTABLE)-$(DATE).vpk . && cd ..
+
+.PHONY: psp2vpk