PSP2: Add Playstation Vita (PSP2) support

This commit is contained in:
cpasjuste 2017-03-01 14:00:17 -06:00 committed by rsn8887
parent 3a7c091122
commit 70988527c6
39 changed files with 2049 additions and 15 deletions

5
.gitignore vendored
View file

@ -208,5 +208,10 @@ dists/msvc*/**
out/
scummvm.xcodeproj
#Ignore PSP2 files
psp2pkg/
*.velf
*.vpk
#Ignore gmon.out created by gprof
gmon.out

View file

@ -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

View file

@ -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 */

View file

@ -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>

View file

@ -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

View file

@ -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_ */

View file

@ -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);
}

View file

@ -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*/

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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,6 +2612,7 @@ void SurfaceSdlGraphicsManager::deinitializeRenderer() {
SDL_DestroyRenderer(_renderer);
_renderer = nullptr;
if (_window)
_window->destroyWindow();
}

View file

@ -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();

View file

@ -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

View file

@ -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();
}

View file

@ -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;

View file

@ -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 \

View file

@ -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)

View file

@ -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"

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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

View file

@ -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

View file

@ -361,7 +361,12 @@ public:
/**
* change analog joystick deadzone
*/
kFeatureJoystickDeadzone
kFeatureJoystickDeadzone,
/**
* shaders
*/
kFeatureShader
};
@ -572,6 +577,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)

81
configure vendored
View file

@ -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

BIN
dists/psp2/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
dists/psp2/icon0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

64
dists/psp2/readme-psp2.md Normal file
View file

@ -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

BIN
dists/psp2/startup.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

11
dists/psp2/template.xml Normal file
View file

@ -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>

View file

@ -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;
@ -1421,6 +1461,15 @@ void GlobalOptionsDialog::build() {
_graphicsTabId = tab->addTab(g_system->getOverlayWidth() > 320 ? _("Graphics") : _("GFX"));
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
//

View file

@ -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);
@ -143,6 +144,13 @@ private:
StaticTextWidget *_renderModePopUpDesc;
PopUpWidget *_renderModePopUp;
//
// Shader controls
//
bool _enableShaderSettings;
StaticTextWidget *_shaderPopUpDesc;
PopUpWidget *_shaderPopUp;
//
// Audio controls
//

View file

@ -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'>"

Binary file not shown.

View file

@ -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'>

View file

@ -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'>

Binary file not shown.

View file

@ -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'>

View file

@ -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'>