aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/fs/psp/psp-fs-factory.cpp8
-rw-r--r--backends/fs/psp/psp-fs.cpp62
-rw-r--r--backends/fs/psp/psp-stream.cpp230
-rw-r--r--backends/fs/psp/psp-stream.h70
-rw-r--r--backends/module.mk1
-rw-r--r--backends/platform/psp/Makefile7
-rw-r--r--backends/platform/psp/README.PSP.in9
-rw-r--r--backends/platform/psp/module.mk1
-rw-r--r--backends/platform/psp/osys_psp.cpp22
-rw-r--r--backends/platform/psp/osys_psp.h6
-rw-r--r--backends/platform/psp/osys_psp_gu.cpp21
-rw-r--r--backends/platform/psp/osys_psp_gu.h2
-rw-r--r--backends/platform/psp/powerman.cpp297
-rw-r--r--backends/platform/psp/powerman.h87
-rw-r--r--backends/platform/psp/psp.spec2
-rw-r--r--backends/platform/psp/psp_main.cpp32
16 files changed, 829 insertions, 28 deletions
diff --git a/backends/fs/psp/psp-fs-factory.cpp b/backends/fs/psp/psp-fs-factory.cpp
index 27bee4de86..7ed84de034 100644
--- a/backends/fs/psp/psp-fs-factory.cpp
+++ b/backends/fs/psp/psp-fs-factory.cpp
@@ -34,7 +34,13 @@ AbstractFSNode *PSPFilesystemFactory::makeRootFileNode() const {
AbstractFSNode *PSPFilesystemFactory::makeCurrentDirectoryFileNode() const {
char buf[MAXPATHLEN];
- return getcwd(buf, MAXPATHLEN) ? new PSPFilesystemNode(buf) : NULL;
+ char * ret = 0;
+
+ PowerMan.beginCriticalSection();
+ ret = getcwd(buf, MAXPATHLEN);
+ PowerMan.endCriticalSection();
+
+ return (ret ? new PSPFilesystemNode(buf) : NULL);
}
AbstractFSNode *PSPFilesystemFactory::makeFileNodePath(const Common::String &path) const {
diff --git a/backends/fs/psp/psp-fs.cpp b/backends/fs/psp/psp-fs.cpp
index f5ff65c9fa..03247e86ad 100644
--- a/backends/fs/psp/psp-fs.cpp
+++ b/backends/fs/psp/psp-fs.cpp
@@ -26,7 +26,8 @@
#include "engines/engine.h"
#include "backends/fs/abstract-fs.h"
-#include "backends/fs/stdiostream.h"
+#include "backends/fs/psp/psp-stream.h"
+#include "backends/platform/psp/powerman.h"
#include <sys/stat.h>
#include <unistd.h>
@@ -35,6 +36,9 @@
#define ROOT_PATH "ms0:/"
+#include "backends/platform/psp/trace.h"
+
+
/**
* Implementation of the ScummVM file system API based on PSPSDK API.
*
@@ -61,13 +65,13 @@ public:
*/
PSPFilesystemNode(const Common::String &p, bool verify = true);
- virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; }
+ virtual bool exists() const;
virtual Common::String getDisplayName() const { return _displayName; }
virtual Common::String getName() const { return _displayName; }
virtual Common::String getPath() const { return _path; }
virtual bool isDirectory() const { return _isDirectory; }
- virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; }
- virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; }
+ virtual bool isReadable() const;
+ virtual bool isWritable() const;
virtual AbstractFSNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
@@ -94,11 +98,44 @@ PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) {
if (verify) {
struct stat st;
+ PowerMan.beginCriticalSection();
_isValid = (0 == stat(_path.c_str(), &st));
+ PowerMan.endCriticalSection();
_isDirectory = S_ISDIR(st.st_mode);
}
}
+bool PSPFilesystemNode::exists() const {
+ int ret = 0;
+
+ PowerMan.beginCriticalSection(); // Make sure to block in case of suspend
+ ret = access(_path.c_str(), F_OK);
+ PowerMan.endCriticalSection();
+
+ return ret == 0;
+}
+
+bool PSPFilesystemNode::isReadable() const {
+ int ret = 0;
+
+ PowerMan.beginCriticalSection(); // Make sure to block in case of suspend
+ ret = access(_path.c_str(), R_OK);
+ PowerMan.endCriticalSection();
+
+ return ret == 0;
+}
+
+bool PSPFilesystemNode::isWritable() const {
+ int ret = 0;
+
+ PowerMan.beginCriticalSection(); // Make sure to block in case of suspend
+ ret = access(_path.c_str(), W_OK);
+ PowerMan.endCriticalSection();
+
+ return ret == 0;
+}
+
+
AbstractFSNode *PSPFilesystemNode::getChild(const Common::String &n) const {
// FIXME: Pretty lame implementation! We do no error checking to speak
// of, do not check if this is a special node, etc.
@@ -117,6 +154,10 @@ bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool
//TODO: honor the hidden flag
+ bool ret = true;
+
+ PowerMan.beginCriticalSection(); // Make sure to block in case of suspend
+
int dfd = sceIoDopen(_path.c_str());
if (dfd > 0) {
SceIoDirent dir;
@@ -149,10 +190,13 @@ bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool
}
sceIoDclose(dfd);
- return true;
- } else {
- return false;
+ ret = true;
+ } else { // dfd <= 0
+ ret = false;
}
+
+ PowerMan.endCriticalSection();
+ return ret;
}
AbstractFSNode *PSPFilesystemNode::getParent() const {
@@ -166,11 +210,11 @@ AbstractFSNode *PSPFilesystemNode::getParent() const {
}
Common::SeekableReadStream *PSPFilesystemNode::createReadStream() {
- return StdioStream::makeFromPath(getPath().c_str(), false);
+ return PSPIoStream::makeFromPath(getPath(), false);
}
Common::WriteStream *PSPFilesystemNode::createWriteStream() {
- return StdioStream::makeFromPath(getPath().c_str(), true);
+ return PSPIoStream::makeFromPath(getPath(), true);
}
#endif //#ifdef __PSP__
diff --git a/backends/fs/psp/psp-stream.cpp b/backends/fs/psp/psp-stream.cpp
new file mode 100644
index 0000000000..fac4067f46
--- /dev/null
+++ b/backends/fs/psp/psp-stream.cpp
@@ -0,0 +1,230 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+#ifdef __PSP__
+
+#include "backends/fs/psp/psp-stream.h"
+#include "backends/platform/psp/trace.h"
+#include <errno.h>
+
+PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode)
+: StdioStream((void *)1), _path(path), _writeMode(writeMode) {
+
+ assert(!path.empty());
+
+ _handle = (void *)0; // Need to do this since base class asserts not 0.
+
+ PowerMan.registerSuspend(this); // Register with the powermanager to be suspended
+
+}
+
+PSPIoStream::~PSPIoStream() {
+ PowerMan.unregisterSuspend(this); // Unregister with powermanager to be suspended
+ // Must do this before fclose() or resume() will reopen.
+
+ fclose((FILE *)_handle);
+}
+
+// Function to open the file pointed to by the path.
+//
+//
+void * PSPIoStream::open() {
+ if (PowerMan.beginCriticalSection()==PowerManager::Blocked) {
+ // No need to open. Just return the _handle resume() already opened.
+ PSPDebugTrace("Suspended in PSPIoStream::open\n");
+ } else {
+ _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); // open
+ }
+
+ PowerMan.endCriticalSection();
+
+ return _handle;
+}
+
+bool PSPIoStream::err() const {
+ bool ret;
+
+ if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+ PSPDebugTrace("Suspended in PSPIoStream::err()\n");
+
+ ret = ferror((FILE *)_handle) != 0;
+
+ PowerMan.endCriticalSection();
+
+ return ret;
+}
+
+void PSPIoStream::clearErr() {
+ if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+ PSPDebugTrace("Suspended in PSPIoStream::clearErr()\n");
+
+ clearerr((FILE *)_handle);
+
+ PowerMan.endCriticalSection();
+}
+
+bool PSPIoStream::eos() const {
+ bool ret;
+
+ if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+ PSPDebugTrace("Suspended in PSPIoStream::eos()\n");
+
+ ret = feof((FILE *)_handle) != 0;
+
+ PowerMan.endCriticalSection();
+
+ return ret;
+}
+
+int32 PSPIoStream::pos() const {
+ int32 ret;
+
+ if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+ PSPDebugTrace("Suspended in PSPIoStream::pos()\n");
+
+ ret = ftell((FILE *)_handle);
+
+ PowerMan.endCriticalSection();
+
+ return ret;
+}
+
+
+int32 PSPIoStream::size() const {
+ if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+ PSPDebugTrace("Suspended in PSPIoStream::size()\n");
+
+ int32 oldPos = ftell((FILE *)_handle);
+ fseek((FILE *)_handle, 0, SEEK_END);
+ int32 length = ftell((FILE *)_handle);
+ fseek((FILE *)_handle, oldPos, SEEK_SET);
+
+ PowerMan.endCriticalSection();
+
+ return length;
+}
+
+bool PSPIoStream::seek(int32 offs, int whence) {
+ int ret = 0;
+
+ // Check if we can access the file
+ if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+ PSPDebugTrace("Suspended in PSPIoStream::seek()\n");
+
+ ret = fseek((FILE *)_handle, offs, whence);
+
+ PowerMan.endCriticalSection();
+
+ return ret == 0;
+}
+
+uint32 PSPIoStream::read(void *ptr, uint32 len) {
+ int ret = 0;
+
+ // Check if we can access the file
+ if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+ PSPDebugTrace("Suspended in PSPIoStream::read()\n");
+
+ ret = fread((byte *)ptr, 1, len, (FILE *)_handle);
+
+ PowerMan.endCriticalSection();
+
+ return ret;
+}
+
+uint32 PSPIoStream::write(const void *ptr, uint32 len) {
+ int ret = 0;
+
+ // Check if we can access the file
+ if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+ PSPDebugTrace("Suspended in PSPIoStream::read()\n");
+
+ ret = fwrite(ptr, 1, len, (FILE *)_handle);
+
+ PowerMan.endCriticalSection();
+
+ return ret;
+}
+
+bool PSPIoStream::flush() {
+ int ret = 0;
+
+ // Check if we can access the file
+ if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+ PSPDebugTrace("Suspended in PSPIoStream::read()\n");
+
+ ret = fflush((FILE *)_handle);
+
+ PowerMan.endCriticalSection();
+
+ return ret == 0;
+}
+
+// For the PSP, since we're building in suspend support, we moved opening
+// the actual file to an open function since we need an actual PSPIoStream object to suspend.
+//
+PSPIoStream *PSPIoStream::makeFromPath(const Common::String &path, bool writeMode) {
+ PSPIoStream *stream = new PSPIoStream(path, writeMode);
+
+ if (stream->open() > 0) {
+ return stream;
+ } else {
+ delete stream;
+ return 0;
+ }
+}
+
+/*
+ * Function to suspend the IO stream (called by PowerManager)
+ */
+int PSPIoStream::suspend() {
+ if (_handle > 0) {
+ _pos = ftell((FILE *)_handle); // Save our position
+ fclose((FILE *)_handle); // close our file descriptor
+ _handle = 0; // Set handle to null
+ }
+
+ return 0;
+}
+
+/*
+ * Function to resume the IO stream (called by Power Manager)
+ */
+int PSPIoStream::resume() {
+ int ret = 0;
+
+ // We reopen our file descriptor
+ _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb");
+ if (_handle <= 0) {
+ PSPDebugTrace("PSPIoStream::resume(): Couldn't reopen file %s\n", _path.c_str());
+ ret = -1;;
+ }
+
+ // Resume our previous position
+ if(_handle > 0) fseek((FILE *)_handle, _pos, SEEK_SET);
+
+ return ret;
+}
+
+#endif /* __PSP__ */
diff --git a/backends/fs/psp/psp-stream.h b/backends/fs/psp/psp-stream.h
new file mode 100644
index 0000000000..0363c92416
--- /dev/null
+++ b/backends/fs/psp/psp-stream.h
@@ -0,0 +1,70 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef PSPSTREAM_H_
+#define PSPSTREAM_H_
+
+#include "backends/fs/stdiostream.h"
+#include "backends/platform/psp/powerman.h"
+#include "common/list.h"
+
+/*
+ * Class to handle special suspend/resume needs of PSP IO Streams
+ */
+class PSPIoStream : public StdioStream, public Suspendable {
+protected:
+ Common::String _path; /* Need to maintain for reopening after suspend */
+ bool _writeMode; /* "" */
+ unsigned int _pos; /* "" */
+
+public:
+ /**
+ * Given a path, invoke fopen on that path and wrap the result in a
+ * PSPIoStream instance.
+ */
+ static PSPIoStream *makeFromPath(const Common::String &path, bool writeMode);
+
+ PSPIoStream(const Common::String &path, bool writeMode);
+ virtual ~PSPIoStream();
+
+ void * open(); // open the file pointed to by the file path
+
+ bool err() const;
+ void clearErr();
+ bool eos() const;
+
+ virtual uint32 write(const void *dataPtr, uint32 dataSize);
+ virtual bool flush();
+
+ virtual int32 pos() const;
+ virtual int32 size() const;
+ virtual bool seek(int32 offs, int whence = SEEK_SET);
+ virtual uint32 read(void *dataPtr, uint32 dataSize);
+
+ int suspend(); /* Suspendable interface (power manager) */
+ int resume(); /* " " */
+};
+
+#endif /* PSPSTREAM_H_ */
diff --git a/backends/module.mk b/backends/module.mk
index f3294c5dc6..42fbeb07eb 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -11,6 +11,7 @@ MODULE_OBJS := \
fs/posix/posix-fs-factory.o \
fs/ps2/ps2-fs-factory.o \
fs/psp/psp-fs-factory.o \
+ fs/psp/psp-stream.o \
fs/symbian/symbian-fs-factory.o \
fs/windows/windows-fs-factory.o \
fs/wii/wii-fs-factory.o \
diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile
index 91a0c60bd6..d18e6ac82c 100644
--- a/backends/platform/psp/Makefile
+++ b/backends/platform/psp/Makefile
@@ -62,7 +62,7 @@ endif
INCDIR := $(srcdir) . $(srcdir)/engines/ . $(PSPSDK)/include
LIBDIR := $(LIBDIR) . $(PSPSDK)/lib
-CXXFLAGS = -O2 -Wall -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -Wno-multichar `$(PSPBIN)/sdl-config --cflags`
+CXXFLAGS = -O3 -Wall -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -Wno-multichar `$(PSPBIN)/sdl-config --cflags`
CXXFLAGS:= $(addprefix -I,$(INCDIR)) $(CXXFLAGS)
LDFLAGS := $(addprefix -L,$(LIBDIR)) $(LDFLAGS)
LIBS =
@@ -75,12 +75,13 @@ LIBS += -lmad
CXXFLAGS+= -DUSE_VORBIS -DUSE_TREMOR
LIBS += -lvorbisidec
-LIBS += `$(PSPBIN)/sdl-config --libs` -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspsdk -lpspuser
+LIBS += `$(PSPBIN)/sdl-config --libs` -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspuser -lpsppower
CXXFLAGS := $(CXXFLAGS) -fno-exceptions -fno-rtti
TARGET = scummvm-psp
-OBJS := psp_main.o \
+OBJS := powerman.o \
+ psp_main.o \
osys_psp.o \
osys_psp_gu.o \
kbd_ss_c.o \
diff --git a/backends/platform/psp/README.PSP.in b/backends/platform/psp/README.PSP.in
index 2a2b53e721..7eeba7d391 100644
--- a/backends/platform/psp/README.PSP.in
+++ b/backends/platform/psp/README.PSP.in
@@ -13,15 +13,17 @@ Controls
========
Left trigger - ESC
-Right trigger - Enter
+Right trigger - Modifier key (see below for uses)
Analog - Mouse movement
+Right trigger + Analog - Fine control mouse
Directionals - Mouse movement
-Analog + triangle - Fine control mouse
+Triangle - Enter
Cross - Mouse button 1
Circle - Mouse button 2
Square - '.' (skip dialogue in some games)
Select - Show/Hide Virtual Keyboard
Start - F5
+Right trigger + Start - Return-To-Launcher menu
Notes
=====
@@ -32,9 +34,6 @@ Notes
As such, it is recommended to play games in their original, uncompressed,
form whenever possible.
-- Sleep/Suspend mode currently isn't supported, so don't use it when
- running ScummVM.
-
- This README may be outdated, for more up-to-date instructions and notes see
the PSP Port Wiki: http://wiki.scummvm.org/index.php/PlayStation_Portable
diff --git a/backends/platform/psp/module.mk b/backends/platform/psp/module.mk
index afe9a23f58..8f083c5dfa 100644
--- a/backends/platform/psp/module.mk
+++ b/backends/platform/psp/module.mk
@@ -1,6 +1,7 @@
MODULE := backends/platform/psp
MODULE_OBJS := \
+ powerman.o \
psp_main.o \
osys_psp.o \
osys_psp_gu.o \
diff --git a/backends/platform/psp/osys_psp.cpp b/backends/platform/psp/osys_psp.cpp
index 45be0a0cd3..566db3014b 100644
--- a/backends/platform/psp/osys_psp.cpp
+++ b/backends/platform/psp/osys_psp.cpp
@@ -79,6 +79,8 @@ OSystem_PSP::OSystem_PSP() : _screenWidth(0), _screenHeight(0), _overlayWidth(0)
memset(_palette, 0, sizeof(_palette));
+ _cursorPaletteDisabled = true;
+
_samplesPerSec = 0;
//init SDL
@@ -110,14 +112,14 @@ void OSystem_PSP::initBackend() {
bool OSystem_PSP::hasFeature(Feature f) {
- return false;
+ return (f == kFeatureOverlaySupportsAlpha || f == kFeatureCursorHasPalette);
}
void OSystem_PSP::setFeatureState(Feature f, bool enable) {
}
bool OSystem_PSP::getFeatureState(Feature f) {
- return (f == kFeatureOverlaySupportsAlpha);
+ return false;
}
const OSystem::GraphicsMode* OSystem_PSP::getSupportedGraphicsModes() const {
@@ -411,7 +413,7 @@ bool OSystem_PSP::pollEvent(Common::Event &event) {
*/
uint32 buttonsChanged = pad.Buttons ^ _prevButtons;
- if (buttonsChanged & (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_START | PSP_CTRL_SELECT | PSP_CTRL_SQUARE)) {
+ if (buttonsChanged & (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_START | PSP_CTRL_SELECT | PSP_CTRL_SQUARE | PSP_CTRL_TRIANGLE)) {
if (buttonsChanged & PSP_CTRL_CROSS) {
event.type = (pad.Buttons & PSP_CTRL_CROSS) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP;
} else if (buttonsChanged & PSP_CTRL_CIRCLE) {
@@ -419,23 +421,29 @@ bool OSystem_PSP::pollEvent(Common::Event &event) {
} else {
//any of the other buttons.
event.type = buttonsChanged & pad.Buttons ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
+ event.kbd.ascii = 0;
event.kbd.flags = 0;
if (buttonsChanged & PSP_CTRL_LTRIGGER) {
event.kbd.keycode = Common::KEYCODE_ESCAPE;
event.kbd.ascii = 27;
- } else if (buttonsChanged & PSP_CTRL_RTRIGGER) {
- event.kbd.keycode = Common::KEYCODE_RETURN;
- event.kbd.ascii = 13;
} else if (buttonsChanged & PSP_CTRL_START) {
event.kbd.keycode = Common::KEYCODE_F5;
event.kbd.ascii = Common::ASCII_F5;
+ if (pad.Buttons & PSP_CTRL_RTRIGGER) {
+ event.kbd.flags = Common::KBD_CTRL; // Main menu to allow RTL
+ }
/* } else if (buttonsChanged & PSP_CTRL_SELECT) {
event.kbd.keycode = Common::KEYCODE_0;
event.kbd.ascii = '0';
*/ } else if (buttonsChanged & PSP_CTRL_SQUARE) {
event.kbd.keycode = Common::KEYCODE_PERIOD;
event.kbd.ascii = '.';
+ } else if (buttonsChanged & PSP_CTRL_TRIANGLE) {
+ event.kbd.keycode = Common::KEYCODE_RETURN;
+ event.kbd.ascii = 13;
+ } else if (pad.Buttons & PSP_CTRL_RTRIGGER) {
+ event.kbd.flags |= Common::KBD_SHIFT;
}
}
@@ -484,7 +492,7 @@ bool OSystem_PSP::pollEvent(Common::Event &event) {
newY += _padAccel >> 2;
// If no movement then this has no effect
- if (pad.Buttons & PSP_CTRL_TRIANGLE) {
+ if (pad.Buttons & PSP_CTRL_RTRIGGER) {
// Fine control mode for analog
if (analogStepAmountX != 0) {
if (analogStepAmountX > 0)
diff --git a/backends/platform/psp/osys_psp.h b/backends/platform/psp/osys_psp.h
index 34957b293c..310efdc7d4 100644
--- a/backends/platform/psp/osys_psp.h
+++ b/backends/platform/psp/osys_psp.h
@@ -23,6 +23,9 @@
*
*/
+#ifndef OSYS_PSP_H
+#define OSYS_PSP_H
+
#include "common/scummsys.h"
#include "graphics/surface.h"
#include "graphics/colormasks.h"
@@ -65,6 +68,7 @@ protected:
int _mouseHotspotX, _mouseHotspotY;
byte _mouseKeyColour;
byte *_mouseBuf;
+ bool _cursorPaletteDisabled;
uint32 _prevButtons;
uint32 _lastPadCheck;
@@ -144,3 +148,5 @@ public:
virtual Common::WriteStream *createConfigWriteStream();
};
+
+#endif /* OSYS_PSP_H */
diff --git a/backends/platform/psp/osys_psp_gu.cpp b/backends/platform/psp/osys_psp_gu.cpp
index 76f6b42e37..0fb1b4aded 100644
--- a/backends/platform/psp/osys_psp_gu.cpp
+++ b/backends/platform/psp/osys_psp_gu.cpp
@@ -41,6 +41,7 @@
unsigned int __attribute__((aligned(16))) list[262144];
unsigned short __attribute__((aligned(16))) clut256[256];
unsigned short __attribute__((aligned(16))) mouseClut[256];
+unsigned short __attribute__((aligned(16))) cursorPalette[256];
unsigned short __attribute__((aligned(16))) kbClut[256];
//unsigned int __attribute__((aligned(16))) offscreen256[640*480];
//unsigned int __attribute__((aligned(16))) overlayBuffer256[640*480*2];
@@ -225,6 +226,24 @@ void OSystem_PSP_GU::setPalette(const byte *colors, uint start, uint num) {
sceKernelDcacheWritebackAll();
}
+void OSystem_PSP_GU::setCursorPalette(const byte *colors, uint start, uint num) {
+ const byte *b = colors;
+
+ for (uint i = 0; i < num; ++i) {
+ cursorPalette[start + i] = RGBToColour(b[0], b[1], b[2]);
+ b += 4;
+ }
+
+ cursorPalette[0] = 0;
+
+ _cursorPaletteDisabled = false;
+
+ sceKernelDcacheWritebackAll();
+}
+
+void OSystem_PSP_GU::disableCursorPalette(bool disable) {
+ _cursorPaletteDisabled = disable;
+}
void OSystem_PSP_GU::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
//Clip the coordinates
@@ -364,7 +383,7 @@ void OSystem_PSP_GU::updateScreen() {
if (_mouseVisible) {
sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image
sceGuClutMode(GU_PSM_5551, 0, 0xff, 0);
- sceGuClutLoad(32, mouseClut); // upload 32*8 entries (256)
+ sceGuClutLoad(32, _cursorPaletteDisabled ? mouseClut : cursorPalette); // upload 32*8 entries (256)
sceGuAlphaFunc(GU_GREATER,0,0xff);
sceGuEnable(GU_ALPHA_TEST);
sceGuTexImage(0, MOUSE_SIZE, MOUSE_SIZE, MOUSE_SIZE, _mouseBuf);
diff --git a/backends/platform/psp/osys_psp_gu.h b/backends/platform/psp/osys_psp_gu.h
index e828a36b7d..c221971fc8 100644
--- a/backends/platform/psp/osys_psp_gu.h
+++ b/backends/platform/psp/osys_psp_gu.h
@@ -47,6 +47,8 @@ public:
void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale);
void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) ;
void setPalette(const byte *colors, uint start, uint num);
+ void setCursorPalette(const byte *colors, uint start, uint num);
+ void disableCursorPalette(bool disable);
bool pollEvent(Common::Event &event);
int _graphicMode;
struct Vertex *_vertices;
diff --git a/backends/platform/psp/powerman.cpp b/backends/platform/psp/powerman.cpp
new file mode 100644
index 0000000000..c553669fc3
--- /dev/null
+++ b/backends/platform/psp/powerman.cpp
@@ -0,0 +1,297 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "./powerman.h"
+#include "./trace.h"
+
+DECLARE_SINGLETON(PowerManager);
+
+ /*******************************************
+*
+* Constructor
+*
+********************************************/
+PowerManager::PowerManager() {
+ _flagMutex = NULL; /* Init mutex handle */
+ _listMutex = NULL; /* Init mutex handle */
+ _condSuspendable = NULL; /* Init condition variable */
+ _condPM = NULL;
+
+ _condSuspendable = SDL_CreateCond();
+ if (_condSuspendable <= 0) {
+ PSPDebugTrace("PowerManager::PowerManager(): Couldn't create condSuspendable\n");
+ }
+
+ _condPM = SDL_CreateCond();
+ if (_condPM <= 0) {
+ PSPDebugTrace("PowerManager::PowerManager(): Couldn't create condPM\n");
+ }
+
+ _flagMutex = SDL_CreateMutex();
+ if (_flagMutex <= 0) {
+ PSPDebugTrace("PowerManager::PowerManager(): Couldn't create flagMutex\n");
+ }
+
+ _listMutex = SDL_CreateMutex();
+ if (_listMutex <= 0) {
+ PSPDebugTrace("PowerManager::PowerManager(): Couldn't create listMutex\n");
+ }
+
+ _suspendFlag = false;
+ _criticalCounter = 0;
+ }
+
+/*******************************************
+*
+* Function to register to be notified when suspend/resume time comes
+*
+********************************************/
+int PowerManager::registerSuspend(Suspendable *item) {
+ // Register in list
+ PSPDebugTrace("In registerSuspend\n");
+
+ if (SDL_mutexP(_listMutex) != 0) {
+ PSPDebugTrace("PowerManager::registerSuspend(): Couldn't lock _listMutex %d\n", _listMutex);
+ }
+
+ _suspendList.push_front(item);
+
+ if (SDL_mutexV(_listMutex) != 0) {
+ PSPDebugTrace("PowerManager::registerSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
+ }
+
+ PSPDebugTrace("Out of registerSuspend\n");
+
+ return 0;
+}
+
+/*******************************************
+*
+* Function to unregister to be notified when suspend/resume time comes
+*
+********************************************/
+int PowerManager::unregisterSuspend(Suspendable *item) {
+
+ PSPDebugTrace("In unregisterSuspend\n");
+
+ // Unregister from stream list
+ if (SDL_mutexP(_listMutex) != 0) {
+ PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
+ }
+
+ _suspendList.remove(item);
+
+ if (SDL_mutexV(_listMutex) != 0) {
+ PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
+ }
+
+ PSPDebugTrace("Out of unregisterSuspend\n");
+
+ return 0;
+ }
+
+ /*******************************************
+*
+* Destructor
+*
+********************************************/
+ PowerManager::~PowerManager() {
+ SDL_DestroyCond(_condSuspendable);
+ _condSuspendable = 0;
+
+ SDL_DestroyCond(_condPM);
+ _condPM = 0;
+
+ SDL_DestroyMutex(_flagMutex);
+ _flagMutex = 0;
+
+ SDL_DestroyMutex(_listMutex);
+ _listMutex = 0;
+ }
+
+
+ /*******************************************
+*
+* Function to be called by threads wanting to block on the PSP entering suspend
+*
+********************************************/
+ int PowerManager::blockOnSuspend() {
+ return beginCriticalSection(true);
+}
+
+ /*
+ * Function to block on a suspend, then start a non-suspendable critical section
+ */
+int PowerManager::beginCriticalSection(bool justBlock) {
+ int ret = PowerManager::NotBlocked;
+
+ if (SDL_mutexP(_flagMutex) != 0) {
+ PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't lock flagMutex %d\n", _flagMutex);
+ ret = PowerManager::Error;
+ }
+
+ // Check the access flag
+ if (_suspendFlag == true) {
+ PSPDebugTrace("Blocking!!\n");
+ ret = PowerManager::Blocked;
+
+ // If it's true, we wait for a signal to continue
+ if( SDL_CondWait(_condSuspendable, _flagMutex) != 0) {
+ PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't wait on cond %d\n", _condSuspendable);
+ }
+
+ PSPDebugTrace("We got blocked!!\n");
+ }
+
+ // Now put the pm to sleep
+ if (justBlock == false)
+ _criticalCounter++;
+
+ if (SDL_mutexV(_flagMutex) != 0) {
+ PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
+ ret = PowerManager::Error;
+ }
+
+ return ret;
+}
+
+int PowerManager::endCriticalSection() {
+ int ret = 0;
+
+ if (SDL_mutexP(_flagMutex) != 0) {
+ PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't lock flagMutex %d\n", _flagMutex);
+ ret = PowerManager::Error;
+ }
+
+ // We're done with our critical section
+ _criticalCounter--;
+
+ if (_criticalCounter <= 0) {
+ if(_suspendFlag == true) PSPDebugTrace("Waking up the PM and suspendFlag is true\n");
+
+ SDL_CondBroadcast(_condPM);
+
+ if (_criticalCounter < 0) {
+ PSPDebugTrace("PowerManager::endCriticalSection(): Error! Critical counter is %d\n", _criticalCounter);
+ }
+ }
+
+ if (SDL_mutexV(_flagMutex) != 0) {
+ PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't unlock flagMutex %d\n", _flagMutex);
+ ret = PowerManager::Error;
+ }
+
+ return ret;
+}
+
+ /*******************************************
+*
+* Callback function to be called to put every Suspendable to suspend
+*
+********************************************/
+int PowerManager::suspend() {
+ int ret = 0;
+
+ // First we set the suspend flag to true
+ if (SDL_mutexP(_flagMutex) != 0) {
+ PSPDebugTrace("PowerManager::suspend(): Couldn't lock flagMutex %d\n", _flagMutex);
+ ret = -1;
+ }
+
+ _suspendFlag = true;
+
+ if (_criticalCounter > 0)
+ SDL_CondWait(_condPM, _flagMutex);
+
+ if (SDL_mutexV(_flagMutex) != 0) {
+ PSPDebugTrace("PowerManager::suspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
+ ret = -1;
+ }
+
+ // Loop over list, calling suspend()
+ if (SDL_mutexP(_listMutex) != 0) {
+ PSPDebugTrace("PowerManager::suspend(): Couldn't lock listMutex %d\n", _listMutex);
+ ret = -1;
+ }
+
+ Common::List<Suspendable *>::iterator i = _suspendList.begin();
+
+ for (; i != _suspendList.end(); i++) {
+ (*i)->suspend();
+ }
+
+ if (SDL_mutexV(_listMutex) != 0) {
+ PSPDebugTrace("PowerManager::suspend(): Couldn't unlock listMutex %d\n", _listMutex);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+/*******************************************
+*
+* Callback function to resume every Suspendable
+*
+********************************************/
+int PowerManager::resume() {
+ int ret = 0;
+
+ // First we notify our Suspendables. Loop over list, calling resume()
+ if (SDL_mutexP(_listMutex) != 0) {
+ PSPDebugTrace("PowerManager::resume(): Couldn't lock listMutex %d\n", _listMutex);
+ ret = -1;
+ }
+
+ Common::List<Suspendable *>::iterator i = _suspendList.begin();
+
+ for (; i != _suspendList.end(); i++) {
+ (*i)->resume();
+ }
+
+ if (SDL_mutexV(_listMutex) != 0) {
+ PSPDebugTrace("PowerManager::resume(): Couldn't unlock listMutex %d\n", _listMutex);
+ ret = -1;
+ }
+
+ // Now we set the suspend flag to false
+ if (SDL_mutexP(_flagMutex) != 0) {
+ PSPDebugTrace("PowerManager::resume(): Couldn't lock flagMutex %d\n", _flagMutex);
+ ret = -1;
+ }
+ _suspendFlag = false;
+
+ // Signal the other threads to wake up
+ if (SDL_CondBroadcast(_condSuspendable) != 0) {
+ PSPDebugTrace("PowerManager::resume(): Couldn't broadcast condition %d\n", _condSuspendable);
+ ret = -1;
+ }
+
+ if (SDL_mutexV(_flagMutex) != 0) {
+ PSPDebugTrace("PowerManager::resume(): Couldn't unlock flagMutex %d\n", _flagMutex);
+ ret = -1;
+ }
+
+ return ret;
+}
diff --git a/backends/platform/psp/powerman.h b/backends/platform/psp/powerman.h
new file mode 100644
index 0000000000..0a5f7a2361
--- /dev/null
+++ b/backends/platform/psp/powerman.h
@@ -0,0 +1,87 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef POWERMAN_H
+#define POWERMAN_H
+
+#include <SDL/SDL_thread.h>
+#include <SDL/SDL_mutex.h>
+#include "common/singleton.h"
+#include "common/list.h"
+
+ /*
+ * Implement this class (interface) if you want to use PowerManager's suspend callback functionality
+ *
+ */
+ class Suspendable {
+ public:
+ virtual ~Suspendable() {}
+ virtual int suspend() = 0;
+ virtual int resume() = 0;
+ };
+
+ /******************************************************************************************************
+ *
+ * This class will call a Suspendable when the PSP goes to suspend/resumes. It also provides the ability to block
+ * a thread when the PSP is going to suspend/suspending, and to wake it up when the PSP is resumed.
+ * This ability is very useful for managing the PSPIoStream class, but may be found useful by other classes as well.
+ *
+ *******************************************************************************************************/
+ class PowerManager: public Common::Singleton<PowerManager> {
+private:
+ friend class Common::Singleton<PowerManager>;
+ PowerManager();
+ ~PowerManager();
+
+ Common::List<Suspendable *> _suspendList; /* list to register in */
+
+ bool _suspendFlag; /* protected variable */
+ SDL_mutex *_flagMutex; /* mutex to access access flag */
+ SDL_mutex *_listMutex; /* mutex to access Suspendable list */
+ SDL_cond *_condSuspendable; /* signal to synchronize accessing threads */
+ SDL_cond *_condPM; /* signal to wake up the PM from a critical section */
+ int _criticalCounter; /* Counter of how many threads are in a critical section */
+
+public:
+ int blockOnSuspend(); /* block if suspending */
+ int beginCriticalSection(bool justBlock = false); /* Use a critical section to block (if suspend was already pressed) */
+ int endCriticalSection(); /* and to prevent the PSP from suspending in a particular section */
+ int registerSuspend(Suspendable *item); /* register to be called to suspend/resume */
+ int unregisterSuspend(Suspendable *item); /* remove from suspend/resume list */
+ int suspend(); /* callback to have all items in list suspend */
+ int resume(); /* callback to have all items in list resume */
+
+ enum {
+ Error = -1,
+ NotBlocked = 0,
+ Blocked = 1
+ };
+
+ };
+
+ // For easy access
+#define PowerMan PowerManager::instance()
+
+ #endif /* POWERMAN_H */
diff --git a/backends/platform/psp/psp.spec b/backends/platform/psp/psp.spec
index 807b8f93b7..e319b022f7 100644
--- a/backends/platform/psp/psp.spec
+++ b/backends/platform/psp/psp.spec
@@ -1,3 +1,3 @@
%rename lib old_lib
*lib:
-%(old_lib) -lpspdebug -lpspgu -lpspctrl -lpspge -lpspdisplay -lpsphprm -lpspsdk -lpsprtc -lpspaudio -lc -lpspuser -lpsputility -lpspkernel -lpspnet_inet -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspsdk -lpspuser
+%(old_lib) -lpspdebug -lpspgu -lpspctrl -lpspge -lpspdisplay -lpsphprm -lpspsdk -lpsprtc -lpspaudio -lc -lpspuser -lpsputility -lpspkernel -lpspnet_inet -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspuser -lpsppower
diff --git a/backends/platform/psp/psp_main.cpp b/backends/platform/psp/psp_main.cpp
index 0af7ebf269..3ea6c55368 100644
--- a/backends/platform/psp/psp_main.cpp
+++ b/backends/platform/psp/psp_main.cpp
@@ -31,10 +31,14 @@
#include <pspdebug.h>
#endif
+#include <psppower.h>
+
#include <common/system.h>
#include <engines/engine.h>
#include <base/main.h>
#include <base/plugins.h>
+#include "backends/platform/psp/powerman.h"
+
#include "osys_psp_gu.h"
#include "./trace.h"
@@ -91,17 +95,36 @@ void loaderInit() {
#endif
/* Exit callback */
-SceKernelCallbackFunction exit_callback(int /*arg1*/, int /*arg2*/, void * /*common*/) {
+int exit_callback(void) {
sceKernelExitGame();
return 0;
}
+/* Function for handling suspend/resume */
+void power_callback(int , int powerinfo) {
+ if (powerinfo & PSP_POWER_CB_POWER_SWITCH || powerinfo & PSP_POWER_CB_SUSPENDING) {
+ PowerMan.suspend();
+ } else if (powerinfo & PSP_POWER_CB_RESUME_COMPLETE) {
+ PowerMan.resume();
+ }
+}
+
/* Callback thread */
int CallbackThread(SceSize /*size*/, void *arg) {
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", (SceKernelCallbackFunction)exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
+ /* Set up callbacks for PSPIoStream */
+
+ cbid = sceKernelCreateCallback("Power Callback", (SceKernelCallbackFunction)power_callback, 0);
+ if (cbid >= 0) {
+ if(scePowerRegisterCallback(-1, cbid) < 0) {
+ PSPDebugTrace("SetupCallbacks(): Couldn't register callback for power_callback\n");
+ }
+ } else {
+ PSPDebugTrace("SetupCallbacks(): Couldn't create a callback for power_callback\n");
+ }
sceKernelSleepThreadCB();
return 0;
@@ -119,8 +142,13 @@ int SetupCallbacks(void) {
#undef main
int main(void) {
+ PowerManager::instance(); // Setup power manager
+
SetupCallbacks();
+ //change clock rate to 333mhz
+ scePowerSetClockFrequency(333, 333, 166);
+
static const char *argv[] = { "scummvm", NULL };
static int argc = sizeof(argv)/sizeof(char *)-1;
@@ -131,6 +159,8 @@ int main(void) {
g_system->quit(); // TODO: Consider removing / replacing this!
+ PowerManager::destroy(); // get rid of PowerManager
+
sceKernelSleepThread();
return res;