aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2017-03-04 22:45:01 +0100
committerGitHub2017-03-04 22:45:01 +0100
commit547e5846a144b820981c45cf3f76c77075971197 (patch)
tree361701d1d21f9bcf1708e1e1d922e3e743ae6c59
parent72962ae0f6338ccecd29efb4da65efe99acf4b99 (diff)
parent70988527c64947fd7fe3c361907e9f0806b0cb5c (diff)
downloadscummvm-rg350-547e5846a144b820981c45cf3f76c77075971197.tar.gz
scummvm-rg350-547e5846a144b820981c45cf3f76c77075971197.tar.bz2
scummvm-rg350-547e5846a144b820981c45cf3f76c77075971197.zip
Merge pull request #915 from rsn8887/vita
PSP2: Add Playstation Vita support
-rw-r--r--.gitignore5
-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
-rw-r--r--common/system.h35
-rwxr-xr-xconfigure81
-rw-r--r--dists/psp2/bg.pngbin0 -> 75965 bytes
-rw-r--r--dists/psp2/icon0.pngbin0 -> 4845 bytes
-rw-r--r--dists/psp2/readme-psp2.md64
-rw-r--r--dists/psp2/startup.pngbin0 -> 27570 bytes
-rw-r--r--dists/psp2/template.xml11
-rw-r--r--gui/options.cpp49
-rw-r--r--gui/options.h8
-rw-r--r--gui/themes/default.inc20
-rw-r--r--gui/themes/scummclassic.zipbin20021 -> 129631 bytes
-rw-r--r--gui/themes/scummclassic/classic_layout.stx13
-rw-r--r--gui/themes/scummclassic/classic_layout_lowres.stx13
-rw-r--r--gui/themes/scummmodern.zipbin739209 -> 1649171 bytes
-rw-r--r--gui/themes/scummmodern/scummmodern_layout.stx13
-rw-r--r--gui/themes/scummmodern/scummmodern_layout_lowres.stx13
39 files changed, 2049 insertions, 15 deletions
diff --git a/.gitignore b/.gitignore
index dff59d2045..53dc2b90e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -208,5 +208,10 @@ dists/msvc*/**
out/
scummvm.xcodeproj
+#Ignore PSP2 files
+psp2pkg/
+*.velf
+*.vpk
+
#Ignore gmon.out created by gprof
gmon.out
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
diff --git a/common/system.h b/common/system.h
index 83bc457707..68d33b78be 100644
--- a/common/system.h
+++ b/common/system.h
@@ -361,7 +361,12 @@ public:
/**
* change analog joystick deadzone
*/
- kFeatureJoystickDeadzone
+ kFeatureJoystickDeadzone,
+
+ /**
+ * shaders
+ */
+ kFeatureShader
};
@@ -573,6 +578,34 @@ public:
#endif
/**
+ * Retrieve a list of all hardware shaders supported by this backend.
+ * This can be only hardware shaders.
+ * it is completely up to the backend maintainer to decide what is
+ * appropriate here and what not.
+ * The list is terminated by an all-zero entry.
+ * @return a list of supported shaders
+ */
+ virtual const GraphicsMode *getSupportedShaders() const {
+ static const OSystem::GraphicsMode no_shader[2] = {{"NONE", "Normal (no shader)", 0}, {0, 0, 0}};
+ return no_shader;
+ }
+
+ /**
+ * Switch to the specified shader mode. If switching to the new mode
+ * failed, this method returns false.
+ *
+ * @param mode the ID of the new shader mode
+ * @return true if the switch was successful, false otherwise
+ */
+ virtual bool setShader(int id) { return false; }
+
+ /**
+ * Determine which shader is currently active.
+ * @return the ID of the active shader
+ */
+ virtual int getShader() { return 0; }
+
+ /**
* Set the size and color format of the virtual screen. Typical sizes include:
* - 320x200 (e.g. for most SCUMM games, and Simon)
* - 320x240 (e.g. for FM-TOWN SCUMM games)
diff --git a/configure b/configure
index 7eaf54a6bc..8021a82003 100755
--- a/configure
+++ b/configure
@@ -883,7 +883,7 @@ Configuration:
-h, --help display this help and exit
--backend=BACKEND backend to build (3ds, android, dc, dingux, ds, gcw0,
gph, iphone, ios7, linuxmoto, maemo, n64, null, openpandora,
- ps2, psp, samsungtv, sdl, tizen, webos, wii, wince) [sdl]
+ ps2, psp, psp2, samsungtv, sdl, tizen, webos, wii, wince) [sdl]
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
@@ -934,6 +934,7 @@ Special configuration feature:
ouya for OUYA
ps2 for PlayStation 2
ps3 for PlayStation 3
+ psp2 for PlayStation Vita
psp for PlayStation Portable
samsungtv for Samsung TV
tizen for Samsung Tizen
@@ -1559,6 +1560,22 @@ ps3)
datadir='${datarootdir}'
docdir='${prefix}/doc'
;;
+psp2)
+ _host_os=psp2
+ _host_cpu=arm
+ _host_alias=arm-vita-eabi
+
+ # The prefix is always the same on PSP2 so we hardcode the default
+ # here. It is still possible to define a custom prefix which is
+ # needed when packaging the app with a user-specific app ID.
+ test "x$prefix" = xNONE && prefix=app0:
+ # PSP2 apps are installed into app-specific directories. The
+ # default directory structure of ScummVM makes no sense here so we
+ # hardcode PSP2 specific directories here.
+ datarootdir='${prefix}/data'
+ datadir='${datarootdir}'
+ docdir='${prefix}/doc'
+ ;;
psp)
_host_os=psp
_host_cpu=mipsallegrexel
@@ -1625,7 +1642,7 @@ fi
#
case $_host in
-caanoo | gp2x | gp2xwiz | openpandora | ps2)
+caanoo | gp2x | gp2xwiz | openpandora | ps2 | psp2)
if test "$_debug_build" = auto; then
# If you want to debug one of these platforms, use '--disable-optimizations --enable-debug'
_debug_build=no
@@ -1719,6 +1736,12 @@ ps3)
exit 1
fi
;;
+psp2)
+ if test -z "$VITASDK"; then
+ echo "Please set VITASDK in your environment. export VITASDK=<path to psp2 toolchain>"
+ exit 1
+ fi
+ ;;
psp)
if test -z "$PSPDEV"; then
PSPDEV=`psp-config --pspdev-path`
@@ -1947,7 +1970,7 @@ if test "$have_gcc" = yes ; then
case $_host_os in
# newlib-based system include files suppress non-C89 function
# declarations under __STRICT_ANSI__
- 3ds | amigaos* | android | androidsdl | dreamcast | ds | gamecube | mingw* | n64 | psp | ps2 | ps3 | tizen | wii | wince )
+ 3ds | amigaos* | android | androidsdl | dreamcast | ds | gamecube | mingw* | n64 | psp | ps2 | ps3 | psp2 | tizen | wii | wince )
;;
*)
append_var CXXFLAGS "-ansi"
@@ -2200,6 +2223,9 @@ case $_host_cpu in
;;
arm-apple-darwin11)
;;
+ # psvita does not like the asm code...
+ arm-vita-eabi)
+ ;;
*)
define_in_config_if_yes yes 'USE_ARM_SCALER_ASM'
@@ -2627,6 +2653,27 @@ case $_host_os in
add_line_to_config_mk 'PLAYSTATION3 = 1'
add_line_to_config_h "#define PREFIX \"${prefix}\""
;;
+ psp2)
+ _freetypepath="$VITASDK/arm-vita-eabi/bin"
+ _freetype2=yes
+ _libcurlpath="$VITASDK/arm-vita-eabi/bin"
+ append_var CXXFLAGS "--sysroot=$VITASDK/arm-vita-eabi"
+ append_var LDFLAGS "--sysroot=$VITASDK/arm-vita-eabi"
+ append_var DEFINES "-DPSP2 -DSYSTEM_NOT_SUPPORTING_D_TYPE"
+ append_var CXXFLAGS "-Wl,-q -I$VITASDK/arm-vita-eabi/include"
+ append_var CXXFLAGS "-march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=hard"
+ append_var LDFLAGS "-Wl,-q -L$VITASDK/arm-vita-eabi/lib"
+ if test "$_debug_build" = no; then
+ _optimization_level=-O1
+ fi
+ if test "$_debug_build" = yes; then
+ _optimization_level=-O0
+ append_var DEFINES "-D__PSP2_DEBUG__"
+ append_var LIBS "-lpsp2shell"
+ fi
+ add_line_to_config_mk 'PSP2 = 1'
+ add_line_to_config_h "#define PREFIX \"${prefix}\""
+ ;;
psp)
if test -d "$PSPDEV/psp/lib"; then
append_var LDFLAGS "-L$PSPDEV/psp/lib"
@@ -3121,6 +3168,16 @@ if test -n "$_host"; then
_eventrec=no
_port_mk="backends/platform/sdl/ps3/ps3.mk"
;;
+ psp2)
+ _backend="psp2"
+ _vkeybd=yes
+ _build_scalers=yes
+ _build_hq_scalers=no
+ _mt32emu=no
+ _timidity=no
+ _eventrec=no
+ _port_mk="backends/platform/sdl/psp2/psp2.mk"
+ ;;
psp)
_backend="psp"
_build_scalers=no
@@ -3294,6 +3351,17 @@ case $_backend in
append_var LIBS "-lpng"
append_var LIBS "-Wl,-Map,mapfile.txt"
;;
+ psp2)
+ append_var LIBS "-lvitashaders -lSDL2 -lvita2d_fbo -lSceCommonDialog_stub"
+ append_var LIBS "-lSceSysmodule_stub -lSceDisplay_stub -lSceGxm_stub"
+ append_var LIBS "-lSceAudio_stub -lSceCtrl_stub -lScePower_stub"
+ append_var LIBS "-lSceNet_stub -lSceNetCtl_stub -lSceAppMgr_stub -lScePgf_stub"
+ append_var DEFINES "-DSDL_BACKEND"
+ add_line_to_config_mk "SDL_BACKEND = 1"
+ add_line_to_config_mk "USE_SDL2 = 1"
+ append_var MODULES "backends/platform/sdl"
+ append_var INCLUDES "-I$VITASDK/arm-vita-eabi/include/SDL2"
+ ;;
samsungtv)
append_var DEFINES "-DSAMSUNGTV"
append_var LDFLAGS "-shared"
@@ -3404,7 +3472,7 @@ esac
# Enable 16bit support only for backends which support it
#
case $_backend in
- 3ds | android | androidsdl | dingux | dc | gph | iphone | ios7 | maemo | openpandora | psp | samsungtv | sdl | tizen | webos | wii)
+ 3ds | android | androidsdl | dingux | dc | gph | iphone | ios7 | maemo | openpandora | psp | psp2 | samsungtv | sdl | tizen | webos | wii)
if test "$_16bit" = auto ; then
_16bit=yes
else
@@ -3480,7 +3548,7 @@ esac
#
echo_n "Checking if host is POSIX compliant... "
case $_host_os in
- amigaos* | cygwin* | dreamcast | ds | gamecube | mingw* | n64 | ps2 | ps3 | psp | wii | wince)
+ amigaos* | cygwin* | dreamcast | ds | gamecube | mingw* | n64 | ps2 | ps3 | psp2 | psp | wii | wince)
_posix=no
;;
3ds | android | androidsdl | beos* | bsd* | darwin* | freebsd* | gnu* | gph-linux | haiku* | hpux* | iphone | ios7 | irix*| k*bsd*-gnu* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | uclinux* | webos)
@@ -4189,6 +4257,9 @@ if test "$_libcurl" != "no"; then
amigaos*)
append_var LIBCURL_LIBS "-lpthread"
;;
+ psp2*)
+ append_var LIBCURL_LIBS "-lssl -lcrypto"
+ ;;
esac
if test "$_libcurl" = "auto"; then
diff --git a/dists/psp2/bg.png b/dists/psp2/bg.png
new file mode 100644
index 0000000000..a6fa8bdc81
--- /dev/null
+++ b/dists/psp2/bg.png
Binary files differ
diff --git a/dists/psp2/icon0.png b/dists/psp2/icon0.png
new file mode 100644
index 0000000000..65696f6f55
--- /dev/null
+++ b/dists/psp2/icon0.png
Binary files differ
diff --git a/dists/psp2/readme-psp2.md b/dists/psp2/readme-psp2.md
new file mode 100644
index 0000000000..559c2fbd60
--- /dev/null
+++ b/dists/psp2/readme-psp2.md
@@ -0,0 +1,64 @@
+Prerequisites
+=============
+- A homebrew enabled PlayStation Vita console.
+- At least one ScummVM supported game. The list of compatible games can be seen here: http://www.scummvm.org/compatibility/
+The page http://wiki.scummvm.org/index.php/Where_to_get_the_games references some places where those games can be bought. Demonstration versions for most of the supported games are downloadable on http://scummvm.org/demos/
+
+Installing
+==========
+From a computer, download the installable package. Unzip and copy the .vpk file it to the PlayStation Vita and install it.
+
+Configuring and playing games
+=============================
+The user manual describes how to add games to ScummVM and launch them : http://wiki.scummvm.org/index.php/User_Manual
+
+PlayStation Vita Specifics
+==========================
+Saves are wrote in the ux0:/data/scummvm/saves folder.
+
+Joypad button mapping
+=====================
+- Left stick => Mouse
+- R + Left stick => Slow Mouse
+- Cross => Left mouse button
+- Circle => Right mouse button
+- DPad => Cursor Keys (useful for character motion)
+- R + DPad => Diagonal Cursor Keys
+- L Trigger => Game menu (F5)
+- R Trigger => Shift (used to enable Mass Add in menu)
+- Square => Period '.' (used to skip dialog lines)
+- R + Square => Space ' '
+- Triangle => Escape (used to skip cutscenes)
+- R + Triangle => Return
+- Start => ScummVM's global in-game menu
+- Select => Toggle virtual keyboard
+- R + Select => AGI predictive input dialog
+
+Disclaimer
+==========
+Unauthorized distribution of an installable package with non freeware games included is a violation of the copyright law and is as such forbidden.
+
+Building from source
+====================
+This port of ScummVM to the PSP2 is based on SDL2. It uses the open source SDK VITASDK.
+
+The dependencies needed to build it are :
+
+- The toolchain from https://github.com/vitadev/vdpm
+- zlib, libpng, libjpeg-turbo, libogg, libvorbis, flac, curl, openssl, freetype, from https://github.com/vitadev/vdpm
+- libmad from https://github.com/Cpasjuste/libmad-psp2
+- SDL2 from https://github.com/Cpasjuste/SDL-Vita
+- ScummVM from https://github.com/Cpasjuste/scummvm
+- The fbo branch of libvita2d from https://github.com/frangarcj/vita2dlib/tree/fbo/libvita2d
+copied under new names libvita2d_fbo.a in $VITASDK/arm-vita-eabi-gcc/lib and vita2d_fbo.h in $VITASDK/arm-vita-eabi-gcc/include. The renaming is necessary to prevent conflict with the official vita2d lib that comes with the VitaSDK.
+- The pre-compiled gtu release of vita-shader-collection from https://github.com/frangarcj/vita-shader-collection/releases, copy all headers to $VITASDK/arm-vita-eabi-gcc/include and the library libvitashaders.a to $VITASDK/arm-vita-eabi-gcc/lib
+
+Once all the dependencies are correctly setup, an installable package can be obtained from source by issuing the following command :
+
+./configure --host=psp2 && make psp2vpk
+
+Thanks
+======
+Xavier from consoleX for donating a ps vita device
+xerpi for initial SDL2 port
+VITASDK and henkaku developers
diff --git a/dists/psp2/startup.png b/dists/psp2/startup.png
new file mode 100644
index 0000000000..4f50ea395f
--- /dev/null
+++ b/dists/psp2/startup.png
Binary files differ
diff --git a/dists/psp2/template.xml b/dists/psp2/template.xml
new file mode 100644
index 0000000000..a4d43f0130
--- /dev/null
+++ b/dists/psp2/template.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<livearea style="a1" format-ver="01.00" content-rev="1">
+ <livearea-background>
+ <image>bg.png</image>
+ </livearea-background>
+
+ <gate>
+ <startup-image>startup.png</startup-image>
+ </gate>
+</livearea>
diff --git a/gui/options.cpp b/gui/options.cpp
index ae88781b71..5b62d493c4 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -159,6 +159,9 @@ void OptionsDialog::init() {
_fullscreenCheckbox = 0;
_filteringCheckbox = 0;
_aspectCheckbox = 0;
+ _enableShaderSettings = false;
+ _shaderPopUpDesc = 0;
+ _shaderPopUp = 0;
_enableAudioSettings = false;
_midiPopUp = 0;
_midiPopUpDesc = 0;
@@ -315,6 +318,14 @@ void OptionsDialog::build() {
}
+ // Shader options
+ if (g_system->hasFeature(OSystem::kFeatureShader)) {
+ if (_shaderPopUp) {
+ int value = ConfMan.getInt("shader", _domain);
+ _shaderPopUp->setSelected(value);
+ }
+ }
+
// Audio options
if (!loadMusicDeviceSetting(_midiPopUp, "music_driver"))
_midiPopUp->setSelected(0);
@@ -549,6 +560,18 @@ void OptionsDialog::apply() {
}
}
+ // Shader options
+ if (_enableShaderSettings) {
+ if (g_system->hasFeature(OSystem::kFeatureShader)) {
+ if (_shaderPopUp) {
+ if (ConfMan.getInt("shader", _domain) != _shaderPopUp->getSelectedTag()) {
+ ConfMan.setInt("shader", _shaderPopUp->getSelectedTag(), _domain);
+ g_system->setShader(_shaderPopUp->getSelectedTag());
+ }
+ }
+ }
+ }
+
// Control options
if (_enableControlSettings) {
if (g_system->hasFeature(OSystem::kFeatureOnScreenControl)) {
@@ -967,6 +990,23 @@ void OptionsDialog::addControlControls(GuiObject *boss, const Common::String &pr
_enableControlSettings = true;
}
+void OptionsDialog::addShaderControls(GuiObject *boss, const Common::String &prefix) {
+ // Shader selector
+ if (g_system->hasFeature(OSystem::kFeatureShader)) {
+ if (g_system->getOverlayWidth() > 320)
+ _shaderPopUpDesc = new StaticTextWidget(boss, prefix + "grShaderPopUpDesc", _("HW Shader:"), _("Different hardware shaders give different visual effects"));
+ else
+ _shaderPopUpDesc = new StaticTextWidget(boss, prefix + "grShaderPopUpDesc", _c("HW Shader:", "lowres"), _("Different hardware shaders give different visual effects"));
+ _shaderPopUp = new PopUpWidget(boss, prefix + "grShaderPopUp", _("Different shaders give different visual effects"));
+ const OSystem::GraphicsMode *p = g_system->getSupportedShaders();
+ while (p->name) {
+ _shaderPopUp->appendEntry(p->name, p->id);
+ p++;
+ }
+ }
+ _enableShaderSettings = true;
+}
+
void OptionsDialog::addGraphicControls(GuiObject *boss, const Common::String &prefix) {
const OSystem::GraphicsMode *gm = g_system->getSupportedGraphicsModes();
Common::String context;
@@ -1422,6 +1462,15 @@ void GlobalOptionsDialog::build() {
addGraphicControls(tab, "GlobalOptions_Graphics.");
//
+ // The shader tab (currently visible only for Vita platform), visibility checking by features
+ //
+
+ if (g_system->hasFeature(OSystem::kFeatureShader)) {
+ tab->addTab(_("Shader"));
+ addShaderControls(tab, "GlobalOptions_Shader.");
+ }
+
+ //
// The control tab (currently visible only for AndroidSDL, SDL, and Vita platform, visibility checking by features
//
if (g_system->hasFeature(OSystem::kFeatureTouchpadMode) ||
diff --git a/gui/options.h b/gui/options.h
index 2f628315e4..ed07307f80 100644
--- a/gui/options.h
+++ b/gui/options.h
@@ -89,6 +89,7 @@ protected:
void addControlControls(GuiObject *boss, const Common::String &prefix);
void addGraphicControls(GuiObject *boss, const Common::String &prefix);
+ void addShaderControls(GuiObject *boss, const Common::String &prefix);
void addAudioControls(GuiObject *boss, const Common::String &prefix);
void addMIDIControls(GuiObject *boss, const Common::String &prefix);
void addMT32Controls(GuiObject *boss, const Common::String &prefix);
@@ -142,6 +143,13 @@ private:
CheckboxWidget *_aspectCheckbox;
StaticTextWidget *_renderModePopUpDesc;
PopUpWidget *_renderModePopUp;
+
+ //
+ // Shader controls
+ //
+ bool _enableShaderSettings;
+ StaticTextWidget *_shaderPopUpDesc;
+ PopUpWidget *_shaderPopUp;
//
// Audio controls
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index f967067adc..6e79450e23 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -877,6 +877,16 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
"/>"
"</layout>"
"</dialog>"
+"<dialog name = 'GlobalOptions_Shader' overlays = 'Dialog.GlobalOptions.TabWidget'>"
+"<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>"
+"<widget name = 'grShaderPopUpDesc' "
+"type = 'OptionsLabel' "
+"/>"
+"<widget name = 'grShaderPopUp' "
+"type = 'PopUp' "
+"/>"
+"</layout>"
+"</dialog>"
"<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'>"
"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<layout type='horizontal' padding='0,0,0,0' spacing='10' center='true'>"
@@ -2454,6 +2464,16 @@ const char *defaultXML1 = "<?xml version = '1.0'?>"
"/>"
"</layout>"
"</dialog>"
+"<dialog name = 'GlobalOptions_Shader' overlays = 'Dialog.GlobalOptions.TabWidget'>"
+"<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>"
+"<widget name = 'grShaderPopUpDesc' "
+"type = 'OptionsLabel' "
+"/>"
+"<widget name = 'grShaderPopUp' "
+"type = 'PopUp' "
+"/>"
+"</layout>"
+"</dialog>"
"<dialog name='GlobalOptions_Audio' overlays='Dialog.GlobalOptions.TabWidget'>"
"<layout type='vertical' padding='16,16,16,16' spacing='8'>"
"<layout type='horizontal' padding='0,0,0,0' spacing='6' center='true'>"
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index 8024437f6b..bff0388d3e 100644
--- a/gui/themes/scummclassic.zip
+++ b/gui/themes/scummclassic.zip
Binary files differ
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index 35f4a03e6d..9d9fe28a16 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -304,6 +304,19 @@
</layout>
</dialog>
+ <dialog name = 'GlobalOptions_Shader' overlays = 'Dialog.GlobalOptions.TabWidget'>
+ <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
+ <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
+ <widget name = 'grShaderPopUpDesc'
+ type = 'OptionsLabel'
+ />
+ <widget name = 'grShaderPopUp'
+ type = 'PopUp'
+ />
+ </layout>
+ </layout>
+ </dialog>
+
<dialog name = 'GlobalOptions_Audio' overlays = 'Dialog.GlobalOptions.TabWidget'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 1085c5fc6f..d0c3170d8e 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -301,6 +301,19 @@
</layout>
</dialog>
+ <dialog name = 'GlobalOptions_Shader' overlays = 'Dialog.GlobalOptions.TabWidget'>
+ <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
+ <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
+ <widget name = 'grShaderPopUpDesc'
+ type = 'OptionsLabel'
+ />
+ <widget name = 'grShaderPopUp'
+ type = 'PopUp'
+ />
+ </layout>
+ </layout>
+ </dialog>
+
<dialog name = 'GlobalOptions_Audio' overlays = 'Dialog.GlobalOptions.TabWidget'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index 73aee35f61..983f727f6a 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index 9633cb4e50..25a95845aa 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -318,6 +318,19 @@
</layout>
</dialog>
+ <dialog name = 'GlobalOptions_Shader' overlays = 'Dialog.GlobalOptions.TabWidget'>
+ <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
+ <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
+ <widget name = 'grShaderPopUpDesc'
+ type = 'OptionsLabel'
+ />
+ <widget name = 'grShaderPopUp'
+ type = 'PopUp'
+ />
+ </layout>
+ </layout>
+ </dialog>
+
<dialog name = 'GlobalOptions_Audio' overlays = 'Dialog.GlobalOptions.TabWidget'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
index be8ce0c17e..3da8a6c6a3 100644
--- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx
+++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
@@ -299,6 +299,19 @@
</layout>
</dialog>
+ <dialog name = 'GlobalOptions_Shader' overlays = 'Dialog.GlobalOptions.TabWidget'>
+ <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
+ <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
+ <widget name = 'grShaderPopUpDesc'
+ type = 'OptionsLabel'
+ />
+ <widget name = 'grShaderPopUp'
+ type = 'PopUp'
+ />
+ </layout>
+ </layout>
+ </dialog>
+
<dialog name = 'GlobalOptions_Audio' overlays = 'Dialog.GlobalOptions.TabWidget'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>