PSP: refactoring/redesign of the backend
svn-id: r48632
This commit is contained in:
parent
18609a70b3
commit
9a2eac7eee
32 changed files with 4458 additions and 1611 deletions
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
class PSPFilesystemFactory : public FilesystemFactory, public Common::Singleton<PSPFilesystemFactory> {
|
||||
public:
|
||||
const char *getObjectName() const { return "PSPFilesystemFactory"; }
|
||||
virtual AbstractFSNode *makeRootFileNode() const;
|
||||
virtual AbstractFSNode *makeCurrentDirectoryFileNode() const;
|
||||
virtual AbstractFSNode *makeFileNodePath(const Common::String &path) const;
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
|
||||
#define ROOT_PATH "ms0:/"
|
||||
|
||||
//#define __PSP_PRINT_TO_FILE__
|
||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
|
||||
//#define __PSP_DEBUG_PRINT__ /* For debug printouts */
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
/**
|
||||
|
@ -63,6 +66,7 @@ public:
|
|||
*/
|
||||
PSPFilesystemNode(const Common::String &p, bool verify = true);
|
||||
|
||||
const char *getObjectName() const { return "PSPFileSystemNode"; }
|
||||
virtual bool exists() const;
|
||||
virtual Common::String getDisplayName() const { return _displayName; }
|
||||
virtual Common::String getName() const { return _displayName; }
|
||||
|
@ -87,6 +91,7 @@ PSPFilesystemNode::PSPFilesystemNode() {
|
|||
}
|
||||
|
||||
PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
assert(p.size() > 0);
|
||||
|
||||
_path = p;
|
||||
|
@ -94,54 +99,70 @@ PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) {
|
|||
_isValid = true;
|
||||
_isDirectory = true;
|
||||
|
||||
PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str());
|
||||
|
||||
if (verify) {
|
||||
struct stat st;
|
||||
if (PowerMan.beginCriticalSection()==PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPFilesystemNode::PSPFilesystemNode\n");
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n");
|
||||
_isValid = (0 == stat(_path.c_str(), &st));
|
||||
PowerMan.endCriticalSection();
|
||||
_isDirectory = S_ISDIR(st.st_mode);
|
||||
}
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
bool PSPFilesystemNode::exists() const {
|
||||
DEBUG_ENTER_FUNC();
|
||||
int ret = 0;
|
||||
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPFilesystemNode::exists()\n"); // Make sure to block in case of suspend
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend
|
||||
|
||||
PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str());
|
||||
|
||||
ret = access(_path.c_str(), F_OK);
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
return ret == 0;
|
||||
DEBUG_EXIT_FUNC();
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
bool PSPFilesystemNode::isReadable() const {
|
||||
DEBUG_ENTER_FUNC();
|
||||
int ret = 0;
|
||||
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPFilesystemNode::isReadable()\n"); // Make sure to block in case of suspend
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend
|
||||
|
||||
PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str());
|
||||
|
||||
ret = access(_path.c_str(), R_OK);
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
return ret == 0;
|
||||
DEBUG_EXIT_FUNC();
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
bool PSPFilesystemNode::isWritable() const {
|
||||
DEBUG_ENTER_FUNC();
|
||||
int ret = 0;
|
||||
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPFilesystemNode::isWritable()\n"); // Make sure to block in case of suspend
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend
|
||||
|
||||
PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str());
|
||||
|
||||
ret = access(_path.c_str(), W_OK);
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
|
||||
AbstractFSNode *PSPFilesystemNode::getChild(const Common::String &n) const {
|
||||
DEBUG_ENTER_FUNC();
|
||||
// FIXME: Pretty lame implementation! We do no error checking to speak
|
||||
// of, do not check if this is a special node, etc.
|
||||
assert(_isDirectory);
|
||||
|
@ -151,10 +172,16 @@ AbstractFSNode *PSPFilesystemNode::getChild(const Common::String &n) const {
|
|||
newPath += '/';
|
||||
newPath += n;
|
||||
|
||||
return new PSPFilesystemNode(newPath, true);
|
||||
PSP_DEBUG_PRINT_FUNC("child [%s]\n", newPath.c_str());
|
||||
|
||||
AbstractFSNode *node = new PSPFilesystemNode(newPath, true);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return node;
|
||||
}
|
||||
|
||||
bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
|
||||
DEBUG_ENTER_FUNC();
|
||||
assert(_isDirectory);
|
||||
|
||||
//TODO: honor the hidden flag
|
||||
|
@ -162,8 +189,10 @@ bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool
|
|||
bool ret = true;
|
||||
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPFilesystemNode::getChildren\n"); // Make sure to block in case of suspend
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend
|
||||
|
||||
PSP_DEBUG_PRINT_FUNC("Current path[%s]\n", _path.c_str());
|
||||
|
||||
int dfd = sceIoDopen(_path.c_str());
|
||||
if (dfd > 0) {
|
||||
SceIoDirent dir;
|
||||
|
@ -186,7 +215,9 @@ bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool
|
|||
|
||||
entry._path = newPath;
|
||||
entry._isDirectory = dir.d_stat.st_attr & FIO_SO_IFDIR;
|
||||
|
||||
|
||||
PSP_DEBUG_PRINT_FUNC("Child[%s], %s\n", entry._path.c_str(), entry._isDirectory ? "dir" : "file");
|
||||
|
||||
// Honor the chosen mode
|
||||
if ((mode == Common::FSNode::kListFilesOnly && entry._isDirectory) ||
|
||||
(mode == Common::FSNode::kListDirectoriesOnly && !entry._isDirectory))
|
||||
|
@ -202,17 +233,24 @@ bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool
|
|||
}
|
||||
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret;
|
||||
}
|
||||
|
||||
AbstractFSNode *PSPFilesystemNode::getParent() const {
|
||||
DEBUG_ENTER_FUNC();
|
||||
if (_path == ROOT_PATH)
|
||||
return 0;
|
||||
|
||||
PSP_DEBUG_PRINT_FUNC("current[%s]\n", _path.c_str());
|
||||
|
||||
const char *start = _path.c_str();
|
||||
const char *end = lastPathComponent(_path, '/');
|
||||
|
||||
return new PSPFilesystemNode(Common::String(start, end - start), false);
|
||||
AbstractFSNode *node = new PSPFilesystemNode(Common::String(start, end - start), false);
|
||||
DEBUG_EXIT_FUNC();
|
||||
return node;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *PSPFilesystemNode::createReadStream() {
|
||||
|
|
|
@ -27,15 +27,20 @@
|
|||
#include <SDL/SDL_thread.h>
|
||||
#include <SDL/SDL_mutex.h>
|
||||
|
||||
#include "backends/platform/psp/trace.h"
|
||||
#include "backends/platform/psp/powerman.h"
|
||||
#include "backends/fs/psp/psp-stream.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
//#define __PSP_PRINT_TO_FILE__
|
||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
|
||||
//#define __PSP_DEBUG_PRINT__ /* For debug printouts */
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode)
|
||||
: StdioStream((void *)1), _path(path), _writeMode(writeMode) {
|
||||
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
assert(!path.empty());
|
||||
|
||||
_handle = (void *)0; // Need to do this since base class asserts not 0.
|
||||
|
@ -43,34 +48,40 @@ PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode)
|
|||
_feof = false;
|
||||
_pos = 0;
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
/* for error checking */
|
||||
_errorSuspend = 0;
|
||||
_errorSource = 0;
|
||||
_errorPos = 0;
|
||||
_errorHandle = 0;
|
||||
_suspendCount = 0;
|
||||
#endif
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
PSPIoStream::~PSPIoStream() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPIoStream::~PSPIoStream()\n");
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n");
|
||||
|
||||
PowerMan.unregisterSuspend(this); // Unregister with powermanager to be suspended
|
||||
// Must do this before fclose() or resume() will reopen.
|
||||
// Must do this before fclose() or resume() will reopen.
|
||||
|
||||
fclose((FILE *)_handle); // We don't need a critical section(?). Worst case, the handle gets closed on its own
|
||||
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Function to open the file pointed to by the path.
|
||||
//
|
||||
//
|
||||
/* Function to open the file pointed to by the path.
|
||||
*
|
||||
*/
|
||||
void *PSPIoStream::open() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked) {
|
||||
// No need to open. Just return the _handle resume() already opened.
|
||||
PSPDebugSuspend("Suspended in PSPIoStream::open\n");
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n");
|
||||
}
|
||||
|
||||
_handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); // open
|
||||
|
@ -79,20 +90,22 @@ void *PSPIoStream::open() {
|
|||
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return _handle;
|
||||
}
|
||||
|
||||
bool PSPIoStream::err() const {
|
||||
DEBUG_ENTER_FUNC();
|
||||
if (_ferror)
|
||||
PSPDebugSuspend("In PSPIoStream::err - mem_ferror=%d, source=%d, suspend error=%d, pos=%d, _errorPos=%d, _errorHandle=%p, suspendCount=%d _handle\n",
|
||||
PSP_ERROR("mem_ferror[%d], source[%d], suspend error[%d], pos[%d], _errorPos[%d], _errorHandle[%p], suspendCount[%d]\n",
|
||||
_ferror, _errorSource, _errorSuspend, _pos, _errorPos, _errorHandle, _suspendCount);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return _ferror;
|
||||
}
|
||||
|
||||
void PSPIoStream::clearErr() {
|
||||
_ferror = false; // Remove regular error bit
|
||||
|
||||
}
|
||||
|
||||
bool PSPIoStream::eos() const {
|
||||
|
@ -105,45 +118,43 @@ int32 PSPIoStream::pos() const {
|
|||
|
||||
|
||||
int32 PSPIoStream::size() const {
|
||||
DEBUG_ENTER_FUNC();
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPIoStream::size()\n");
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n");
|
||||
|
||||
fseek((FILE *)_handle, 0, SEEK_END);
|
||||
int32 length = ftell((FILE *)_handle);
|
||||
fseek((FILE *)_handle, _pos, SEEK_SET);
|
||||
|
||||
if (_pos < 0 || length < 0) { // Check for errors
|
||||
PSPDebugSuspend("In PSPIoStream::size(). encountered an error!\n");
|
||||
_errorSource = 2;
|
||||
PSP_ERROR("pos[%d] or length[%d] < 0!\n", _pos, length);
|
||||
_ferror = true;
|
||||
length = -1; // If our oldPos is bad, we want length to be bad too to signal
|
||||
clearerr((FILE *)_handle);
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
_errorSource = 2;
|
||||
#endif
|
||||
}
|
||||
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return length;
|
||||
}
|
||||
|
||||
bool PSPIoStream::seek(int32 offs, int whence) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
// Check if we can access the file
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPIoStream::seek()\n");
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n");
|
||||
|
||||
int ret = fseek((FILE *)_handle, offs, whence);
|
||||
|
||||
if (ret != 0) {
|
||||
_ferror = true;
|
||||
PSPDebugSuspend("In PSPIoStream::seek(). encountered an error!\n");
|
||||
PSP_ERROR("fseek returned with [%d], non-zero\n", ret);
|
||||
clearerr((FILE *)_handle);
|
||||
_feof = feof((FILE *)_handle);
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
_errorSource = 3;
|
||||
#endif
|
||||
}
|
||||
else { // everything ok
|
||||
_feof = false; // Reset eof flag since we know it was ok
|
||||
|
@ -153,13 +164,17 @@ bool PSPIoStream::seek(int32 offs, int whence) {
|
|||
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
return ret == 0;
|
||||
DEBUG_EXIT_FUNC();
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
uint32 PSPIoStream::read(void *ptr, uint32 len) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
// Check if we can access the file
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPIoStream::read()\n");
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n");
|
||||
|
||||
PSP_DEBUG_PRINT_FUNC("filename[%s], len[%d]\n", _path.c_str(), len);
|
||||
|
||||
size_t ret = fread((byte *)ptr, 1, len, (FILE *)_handle);
|
||||
|
||||
|
@ -171,24 +186,25 @@ uint32 PSPIoStream::read(void *ptr, uint32 len) {
|
|||
_ferror = true;
|
||||
clearerr((FILE *)_handle);
|
||||
_pos = ftell((FILE *)_handle); // Update our position
|
||||
PSPDebugSuspend("In PSPIoStream::read(). encountered an error!\n");
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
_errorSource = 4;
|
||||
#endif
|
||||
PSP_ERROR("fread returned ret[%d] instead of len[%d]\n", ret, len);
|
||||
}
|
||||
}
|
||||
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32 PSPIoStream::write(const void *ptr, uint32 len) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
// Check if we can access the file
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPIoStream::read()\n");
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n");
|
||||
|
||||
PSP_DEBUG_PRINT_FUNC("filename[%s], len[%d]\n", _path.c_str(), len);
|
||||
|
||||
size_t ret = fwrite(ptr, 1, len, (FILE *)_handle);
|
||||
|
||||
_pos += ret;
|
||||
|
@ -197,73 +213,73 @@ uint32 PSPIoStream::write(const void *ptr, uint32 len) {
|
|||
_ferror = true;
|
||||
clearerr((FILE *)_handle);
|
||||
_pos = ftell((FILE *)_handle); // Update pos
|
||||
PSPDebugTrace("In PSPIoStream::write(). encountered an error!\n");
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
_errorSource = 5;
|
||||
#endif
|
||||
PSP_ERROR("fwrite returned[%d] instead of len[%d]\n", ret, len);
|
||||
}
|
||||
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool PSPIoStream::flush() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
// Enter critical section
|
||||
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
|
||||
PSPDebugSuspend("Suspended in PSPIoStream::read()\n");
|
||||
PSP_DEBUG_PRINT_FUNC("Suspended\n");
|
||||
|
||||
int ret = fflush((FILE *)_handle);
|
||||
|
||||
if (ret != 0) {
|
||||
_ferror = true;
|
||||
clearerr((FILE *)_handle);
|
||||
PSPDebugSuspend("In PSPIoStream::flush(). encountered an error!\n");
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
_errorSource = 6;
|
||||
#endif
|
||||
PSP_ERROR("fflush returned ret[%u]\n", ret);
|
||||
}
|
||||
|
||||
PowerMan.endCriticalSection();
|
||||
|
||||
return ret == 0;
|
||||
DEBUG_EXIT_FUNC();
|
||||
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) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSPIoStream *stream = new PSPIoStream(path, writeMode);
|
||||
|
||||
if (stream->open() > 0) {
|
||||
return stream;
|
||||
} else {
|
||||
if (stream->open() <= 0) {
|
||||
delete stream;
|
||||
return 0;
|
||||
stream = 0;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return stream;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to suspend the IO stream (called by PowerManager)
|
||||
* we can have no output here
|
||||
*/
|
||||
int PSPIoStream::suspend() {
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
DEBUG_ENTER_FUNC();
|
||||
_suspendCount++;
|
||||
|
||||
if (_handle > 0 && _pos < 0) {
|
||||
if (_handle > 0 && _pos < 0) { /* check for error */
|
||||
_errorSuspend = SuspendError;
|
||||
_errorPos = _pos;
|
||||
_errorHandle = _handle;
|
||||
}
|
||||
#endif /* __PSP_DEBUG_SUSPEND__ */
|
||||
|
||||
if (_handle > 0) {
|
||||
fclose((FILE *)_handle); // close our file descriptor
|
||||
_handle = (void *)0xFFFFFFFF; // Set handle to non-null invalid value so makeFromPath doesn't return error
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -271,31 +287,27 @@ int PSPIoStream::suspend() {
|
|||
* Function to resume the IO stream (called by Power Manager)
|
||||
*/
|
||||
int PSPIoStream::resume() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
int ret = 0;
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
_suspendCount--;
|
||||
#endif
|
||||
|
||||
// We reopen our file descriptor
|
||||
_handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb");
|
||||
if (_handle <= 0) {
|
||||
PSPDebugSuspend("PSPIoStream::resume(): Couldn't reopen file %s\n", _path.c_str());
|
||||
PSP_ERROR("Couldn't reopen file %s\n", _path.c_str());
|
||||
}
|
||||
|
||||
// Resume our previous position
|
||||
if (_handle > 0 && _pos > 0) {
|
||||
ret = fseek((FILE *)_handle, _pos, SEEK_SET);
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
if (ret != 0) { // Check for problem
|
||||
_errorSuspend = ResumeError;
|
||||
_errorPos = _pos;
|
||||
_errorHandle = _handle;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,13 +49,14 @@ protected:
|
|||
int _errorSuspend;
|
||||
mutable int _errorSource;
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
// Error checking
|
||||
int _errorPos;
|
||||
void * _errorHandle;
|
||||
int _suspendCount;
|
||||
#endif /* __PSP_DEBUG_SUSPEND__ */
|
||||
|
||||
public:
|
||||
|
||||
const char *getObjectName() const { return "PSPIoStream"; }
|
||||
/**
|
||||
* Given a path, invoke fopen on that path and wrap the result in a
|
||||
* PSPIoStream instance.
|
||||
|
|
|
@ -66,7 +66,7 @@ endif
|
|||
#CC = psp-gcc
|
||||
CXX = psp-g++
|
||||
CXXFLAGS = -O3 -Wall -Wno-multichar -fno-exceptions -fno-rtti
|
||||
DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL
|
||||
DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -DUSE_RGB_COLOR
|
||||
LDFLAGS :=
|
||||
INCDIR := $(srcdir) . $(srcdir)/engines/ $(PSPSDK)/include
|
||||
INCLUDES := $(addprefix -I, $(INCDIR))
|
||||
|
@ -133,6 +133,13 @@ LIBS += -lpng -lSDL -lz $(findstring -lGL,$(SDLLIBS)) -lstdc++ -lc -lm $(fil
|
|||
OBJS := powerman.o \
|
||||
psp_main.o \
|
||||
osys_psp.o \
|
||||
psppixelformat.o \
|
||||
memory.o \
|
||||
display_manager.o \
|
||||
display_client.o \
|
||||
default_display_client.o \
|
||||
input.o \
|
||||
cursor.o \
|
||||
trace.o \
|
||||
psploader.o \
|
||||
pspkeyboard.o
|
||||
|
|
|
@ -16,12 +16,13 @@ Left trigger - ESC
|
|||
Right trigger - Modifier key (see below for uses)
|
||||
Analog - Mouse movement
|
||||
Right trigger + Analog - Fine control mouse
|
||||
Directionals - Mouse movement
|
||||
Directions - Arrow keys
|
||||
Directions + Right Trigger - Diagonal arrow keys
|
||||
Triangle - Enter
|
||||
Cross - Mouse button 1
|
||||
Circle - Mouse button 2
|
||||
Square - '.' (skip dialogue in some games)
|
||||
Start - F5
|
||||
Start - F5 (Main Menu)
|
||||
Right trigger + Start - Return-To-Launcher menu
|
||||
|
||||
Virtual Keyboard
|
||||
|
|
365
backends/platform/psp/cursor.cpp
Normal file
365
backends/platform/psp/cursor.cpp
Normal file
|
@ -0,0 +1,365 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.h $
|
||||
* $Id: osys_psp.h 46120 2009-11-24 10:33:30Z Bluddy $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "backends/platform/psp/display_client.h"
|
||||
#include "backends/platform/psp/default_display_client.h"
|
||||
#include "backends/platform/psp/cursor.h"
|
||||
|
||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
|
||||
//#define __PSP_DEBUG_PRINT__
|
||||
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
void Cursor::init() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_renderer.setBuffer(&_buffer); // We do this explicitly
|
||||
_renderer.setPalette(&_screenPalette); // because we want to choose screenpalette by default
|
||||
_renderer.setUseGlobalScaler(true);
|
||||
setRendererModePalettized(true); // Assume we start in 8bit mode
|
||||
|
||||
// Default modes
|
||||
_palette.setPixelFormats(PSPPixelFormat::Type_5551, PSPPixelFormat::Type_Palette_8bit); // default
|
||||
_screenPalette.setPixelFormats(PSPPixelFormat::Type_5551, PSPPixelFormat::Type_Palette_8bit);
|
||||
_buffer.setPixelFormat(PSPPixelFormat::Type_5551);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Cursor::deallocate() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_buffer.deallocate();
|
||||
_palette.deallocate();
|
||||
_screenPalette.deallocate();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Cursor::setCursorPalette(const byte *colors, uint start, uint num) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (!_palette.isAllocated()) {
|
||||
_palette.allocate();
|
||||
}
|
||||
|
||||
// Workaround: This is wrong, but we seem to not be getting setScreenPalette
|
||||
if (!_screenPalette.isAllocated()) {
|
||||
_screenPalette.allocate();
|
||||
}
|
||||
|
||||
_palette.setPartial(colors, start, num);
|
||||
setDirty();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Cursor::setScreenPalette(const byte *colors, uint start, uint num) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (!_screenPalette.isAllocated()) {
|
||||
_screenPalette.allocate();
|
||||
}
|
||||
|
||||
_screenPalette.setPartial(colors, start, num);
|
||||
setDirty();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Cursor::setKeyColor(uint32 color) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("new color[%u], old color[%u]\n", color, _keyColor);
|
||||
|
||||
// If it's a different color, undo the last keycolor
|
||||
if (_buffer.hasPalette() && color != _keyColor) {
|
||||
if (_screenPalette.isAllocated())
|
||||
_screenPalette.setColorPositionAlpha(_keyColor, true);
|
||||
if (_palette.isAllocated())
|
||||
_palette.setColorPositionAlpha(_keyColor, true);
|
||||
}
|
||||
// Don't need anything special for 16-bit
|
||||
_keyColor = color;
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Cursor::clearKeyColor() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("keyColor[%d]\n", _keyColor);
|
||||
|
||||
// We need 2 mechanisms: one for palettized and one for 16 bit
|
||||
if (_buffer.hasPalette()) {
|
||||
if (_screenPalette.isAllocated())
|
||||
_screenPalette.setColorPositionAlpha(_keyColor, false); // set keycolor to 0
|
||||
if (_palette.isAllocated())
|
||||
_palette.setColorPositionAlpha(_keyColor, false);
|
||||
} else { // 16bit
|
||||
_renderer.setKeyColor(_keyColor);
|
||||
}
|
||||
setDirty();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Cursor::enableCursorPalette(bool enable) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("enable[%s]\n", enable ? "true" : "false");
|
||||
|
||||
_useCursorPalette = enable;
|
||||
if (enable)
|
||||
_renderer.setPalette(&_palette); // very important that we do this switch
|
||||
else
|
||||
_renderer.setPalette(&_screenPalette);
|
||||
|
||||
setDirty();
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline void Cursor::setSize(uint32 width, uint32 height) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("width[%u], height[%u]\n", width, height);
|
||||
|
||||
_buffer.setSize(width, height, Buffer::kSizeByTextureSize); // we'll use texture size for mouse
|
||||
_renderer.setDrawWholeBuffer(); // We need to let the renderer know how much to draw
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Cursor::copyFromArray(const byte *array) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (!_buffer.isAllocated()) {
|
||||
_buffer.allocate();
|
||||
}
|
||||
|
||||
_buffer.copyFromArray(array, _buffer.getSourceWidthInBytes()); // pitch is source width
|
||||
setDirty();
|
||||
|
||||
// debug
|
||||
//PSP_DEBUG_DO(_buffer.print(0xF));
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
|
||||
}
|
||||
|
||||
void Cursor::setHotspot(int32 x, int32 y) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_hotspotX = x;
|
||||
_hotspotY = y;
|
||||
updateRendererOffset(); // Important
|
||||
|
||||
PSP_DEBUG_PRINT("hotspotX[%d], hotspotY[%d]\n", x, y);
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Returns true if change in x or y
|
||||
bool Cursor::increaseXY(int32 incX, int32 incY) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
int32 oldX = _x, oldY = _y;
|
||||
|
||||
// adjust for differences in X and Y
|
||||
adjustXYForScreenSize(incX, incY);
|
||||
|
||||
_x += incX;
|
||||
_y += incY;
|
||||
|
||||
// Clamp mouse
|
||||
if (_x < 0)
|
||||
_x = 0;
|
||||
if (_y < 0)
|
||||
_y = 0;
|
||||
if (_x >= (int)_mouseLimitWidth)
|
||||
_x = (int)_mouseLimitWidth - 1;
|
||||
if (_y >= (int)_mouseLimitHeight)
|
||||
_y = (int)_mouseLimitHeight - 1;
|
||||
|
||||
PSP_DEBUG_PRINT("X[%d], Y[%d]\n", _x, _y);
|
||||
|
||||
if (oldX != _x || oldY != _y) {
|
||||
updateRendererOffset();
|
||||
setDirty();
|
||||
DEBUG_EXIT_FUNC();
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set limits on the movement of the cursor ie. screen size
|
||||
void Cursor::setLimits(uint32 width, uint32 height) {
|
||||
#define PSP_SCREEN_WIDTH 480
|
||||
#define PSP_SCREEN_HEIGHT 272
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
PSP_DEBUG_PRINT("width[%u], height[%u]\n", width, height);
|
||||
_mouseLimitWidth = width;
|
||||
_mouseLimitHeight = height;
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Adjust X,Y movement for the screen size to keep it consistent
|
||||
inline void Cursor::adjustXYForScreenSize(int32 &x, int32 &y) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
// We have our speed calibrated for the y axis at 480x272. The idea is to adjust this for other
|
||||
// resolutions and for x, which is wider.
|
||||
int32 newX = x, newY = y;
|
||||
|
||||
// adjust width movement to match height (usually around 1.5)
|
||||
if (_mouseLimitWidth >= _mouseLimitHeight + (_mouseLimitHeight >> 1))
|
||||
newX = newX + (newX >> 1);
|
||||
|
||||
if (_mouseLimitWidth >= 600) { // multiply by 2
|
||||
newX <<= 1;
|
||||
newY <<= 1;
|
||||
} else if (_mouseLimitWidth >= 480) { // multiply by 1.5
|
||||
newX = newX + (newX >> 1);
|
||||
newY = newY + (newY >> 1);
|
||||
}
|
||||
|
||||
// Divide all movements by 8
|
||||
newX >>= 3;
|
||||
newY >>= 3;
|
||||
|
||||
// Make sure we didn't destroy minimum movement
|
||||
if (!((x && !newX) || (y && !newY))) {
|
||||
x = newX;
|
||||
y = newY;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// This is only called when we have a new screen
|
||||
void Cursor::setScreenPaletteScummvmPixelFormat(const Graphics::PixelFormat *format) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
uint32 oldPaletteSize = 0;
|
||||
if (_screenPalette.isAllocated())
|
||||
oldPaletteSize = _screenPalette.getSizeInBytes();
|
||||
|
||||
PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown;
|
||||
PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown;
|
||||
bool swapRedBlue = false;
|
||||
|
||||
// Convert Scummvm Pixel Format to PSPPixelFormat
|
||||
PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, swapRedBlue);
|
||||
|
||||
if (paletteType == PSPPixelFormat::Type_None) {
|
||||
//_screenPalette.deallocate(); // leave palette for default CLUT8
|
||||
setRendererModePalettized(false); // use 16-bit mechanism
|
||||
} else { // We have a palette
|
||||
_screenPalette.setPixelFormats(paletteType, bufferType);
|
||||
_palette.setPixelFormats(paletteType, bufferType);
|
||||
setRendererModePalettized(true); // use palettized mechanism
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// This is called many many times
|
||||
void Cursor::setSizeAndScummvmPixelFormat(uint32 width, uint32 height, const Graphics::PixelFormat *format) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
PSP_DEBUG_PRINT("useCursorPalette[%s]\n", _useCursorPalette ? "true" : "false");
|
||||
|
||||
uint32 oldBufferSize = 0, oldPaletteSize = 0;
|
||||
|
||||
if (_buffer.isAllocated())
|
||||
oldBufferSize = _buffer.getSizeInBytes();
|
||||
|
||||
if (_palette.isAllocated())
|
||||
oldPaletteSize = _palette.getSizeInBytes();
|
||||
|
||||
setSize(width, height);
|
||||
|
||||
PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown;
|
||||
PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown;
|
||||
bool swapRedBlue = false;
|
||||
|
||||
PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, swapRedBlue);
|
||||
PSP_DEBUG_PRINT("bufferType[%u], paletteType[%u]\n", bufferType, paletteType);
|
||||
|
||||
// Check if we need to set new pixel format
|
||||
if (_buffer.getPixelFormat() != bufferType) {
|
||||
PSP_DEBUG_PRINT("new buffer pixel format[%u] is different from [%u]. Setting it.\n", bufferType, _buffer.getPixelFormat());
|
||||
_buffer.setPixelFormat(bufferType);
|
||||
}
|
||||
|
||||
// Check if we need to reallocate
|
||||
if (_buffer.getSizeInBytes() != oldBufferSize) {
|
||||
_buffer.allocate();
|
||||
PSP_DEBUG_PRINT("reallocating buffer. new size: width[%u], height[%u]\n", width, height);
|
||||
}
|
||||
|
||||
PSP_DEBUG_PRINT("palette pixel format[%u]\n", paletteType);
|
||||
|
||||
if (paletteType == PSPPixelFormat::Type_None) {
|
||||
setRendererModePalettized(false); // use palettized mechanism
|
||||
} else { // We have a palette
|
||||
_palette.setPixelFormats(paletteType, bufferType);
|
||||
setRendererModePalettized(true); // use palettized mechanism
|
||||
}
|
||||
|
||||
// debug
|
||||
// PSP_DEBUG_DO(_palette.print(10));
|
||||
// PSP_DEBUG_DO(_screenPalette.print(10));
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Cursor::setXY(int x, int y) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_x = x;
|
||||
_y = y;
|
||||
updateRendererOffset(); // Very important to let renderer know things changed
|
||||
setDirty();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline void Cursor::updateRendererOffset() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
_renderer.setOffsetOnScreen(_x - _hotspotX, _y - _hotspotY);
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline void Cursor::setRendererModePalettized(bool palettized) {
|
||||
if (palettized) { // We have a palette. Use blending
|
||||
_renderer.setAlphaBlending(true);
|
||||
_renderer.setAlphaReverse(false);
|
||||
_renderer.setColorTest(false);
|
||||
} else { // 16 bits, no palette
|
||||
_renderer.setAlphaBlending(true);
|
||||
_renderer.setAlphaReverse(true); // We can't change all alpha values, so just reverse
|
||||
_renderer.setColorTest(true); // Color test to make our key color transparent
|
||||
}
|
||||
}
|
81
backends/platform/psp/cursor.h
Normal file
81
backends/platform/psp/cursor.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.h $
|
||||
* $Id: osys_psp.h 46120 2009-11-24 10:33:30Z Bluddy $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MOUSE_H
|
||||
#define MOUSE_H
|
||||
|
||||
class Cursor : public DefaultDisplayClient {
|
||||
private:
|
||||
int _hotspotX, _hotspotY;
|
||||
uint32 _keyColor;
|
||||
int _cursorTargetScale;
|
||||
bool _useCursorPalette;
|
||||
bool _hasCursorPalette;
|
||||
uint32 _mouseLimitWidth;
|
||||
uint32 _mouseLimitHeight;
|
||||
int32 _x, _y;
|
||||
Palette _screenPalette; // separate palette for screen. default 'palette' is cursor palette.
|
||||
|
||||
void updateRendererOffset();
|
||||
|
||||
public:
|
||||
Cursor() : _hotspotX(0), _hotspotY(0), _keyColor(0), _cursorTargetScale(0),
|
||||
_useCursorPalette(false), _hasCursorPalette(false), _mouseLimitWidth(0),
|
||||
_mouseLimitHeight(0), _x(0), _y(0) { }
|
||||
virtual ~Cursor() { deallocate(); }
|
||||
|
||||
void setKeyColor(uint32 color);
|
||||
void setCursorTargetScale(int scale) { _cursorTargetScale = scale; }
|
||||
void setScreenPalette(const byte *colors, uint start, uint num);
|
||||
void copyFromArray(const byte *array);
|
||||
Palette &palette() { return _palette; }
|
||||
Buffer &buffer() { return _buffer; }
|
||||
void setCursorPalette(const byte *colors, uint start, uint num);
|
||||
void enableCursorPalette(bool enable);
|
||||
void setLimits(uint32 width, uint32 height);
|
||||
void setXY(int x, int y);
|
||||
int32 getX() { return _x; }
|
||||
int32 getY() { return _y; }
|
||||
bool increaseXY(int32 incX, int32 incY); // returns true if there's a change in x or y
|
||||
void adjustXYForScreenSize(int32 &x, int32 &y);
|
||||
void init();
|
||||
void setHotspot(int32 x, int32 y);
|
||||
void setScreenPaletteScummvmPixelFormat(const Graphics::PixelFormat *format);
|
||||
void setSizeAndScummvmPixelFormat(uint32 widht, uint32 height, const Graphics::PixelFormat *format);
|
||||
void clearKeyColor();
|
||||
void useGlobalScaler(bool val) { _renderer.setUseGlobalScaler(val); }
|
||||
bool allocate();
|
||||
void deallocate();
|
||||
|
||||
private:
|
||||
void setSize(uint32 width, uint32 height);
|
||||
void getPixelFormatsFromScummvmPixelFormat(const Graphics::PixelFormat *format,
|
||||
PSPPixelFormat::Type &bufferFormat,
|
||||
PSPPixelFormat::Type &paletteFormat,
|
||||
uint32 &numOfEntries);
|
||||
void setRendererModePalettized(bool palettized);
|
||||
};
|
||||
|
||||
#endif /* MOUSE_H */
|
238
backends/platform/psp/default_display_client.cpp
Normal file
238
backends/platform/psp/default_display_client.cpp
Normal file
|
@ -0,0 +1,238 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.h $
|
||||
* $Id: osys_psp.h 46120 2009-11-24 10:33:30Z Bluddy $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "backends/platform/psp/display_client.h"
|
||||
#include "backends/platform/psp/default_display_client.h"
|
||||
|
||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
|
||||
//#define __PSP_DEBUG_PRINT__
|
||||
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
// Class DefaultDisplayClient ---------------------------------------------
|
||||
|
||||
bool DefaultDisplayClient::allocate(bool bufferInVram /* = false */, bool paletteInVram /* = false */) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (!_buffer.allocate(bufferInVram)) {
|
||||
PSP_ERROR("Couldn't allocate buffer.\n");
|
||||
DEBUG_EXIT_FUNC();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_buffer.hasPalette())
|
||||
{
|
||||
PSP_DEBUG_PRINT("_palette[%p]\n", &_palette);
|
||||
|
||||
if (!_palette.allocate()) {
|
||||
PSP_ERROR("Couldn't allocate pallette.\n");
|
||||
DEBUG_EXIT_FUNC();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DefaultDisplayClient::deallocate() {
|
||||
_buffer.deallocate();
|
||||
if (_buffer.hasPalette())
|
||||
_palette.deallocate();
|
||||
}
|
||||
|
||||
|
||||
void DefaultDisplayClient::clearBuffer() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
_buffer.clear();
|
||||
setDirty();
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline void DefaultDisplayClient::clearPalette() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
_palette.clear();
|
||||
setDirty();
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void DefaultDisplayClient::init() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
_renderer.setBuffer(&_buffer);
|
||||
_renderer.setPalette(&_palette);
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void DefaultDisplayClient::copyFromRect(const byte *buf, int pitch, int destX, int destY, int recWidth, int recHeight) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
_buffer.copyFromRect(buf, pitch, destX, destY, recWidth, recHeight);
|
||||
setDirty();
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void DefaultDisplayClient::copyToArray(byte *dst, int pitch) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
_buffer.copyToArray(dst, pitch);
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Class Overlay -------------------------------------------------------
|
||||
|
||||
void Overlay::init() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
DefaultDisplayClient::init();
|
||||
_renderer.setAlphaBlending(true);
|
||||
_renderer.setColorTest(false);
|
||||
_renderer.setUseGlobalScaler(false);
|
||||
_renderer.setFullScreen(true); // speeds up render slightly
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Overlay::setBytesPerPixel(uint32 size) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
_buffer.setPixelFormat(PSPPixelFormat::Type_Palette_8bit);
|
||||
_palette.setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_8bit);
|
||||
break;
|
||||
case 2:
|
||||
_buffer.setPixelFormat(PSPPixelFormat::Type_4444);
|
||||
break;
|
||||
case 4:
|
||||
_buffer.setPixelFormat(PSPPixelFormat::Type_8888);
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Overlay::setSize(uint32 width, uint32 height) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
_buffer.setSize(width, height, Buffer::kSizeBySourceSize);
|
||||
_renderer.setDrawWholeBuffer(); // We need to let the renderer know how much to draw
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Overlay::copyToArray(OverlayColor *buf, int pitch) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
_buffer.copyToArray((byte *)buf, pitch * sizeof(OverlayColor)); // Change to bytes
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Overlay::copyFromRect(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_buffer.copyFromRect((byte *)buf, pitch * sizeof(OverlayColor), x, y, w, h); // Change to bytes
|
||||
// debug
|
||||
//_buffer.print(0xFF);
|
||||
setDirty();
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
bool Overlay::allocate() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
bool ret = DefaultDisplayClient::allocate(true, false); // buffer in VRAM
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Class Screen -----------------------------------------------------------
|
||||
|
||||
void Screen::init() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
DefaultDisplayClient::init();
|
||||
_renderer.setAlphaBlending(false);
|
||||
_renderer.setColorTest(false);
|
||||
_renderer.setUseGlobalScaler(true);
|
||||
_renderer.setFullScreen(true);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Screen::setShakePos(int pos) {
|
||||
_shakePos = pos;
|
||||
_renderer.setOffsetOnScreen(0, pos);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
void Screen::setSize(uint32 width, uint32 height) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_buffer.setSize(width, height, Buffer::kSizeBySourceSize);
|
||||
_renderer.setDrawWholeBuffer(); // We need to let the renderer know how much to draw
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Screen::setScummvmPixelFormat(const Graphics::PixelFormat *format) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("format[%p], _buffer[%p], _palette[%p]\n", format, &_buffer, &_palette);
|
||||
|
||||
if (!format) {
|
||||
bzero(&_pixelFormat, sizeof(_pixelFormat));
|
||||
_pixelFormat.bytesPerPixel = 1; // default
|
||||
} else {
|
||||
_pixelFormat = *format;
|
||||
}
|
||||
|
||||
PSPPixelFormat::Type bufferFormat, paletteFormat;
|
||||
bool swapRedBlue = false;
|
||||
|
||||
PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferFormat, paletteFormat, swapRedBlue);
|
||||
_buffer.setPixelFormat(bufferFormat, swapRedBlue);
|
||||
_palette.setPixelFormats(paletteFormat, bufferFormat, swapRedBlue);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
Graphics::Surface *Screen::lockAndGetForEditing() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_frameBuffer.pixels = _buffer.getPixels();
|
||||
_frameBuffer.w = _buffer.getSourceWidth();
|
||||
_frameBuffer.h = _buffer.getSourceHeight();
|
||||
_frameBuffer.pitch = _buffer.getBytesPerPixel() * _buffer.getWidth();
|
||||
_frameBuffer.bytesPerPixel = _buffer.getBytesPerPixel();
|
||||
// We'll set to dirty once we unlock the screen
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
|
||||
return &_frameBuffer;
|
||||
}
|
||||
|
||||
bool Screen::allocate() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
return DefaultDisplayClient::allocate(true, false); // buffer in VRAM
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
108
backends/platform/psp/default_display_client.h
Normal file
108
backends/platform/psp/default_display_client.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/trace.h $
|
||||
* $Id: trace.h 44276 2009-09-23 16:11:23Z joostp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSP_DEF_DISPLAY_CLIENT_H
|
||||
#define PSP_DEF_DISPLAY_CLIENT_H
|
||||
|
||||
/**
|
||||
* Default display client that is useful for most purposes.
|
||||
*/
|
||||
class DefaultDisplayClient : public DisplayClient {
|
||||
public:
|
||||
DefaultDisplayClient() : _visible(false), _dirty(true) {}
|
||||
|
||||
bool isVisible() { return _visible; }
|
||||
void setVisible(bool v) { _visible = v; setDirty(); }
|
||||
Buffer &buffer() { return _buffer; }
|
||||
Palette &palette() { return _palette; }
|
||||
void init();
|
||||
bool allocate(bool bufferInVram = false, bool paletteInVram = false);
|
||||
void deallocate();
|
||||
void clearBuffer();
|
||||
void clearPalette();
|
||||
void render() { _renderer.render(); }
|
||||
uint32 getWidth() { return _buffer.getSourceWidth(); }
|
||||
uint32 getHeight() { return _buffer.getSourceHeight(); }
|
||||
void setPartialPalette(const byte *colors, uint start, uint num) { setDirty(); return _palette.setPartial(colors, start, num); }
|
||||
void getPartialPalette(byte *colors, uint start, uint num) {
|
||||
return _palette.getPartial(colors, start, num);
|
||||
}
|
||||
void copyFromRect(const byte *buf, int pitch, int destX, int destY, int recWidth, int recHeight);
|
||||
void copyToArray(byte *dst, int pitch);
|
||||
void setDirty() { _dirty = true; }
|
||||
void setClean() { _dirty = false; }
|
||||
bool isDirty() { return _dirty; }
|
||||
|
||||
protected:
|
||||
Buffer _buffer;
|
||||
Palette _palette;
|
||||
GuRenderer _renderer;
|
||||
bool _visible;
|
||||
bool _dirty;
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen overlay class.
|
||||
*/
|
||||
class Overlay : public DefaultDisplayClient {
|
||||
public:
|
||||
Overlay() {}
|
||||
~Overlay() { }
|
||||
|
||||
void init();
|
||||
bool allocate();
|
||||
void setBytesPerPixel(uint32 size);
|
||||
void setSize(uint32 width, uint32 height);
|
||||
void copyToArray(OverlayColor *buf, int pitch);
|
||||
void copyFromRect(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
|
||||
};
|
||||
|
||||
/**
|
||||
* Screen class.
|
||||
*/
|
||||
class Screen : public DefaultDisplayClient {
|
||||
public:
|
||||
Screen() : _shakePos(0) {
|
||||
memset(&_pixelFormat, 0, sizeof(_pixelFormat));
|
||||
memset(&_frameBuffer, 0, sizeof(_frameBuffer));
|
||||
}
|
||||
~Screen() {}
|
||||
|
||||
void init();
|
||||
bool allocate();
|
||||
void setShakePos(int pos);
|
||||
void setScummvmPixelFormat(const Graphics::PixelFormat *format);
|
||||
const Graphics::PixelFormat &getScummvmPixelFormat() const { return _pixelFormat; }
|
||||
Graphics::Surface *lockAndGetForEditing();
|
||||
void unlock() { setDirty(); } // set dirty here because of changes
|
||||
void setSize(uint32 width, uint32 height);
|
||||
|
||||
private:
|
||||
uint32 _shakePos;
|
||||
Graphics::PixelFormat _pixelFormat;
|
||||
Graphics::Surface _frameBuffer;
|
||||
};
|
||||
|
||||
#endif /* PSP_DEF_DISPLAY_CLIENT_H */
|
805
backends/platform/psp/display_client.cpp
Normal file
805
backends/platform/psp/display_client.cpp
Normal file
|
@ -0,0 +1,805 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
|
||||
* $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <pspgu.h>
|
||||
#include <pspdisplay.h>
|
||||
#include <psputils.h>
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "backends/platform/psp/display_client.h"
|
||||
#include "backends/platform/psp/display_manager.h"
|
||||
#include "backends/platform/psp/memory.h"
|
||||
|
||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
|
||||
//#define __PSP_DEBUG_PRINT__
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
#define PSP_BUFFER_WIDTH (512)
|
||||
#define PSP_SCREEN_WIDTH 480
|
||||
#define PSP_SCREEN_HEIGHT 272
|
||||
#define PSP_FRAME_SIZE (PSP_BUFFER_WIDTH * PSP_SCREEN_HEIGHT)
|
||||
|
||||
DisplayManager *GuRenderer::_displayManager = 0;
|
||||
|
||||
|
||||
// class Palette ------------------------------------------------------------
|
||||
//
|
||||
void Palette::clear() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (_values && _numOfEntries)
|
||||
memset(_values, 0, getSizeInBytes());
|
||||
|
||||
PSP_DEBUG_PRINT("_values[%p]\n", _values);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Used to clear the specific keycolor
|
||||
//
|
||||
void Palette::setColorPositionAlpha(uint32 position, bool alpha) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
assert(_values);
|
||||
assert(position < _numOfEntries);
|
||||
|
||||
PSP_DEBUG_PRINT("position[%d], numofEntries[%u], bpp[%u], values[%p]\n", position, _numOfEntries,
|
||||
_pixelFormat.bitsPerPixel, _values);
|
||||
|
||||
if (_numOfEntries <= 16)
|
||||
position &= 0xF;
|
||||
else if (_numOfEntries <= 256)
|
||||
position &= 0xFF;
|
||||
|
||||
switch (_pixelFormat.bitsPerPixel) {
|
||||
case 16: {
|
||||
uint16 *shortVal = (uint16 *)&_values[_pixelFormat.pixelsToBytes(position)];
|
||||
*shortVal = _pixelFormat.setColorAlpha((uint32)*shortVal, alpha ? 255 : 0);
|
||||
}
|
||||
break;
|
||||
case 32: {
|
||||
uint32 *wordVal = (uint32 *)&_values[_pixelFormat.pixelsToBytes(position)];
|
||||
*wordVal = _pixelFormat.setColorAlpha((uint32)*wordVal, alpha ? 255 : 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PSP_ERROR("Incorrect bits per pixel value[%u]\n", _pixelFormat.bitsPerPixel);
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Set some of the palette to color values in array
|
||||
// By default, ScummVm doesn't support alpha values in palettes
|
||||
void Palette::setPartial(const byte *colors, uint32 start, uint32 num, bool supportsAlpha /* = false */) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
assert(_values);
|
||||
assert(_numOfEntries);
|
||||
|
||||
const byte *src = colors;
|
||||
|
||||
if (start + num > _numOfEntries) // Check boundary
|
||||
num = _numOfEntries - start;
|
||||
|
||||
if (_pixelFormat.bitsPerPixel == 16) {
|
||||
uint16 *palette = (uint16 *)_values;
|
||||
palette += start;
|
||||
|
||||
for (uint32 i = 0; i < num; ++i) {
|
||||
byte alphaVal = supportsAlpha ? src[3] : 0xFF;
|
||||
*palette = (uint16)_pixelFormat.rgbaToColor(src[0], src[1], src[2], alphaVal);
|
||||
src += 4;
|
||||
palette++;
|
||||
}
|
||||
}
|
||||
else if (_pixelFormat.bitsPerPixel == 32) {
|
||||
uint32 *palette = (uint32 *)_values;
|
||||
palette += start;
|
||||
|
||||
for (uint32 i = 0; i < num; ++i) {
|
||||
byte alphaVal = supportsAlpha ? src[3] : 0xFF;
|
||||
*palette = _pixelFormat.rgbaToColor(src[0], src[1], src[2], alphaVal);
|
||||
src += 4;
|
||||
palette++;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Sets pixel format and number of entries by the buffer's pixel format */
|
||||
void Palette::setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType, bool swapRedBlue /* = false */) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (paletteType == PSPPixelFormat::Type_Unknown)
|
||||
PSP_ERROR("Unknown paletteType[%u]\n", paletteType);
|
||||
|
||||
switch (bufferType) {
|
||||
case PSPPixelFormat::Type_Palette_8bit:
|
||||
_numOfEntries = 256;
|
||||
break;
|
||||
case PSPPixelFormat::Type_Palette_4bit:
|
||||
_numOfEntries = 16;
|
||||
break;
|
||||
case PSPPixelFormat::Type_Unknown:
|
||||
case PSPPixelFormat::Type_None:
|
||||
PSP_ERROR("Unhandled bufferType[%u]\n", bufferType);
|
||||
break;
|
||||
default: // No palette
|
||||
_numOfEntries = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
_pixelFormat.set(paletteType, swapRedBlue);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
bool Palette::allocate() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("_numOfEntries[%u]\n", _numOfEntries);
|
||||
PSP_DEBUG_PRINT("_pixelFormat: format[%u], bpp[%u]\n", _pixelFormat.format, _pixelFormat.bitsPerPixel);
|
||||
|
||||
if (_values) {
|
||||
free (CACHED(_values));
|
||||
_values = 0;
|
||||
}
|
||||
|
||||
// We allocate on 64bytes to get a cache line, and round up to 64bytes to get the full line
|
||||
uint32 amountInBytes = getSizeInBytes();
|
||||
if (amountInBytes < 64)
|
||||
amountInBytes = 64;
|
||||
_values = (byte *)memalign(64, amountInBytes);
|
||||
|
||||
// Use uncached memory
|
||||
GuRenderer::cacheInvalidate(_values, amountInBytes);
|
||||
_values = UNCACHED(_values);
|
||||
|
||||
if (!_values) {
|
||||
PSP_ERROR("Couldn't allocate palette.\n");
|
||||
DEBUG_EXIT_FUNC();
|
||||
return false;
|
||||
}
|
||||
|
||||
PSP_DEBUG_PRINT("_values[%p]\n", _values);
|
||||
clear();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Palette::deallocate() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
free (CACHED(_values));
|
||||
_values = 0;
|
||||
_numOfEntries = 0;
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Copy some of the palette to an array of colors
|
||||
//
|
||||
void Palette::getPartial(byte *colors, uint start, uint num) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
assert(_values);
|
||||
assert(_numOfEntries);
|
||||
|
||||
uint32 r, g, b, a;
|
||||
|
||||
if (start + num > _numOfEntries) // Check boundary
|
||||
num = _numOfEntries - start;
|
||||
|
||||
if (_pixelFormat.bitsPerPixel == 16) {
|
||||
uint16 *palette = (uint16 *)_values;
|
||||
palette += start;
|
||||
|
||||
for (uint32 i = start; i < start + num; i++) {
|
||||
_pixelFormat.colorToRgba(*palette, r, g, b, a);
|
||||
|
||||
*colors++ = (byte)r;
|
||||
*colors++ = (byte)g;
|
||||
*colors++ = (byte)b;
|
||||
*colors++ = (byte)a;
|
||||
palette++;
|
||||
}
|
||||
} else if (_pixelFormat.bitsPerPixel == 32) {
|
||||
uint32 *palette = (uint32 *)_values;
|
||||
palette += start;
|
||||
|
||||
for (uint32 i = start; i < start + num; i++) {
|
||||
_pixelFormat.colorToRgba(*palette, r, g, b, a);
|
||||
|
||||
*colors++ = (byte)r;
|
||||
*colors++ = (byte)g;
|
||||
*colors++ = (byte)b;
|
||||
*colors++ = (byte)a;
|
||||
palette++;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Palette::setSingleColorRGBA(uint32 num, byte r, byte g, byte b, byte a) {
|
||||
// DEBUG_ENTER_FUNC();
|
||||
uint16 *shortValues;
|
||||
uint32 *wordValues;
|
||||
|
||||
assert (_values);
|
||||
assert (num < _numOfEntries);
|
||||
|
||||
switch (_pixelFormat.bitsPerPixel) {
|
||||
case 16:
|
||||
shortValues = (uint16 *)_values;
|
||||
shortValues[num] = _pixelFormat.rgbaToColor(r, g, b, a);
|
||||
break;
|
||||
case 32:
|
||||
wordValues = (uint32 *)_values;
|
||||
wordValues[num] = _pixelFormat.rgbaToColor(r, g, b, a);
|
||||
break;
|
||||
default:
|
||||
PSP_ERROR("Incorrect bitsPerPixel[%d]\n", _pixelFormat.bitsPerPixel);
|
||||
break;
|
||||
}
|
||||
// DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Print to screen
|
||||
void Palette::print(uint32 numToPrint /* = 0 */) {
|
||||
if (_numOfEntries > 0) {
|
||||
assert (_values);
|
||||
|
||||
if (numToPrint > _numOfEntries || numToPrint == 0)
|
||||
numToPrint = _numOfEntries;
|
||||
|
||||
PSP_INFO_PRINT("cursor palette:\n");
|
||||
|
||||
for (unsigned int i=0; i<numToPrint; i++) {
|
||||
byte *pcolor = &_values[_pixelFormat.pixelsToBytes(i)];
|
||||
uint32 color = _pixelFormat.getColorValueAt(pcolor);
|
||||
|
||||
PSP_INFO_PRINT("[%u=%x] ", i, color);
|
||||
}
|
||||
|
||||
PSP_INFO_PRINT("\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Palette::getRawColorAt(uint32 position) {
|
||||
byte *pcolor = &_values[_pixelFormat.pixelsToBytes(position)];
|
||||
uint32 color = _pixelFormat.getColorValueAt(pcolor);
|
||||
return color;
|
||||
}
|
||||
|
||||
uint32 Palette::getRGBAColorAt(uint32 position) {
|
||||
uint32 color = getRawColorAt(position);
|
||||
uint32 r, g, b, a;
|
||||
_pixelFormat.colorToRgba(color, r, g, b, a);
|
||||
return (a << 24 | b << 16 | g << 8 | r);
|
||||
}
|
||||
|
||||
// class Buffer ---------------------------------------------------
|
||||
|
||||
void Buffer::setPixelFormat(PSPPixelFormat::Type type, bool swapRedBlue) {
|
||||
if (type == PSPPixelFormat::Type_None ||
|
||||
type == PSPPixelFormat::Type_Unknown)
|
||||
PSP_ERROR("Unhandled buffer format[%u]\n", type);
|
||||
|
||||
_pixelFormat.set(type, swapRedBlue);
|
||||
}
|
||||
|
||||
bool Buffer::hasPalette() {
|
||||
if (_pixelFormat.format == PSPPixelFormat::Type_Palette_8bit ||
|
||||
_pixelFormat.format == PSPPixelFormat::Type_Palette_4bit)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* pitch is in bytes */
|
||||
void Buffer::copyFromArray(const byte *buffer, int pitch) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
// We use sourceSize because outside, they won't know what the true size is
|
||||
copyFromRect(buffer, pitch, 0, 0, _sourceSize.width, _sourceSize.height);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
/* pitch is in bytes */
|
||||
void Buffer::copyFromRect(const byte *buf, uint32 pitch, int destX, int destY, uint32 recWidth, uint32 recHeight) {
|
||||
// Removed silly clipping code
|
||||
DEBUG_ENTER_FUNC();
|
||||
assert (_pixels);
|
||||
|
||||
if (recWidth > _sourceSize.width - destX) {
|
||||
recWidth = _sourceSize.width - destX;
|
||||
}
|
||||
|
||||
if (recHeight > _sourceSize.height - destY) {
|
||||
recHeight = _sourceSize.height - destY;
|
||||
}
|
||||
|
||||
if (recWidth <= 0 || recHeight <= 0) {
|
||||
DEBUG_EXIT_FUNC();
|
||||
return;
|
||||
}
|
||||
|
||||
byte *dst = _pixels + _pixelFormat.pixelsToBytes((destY * _width) + destX);
|
||||
|
||||
uint32 recWidthInBytes = _pixelFormat.pixelsToBytes(recWidth);
|
||||
uint32 realWidthInBytes = _pixelFormat.pixelsToBytes(_width);
|
||||
|
||||
if (pitch == realWidthInBytes && pitch == recWidthInBytes) {
|
||||
//memcpy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth));
|
||||
Copier::copy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth), &_pixelFormat);
|
||||
} else {
|
||||
do {
|
||||
//memcpy(dst, buf, recWidthInBytes);
|
||||
Copier::copy(dst, buf, recWidthInBytes, &_pixelFormat);
|
||||
buf += pitch;
|
||||
dst += realWidthInBytes;
|
||||
} while (--recHeight);
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
/* pitch is in bytes */
|
||||
void Buffer::copyToArray(byte *dst, int pitch) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
assert (_pixels);
|
||||
|
||||
uint32 h = _height;
|
||||
byte *src = _pixels;
|
||||
uint32 sourceWidthInBytes = _pixelFormat.pixelsToBytes(_sourceSize.width);
|
||||
uint32 realWidthInBytes = _pixelFormat.pixelsToBytes(_width);
|
||||
|
||||
do {
|
||||
//memcpy(dst, src, sourceWidthInBytes);
|
||||
Copier::copy(dst, src, sourceWidthInBytes, &_pixelFormat);
|
||||
src += realWidthInBytes;
|
||||
dst += pitch;
|
||||
} while (--h);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
/* We can size the buffer either by texture size (multiple of 2^n) or source size. The GU can
|
||||
really handle both, but is supposed to get only 2^n size buffers */
|
||||
void Buffer::setSize(uint32 width, uint32 height, HowToSize textureOrSource/*=kSizeByTextureSize*/) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("w[%u], h[%u], %s\n", width, height, textureOrSource ? "size by source" : "size by texture");
|
||||
|
||||
_sourceSize.width = width;
|
||||
_sourceSize.height = height;
|
||||
|
||||
_textureSize.width = scaleUpToPowerOfTwo(width);
|
||||
_textureSize.height = scaleUpToPowerOfTwo(height);
|
||||
|
||||
if (textureOrSource == kSizeByTextureSize) {
|
||||
_width = _textureSize.width;
|
||||
_height = _textureSize.height;
|
||||
}
|
||||
else { /* kSizeBySourceSize */
|
||||
_width = _sourceSize.width;
|
||||
_height = _sourceSize.height;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
/* Scale a dimension (width/height) up to power of 2 for the texture */
|
||||
uint32 Buffer::scaleUpToPowerOfTwo(uint32 size) {
|
||||
|
||||
uint32 textureDimension = 0;
|
||||
if (size <= 16)
|
||||
textureDimension = 16;
|
||||
else if (size <= 32)
|
||||
textureDimension = 32;
|
||||
else if (size <= 64)
|
||||
textureDimension = 64;
|
||||
else if (size <= 128)
|
||||
textureDimension = 128;
|
||||
else if (size <= 256)
|
||||
textureDimension = 256;
|
||||
else
|
||||
textureDimension = 512;
|
||||
|
||||
PSP_DEBUG_PRINT("power of 2 = %u\n", textureDimension);
|
||||
|
||||
return textureDimension;
|
||||
}
|
||||
|
||||
bool Buffer::allocate(bool inVram/*=false*/) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
PSP_DEBUG_PRINT("_width[%u], _height[%u]\n", _width, _height);
|
||||
PSP_DEBUG_PRINT("_pixelFormat: format[%u], bpp[%u]\n", _pixelFormat.format, _pixelFormat.bitsPerPixel);
|
||||
|
||||
if (_pixels) {
|
||||
if (VramAllocator::isAddressInVram(_pixels)) // Check if in VRAM
|
||||
VramAllocator::instance().deallocate(_pixels);
|
||||
else // not in VRAM
|
||||
free (CACHED(_pixels));
|
||||
|
||||
_pixels = 0;
|
||||
}
|
||||
|
||||
uint32 size = getSizeInBytes();
|
||||
|
||||
if (inVram) {
|
||||
_pixels = (byte *)VramAllocator::instance().allocate(size);
|
||||
}
|
||||
|
||||
if (!_pixels) { // Either we are not in vram or we didn't manage to allocate in vram
|
||||
// Align to 64 bytes. All normal buffer sizes are multiples of 64 anyway
|
||||
_pixels = (byte *)memalign(64, size);
|
||||
}
|
||||
|
||||
if (!_pixels) {
|
||||
PSP_ERROR("couldn't allocate buffer.\n");
|
||||
DEBUG_EXIT_FUNC();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use uncached memory
|
||||
GuRenderer::cacheInvalidate(_pixels, size);
|
||||
_pixels = UNCACHED(_pixels);
|
||||
|
||||
clear();
|
||||
DEBUG_EXIT_FUNC();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Buffer::deallocate() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (!_pixels)
|
||||
return;
|
||||
|
||||
if (VramAllocator::isAddressInVram(_pixels)) // Check if in VRAM
|
||||
VramAllocator::instance().deallocate(_pixels);
|
||||
else
|
||||
free(CACHED(_pixels));
|
||||
|
||||
_pixels = 0;
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void Buffer::clear() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (_pixels)
|
||||
memset(_pixels, 0, getSizeInBytes());
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
/* Convert 4 bit images to match weird PSP format */
|
||||
void Buffer::flipNibbles() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (_pixelFormat.bitsPerPixel != 4)
|
||||
return;
|
||||
|
||||
assert(_pixels);
|
||||
|
||||
uint32 *dest = (uint32 *)_pixels;
|
||||
|
||||
for (uint32 i = 0; i < getSourceHeight(); i++) {
|
||||
for (uint32 j = 0; j < (getWidth() >> 3); j++) { // /8 because we do it in 32bit chunks
|
||||
uint32 val = *dest;
|
||||
*dest++ = ((val >> 4) & 0x0F0F0F0F) | ((val << 4) & 0xF0F0F0F0);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Print buffer contents to screen (only source size is printed out)
|
||||
void Buffer::print(uint32 mask, uint32 numToPrint /*=0*/) {
|
||||
assert(_pixels);
|
||||
|
||||
if (numToPrint > _sourceSize.width * _sourceSize.height || numToPrint == 0)
|
||||
numToPrint = _sourceSize.width * _sourceSize.height;
|
||||
|
||||
PSP_INFO_PRINT("buffer: \n");
|
||||
PSP_INFO_PRINT("width[%u], height[%u]\n\n", _sourceSize.width, _sourceSize.height);
|
||||
|
||||
for (unsigned int i=0; i < _sourceSize.height; i++) {
|
||||
for (unsigned int j=0; j < _sourceSize.width; j++) {
|
||||
if (numToPrint <= 0) // check if done
|
||||
break;
|
||||
|
||||
byte *pcolor = &_pixels[_pixelFormat.pixelsToBytes((i * _width) + j)];
|
||||
uint32 color = _pixelFormat.getColorValueAt(pcolor);
|
||||
|
||||
//if (color != 0) PSP_INFO_PRINT("[%x] ", color);
|
||||
PSP_INFO_PRINT("[%x] ", mask & color);
|
||||
|
||||
numToPrint--;
|
||||
}
|
||||
PSP_INFO_PRINT("\n");
|
||||
}
|
||||
PSP_INFO_PRINT("\n");
|
||||
}
|
||||
|
||||
// class GuRenderer -------------------------------------------------
|
||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
|
||||
//#define __PSP_DEBUG_PRINT__
|
||||
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
|
||||
void GuRenderer::render() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("Buffer[%p] Palette[%p]\n", _buffer->getPixels(), _palette->getRawValues());
|
||||
|
||||
setMaxTextureOffsetByIndex(0, 0);
|
||||
|
||||
guProgramDrawBehavior();
|
||||
|
||||
if (_buffer->hasPalette())
|
||||
guLoadPalette();
|
||||
|
||||
guProgramTextureFormat();
|
||||
guLoadTexture();
|
||||
|
||||
Vertex *vertices = guGetVertices();
|
||||
fillVertices(vertices);
|
||||
|
||||
guDrawVertices(vertices);
|
||||
|
||||
if (_buffer->getSourceWidth() > 512) {
|
||||
setMaxTextureOffsetByIndex(1, 0);
|
||||
|
||||
guLoadTexture();
|
||||
|
||||
vertices = guGetVertices();
|
||||
fillVertices(vertices);
|
||||
|
||||
guDrawVertices(vertices);
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline void GuRenderer::setMaxTextureOffsetByIndex(uint32 x, uint32 y) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
const uint32 maxTextureSizeShift = 9; /* corresponds to 512 = max texture size*/
|
||||
|
||||
_maxTextureOffset.x = x << maxTextureSizeShift; /* x times 512 */
|
||||
_maxTextureOffset.y = y << maxTextureSizeShift; /* y times 512 */
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline void GuRenderer::guProgramDrawBehavior() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("blending[%s] colorTest[%s] reverseAlpha[%s] keyColor[%u]\n", _blending ? "on" : "off", _colorTest ? "on" : "off", _alphaReverse ? "on" : "off", _keyColor);
|
||||
|
||||
if (_blending) {
|
||||
sceGuEnable(GU_BLEND);
|
||||
|
||||
if (_alphaReverse) // Reverse the alpha value (0 is 1)
|
||||
sceGuBlendFunc(GU_ADD, GU_ONE_MINUS_SRC_ALPHA, GU_SRC_ALPHA, 0, 0);
|
||||
else // Normal alpha values
|
||||
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
|
||||
|
||||
} else
|
||||
sceGuDisable(GU_BLEND);
|
||||
|
||||
if (_colorTest) {
|
||||
sceGuEnable(GU_COLOR_TEST);
|
||||
sceGuColorFunc(GU_NOTEQUAL, _keyColor, 0x00ffffff);
|
||||
} else
|
||||
sceGuDisable(GU_COLOR_TEST);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline void GuRenderer::guLoadPalette() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
uint32 mask;
|
||||
|
||||
if (_buffer->getBitsPerPixel() == 4)
|
||||
mask = 0x0F;
|
||||
else if (_buffer->getBitsPerPixel() == 8)
|
||||
mask = 0xFF;
|
||||
else
|
||||
assert(0); /* error */
|
||||
|
||||
PSP_DEBUG_PRINT("numOfEntries[%d]\n", _palette->getNumOfEntries());
|
||||
PSP_DEBUG_PRINT("bpp[%d], pixelformat[%d], mask[%x]\n", _buffer->getBitsPerPixel(), _palette->getPixelFormat(), mask);
|
||||
|
||||
sceGuClutMode(convertToGuPixelFormat(_palette->getPixelFormat()), 0, mask, 0);
|
||||
sceGuClutLoad(_palette->getNumOfEntries() >> 3, _palette->getRawValues());
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline void GuRenderer::guProgramTextureFormat() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("pixelFormat[%d]\n", _buffer->getPixelFormat());
|
||||
|
||||
sceGuTexMode(convertToGuPixelFormat(_buffer->getPixelFormat()), 0, 0, 0);
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline uint32 GuRenderer::convertToGuPixelFormat(PSPPixelFormat::Type format) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
uint32 guFormat = 0;
|
||||
|
||||
switch (format) {
|
||||
case PSPPixelFormat::Type_4444:
|
||||
guFormat = GU_PSM_4444;
|
||||
break;
|
||||
case PSPPixelFormat::Type_5551:
|
||||
guFormat = GU_PSM_5551;
|
||||
break;
|
||||
case PSPPixelFormat::Type_5650:
|
||||
guFormat = GU_PSM_5650;
|
||||
break;
|
||||
case PSPPixelFormat::Type_8888:
|
||||
guFormat = GU_PSM_8888;
|
||||
break;
|
||||
case PSPPixelFormat::Type_Palette_8bit:
|
||||
guFormat = GU_PSM_T8;
|
||||
break;
|
||||
case PSPPixelFormat::Type_Palette_4bit:
|
||||
guFormat = GU_PSM_T4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
PSP_DEBUG_PRINT("Pixelformat[%d], guFormat[%d]\n", format, guFormat);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return guFormat;
|
||||
|
||||
}
|
||||
|
||||
inline void GuRenderer::guLoadTexture() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
sceGuTexImage(0, _buffer->getTextureWidth(), _buffer->getTextureHeight(), _buffer->getWidth(), _buffer->getPixels() + _buffer->_pixelFormat.pixelsToBytes(_maxTextureOffset.x));
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline Vertex *GuRenderer::guGetVertices() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
Vertex *ret = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Fills the vertices. Most of the logic is here.
|
||||
void GuRenderer::fillVertices(Vertex *vertices) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
uint32 outputWidth = _displayManager->getOutputWidth();
|
||||
uint32 outputHeight = _displayManager->getOutputHeight();
|
||||
|
||||
float textureStartX, textureStartY, textureEndX, textureEndY;
|
||||
|
||||
// Texture adjustments for eliminating half-pixel artifacts from scaling
|
||||
// Not necessary if we don't scale
|
||||
float textureAdjustment = 0.0f;
|
||||
if (_useGlobalScaler &&
|
||||
(_displayManager->getScaleX() != 1.0f || _displayManager->getScaleX() != 1.0f))
|
||||
textureAdjustment = 0.5f;
|
||||
|
||||
textureStartX = textureAdjustment + _offsetInBuffer.x; //debug
|
||||
textureStartY = textureAdjustment + _offsetInBuffer.y;
|
||||
// We subtract maxTextureOffset because our shifted texture starts at 512 and will go to 640
|
||||
textureEndX = _offsetInBuffer.x + _drawSize.width - textureAdjustment - _maxTextureOffset.x;
|
||||
textureEndY = _offsetInBuffer.y + _drawSize.height - textureAdjustment;
|
||||
|
||||
// For scaling to the final image size, calculate the gaps on both sides
|
||||
uint32 gapX = _useGlobalScaler ? (PSP_SCREEN_WIDTH - outputWidth) >> 1 : 0;
|
||||
uint32 gapY = _useGlobalScaler ? (PSP_SCREEN_HEIGHT - outputHeight) >> 1 : 0;
|
||||
|
||||
float imageStartX, imageStartY, imageEndX, imageEndY;
|
||||
|
||||
imageStartX = gapX + ( scaleSourceToOutputX(_maxTextureOffset.x) );
|
||||
imageStartY = gapY;
|
||||
|
||||
imageStartX += scaleSourceToOutputX(_offsetOnScreen.x);
|
||||
imageStartY += scaleSourceToOutputY(_offsetOnScreen.y);
|
||||
|
||||
if (_fullScreen) { // shortcut
|
||||
imageEndX = PSP_SCREEN_WIDTH - gapX;
|
||||
imageEndY = PSP_SCREEN_HEIGHT - gapY;
|
||||
} else { /* !fullScreen */
|
||||
imageEndX = imageStartX + scaleSourceToOutputX(_drawSize.width);
|
||||
imageEndY = imageStartY + scaleSourceToOutputY(_drawSize.height);
|
||||
}
|
||||
|
||||
vertices[0].u = textureStartX;
|
||||
vertices[0].v = textureStartY;
|
||||
vertices[1].u = textureEndX;
|
||||
vertices[1].v = textureEndY;
|
||||
|
||||
vertices[0].x = imageStartX;
|
||||
vertices[0].y = imageStartY;
|
||||
vertices[0].z = 0;
|
||||
vertices[1].x = imageEndX;
|
||||
vertices[1].y = imageEndY;
|
||||
vertices[1].z = 0;
|
||||
|
||||
PSP_DEBUG_PRINT("TextureStart: X[%f] Y[%f] TextureEnd: X[%.1f] Y[%.1f]\n", textureStartX, textureStartY, textureEndX, textureEndY);
|
||||
PSP_DEBUG_PRINT("ImageStart: X[%f] Y[%f] ImageEnd: X[%.1f] Y[%.1f]\n", imageStartX, imageStartY, imageEndX, imageEndY);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
/* Scale the input X offset to appear in proper position on the screen */
|
||||
inline float GuRenderer::scaleSourceToOutputX(float offset) {
|
||||
float result;
|
||||
|
||||
if (!_useGlobalScaler)
|
||||
result = offset;
|
||||
else if (!offset)
|
||||
result = 0.0f;
|
||||
else
|
||||
result = offset * _displayManager->getScaleX();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Scale the input Y offset to appear in proper position on the screen */
|
||||
inline float GuRenderer::scaleSourceToOutputY(float offset) {
|
||||
float result;
|
||||
|
||||
if (!_useGlobalScaler)
|
||||
result = offset;
|
||||
else if (!offset)
|
||||
result = 0.0f;
|
||||
else
|
||||
result = offset * _displayManager->getScaleY();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void GuRenderer::guDrawVertices(Vertex *vertices) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void GuRenderer::cacheInvalidate(void *pointer, uint32 size) {
|
||||
sceKernelDcacheWritebackInvalidateRange(pointer, size);
|
||||
}
|
238
backends/platform/psp/display_client.h
Normal file
238
backends/platform/psp/display_client.h
Normal file
|
@ -0,0 +1,238 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
|
||||
* $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSP_GRAPHICS_H
|
||||
#define PSP_GRAPHICS_H
|
||||
|
||||
#include "common/singleton.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "common/system.h"
|
||||
#include "backends/platform/psp/psppixelformat.h"
|
||||
#include "backends/platform/psp/memory.h"
|
||||
|
||||
#define MAX_TEXTURE_SIZE 512
|
||||
|
||||
class DisplayManager;
|
||||
class GuRenderer;
|
||||
|
||||
/**
|
||||
* Interface to inherit for all display clients
|
||||
* We deliberately avoid virtual functions for speed.
|
||||
*/
|
||||
class DisplayClient { // Abstract class
|
||||
public:
|
||||
DisplayClient() {}
|
||||
bool isVisible() { return true; }
|
||||
bool isDirty() { return true; }
|
||||
void setClean() {}
|
||||
void render() {}
|
||||
virtual ~DisplayClient() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Vertex used for GU rendering
|
||||
*/
|
||||
struct Vertex {
|
||||
float u,v;
|
||||
float x,y,z;
|
||||
};
|
||||
|
||||
struct Point {
|
||||
int x;
|
||||
int y;
|
||||
Point() : x(0), y(0) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dimensions struct for simplification
|
||||
*/
|
||||
struct Dimensions {
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
Dimensions() : width(0), height(0) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Universal PSP Palette class
|
||||
* Use this in any class that wishes to draw to the PSP screen.
|
||||
* Use together with GuRenderer
|
||||
*/
|
||||
class Palette {
|
||||
public:
|
||||
Palette() : _values(0), _numOfEntries(0) {}
|
||||
virtual ~Palette() { deallocate(); }
|
||||
bool allocate();
|
||||
void deallocate();
|
||||
void clear();
|
||||
void setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType, bool swapRedBlue = false);
|
||||
void setNumOfEntries(uint32 num) { _numOfEntries = num; }
|
||||
uint32 getNumOfEntries() { return _numOfEntries; }
|
||||
uint32 getSizeInBytes() { return _pixelFormat.pixelsToBytes(_numOfEntries); }
|
||||
void set(byte *values) { setPartial(values, 0, _numOfEntries); }
|
||||
void setPartial(const byte *colors, uint start, uint num, bool supportsAlpha = false);
|
||||
void getPartial(byte *colors, uint start, uint num);
|
||||
uint32 getRawColorAt(uint32 position);
|
||||
uint32 getRGBAColorAt(uint32 position);
|
||||
void setSingleColorRGBA(uint32 num, byte r, byte g, byte b, byte a);
|
||||
void setColorPositionAlpha(uint32 position, bool alpha);
|
||||
byte *getRawValues() { return _values; }
|
||||
bool isAllocated() { return (_values != 0); }
|
||||
PSPPixelFormat::Type getPixelFormat() { return _pixelFormat.format; }
|
||||
void print(uint32 numToPrint = 0); // print to screen
|
||||
|
||||
protected:
|
||||
byte *_values; ///< array of palette data
|
||||
uint32 _numOfEntries; ///< number of palette entries
|
||||
PSPPixelFormat _pixelFormat; ///< pixel format of the palette data
|
||||
};
|
||||
|
||||
/**
|
||||
* Universal PSP buffer/texture object
|
||||
* Use this in any class that wishes to draw to the PSP screen.
|
||||
* Use together with GuRenderer
|
||||
*/
|
||||
class Buffer {
|
||||
public:
|
||||
enum HowToSize {
|
||||
kSizeByTextureSize, // buffer size is determined by power of 2 roundup for texture
|
||||
kSizeBySourceSize // buffer size is determined by source size
|
||||
};
|
||||
|
||||
Buffer() : _pixels(0), _width(0), _height(0) {}
|
||||
virtual ~Buffer() { deallocate(); }
|
||||
|
||||
// setters
|
||||
void setSize(uint32 width, uint32 height, HowToSize textureOrSource=kSizeByTextureSize);
|
||||
void setBitsPerPixel(uint32 bits) { _pixelFormat.bitsPerPixel = bits; }
|
||||
void setBytesPerPixel(uint32 bytes) { setBitsPerPixel(bytes << 3); }
|
||||
void setPixelFormat(PSPPixelFormat::Type type, bool swapRedBlue = false);
|
||||
|
||||
// getters
|
||||
uint32 getWidth() { return _width; }
|
||||
uint32 getWidthInBytes() { return _pixelFormat.pixelsToBytes(getWidth()); }
|
||||
uint32 getHeight() { return _height; }
|
||||
uint32 getSourceWidth() { return _sourceSize.width; }
|
||||
uint32 getSourceWidthInBytes() { return _pixelFormat.pixelsToBytes(_sourceSize.width); }
|
||||
uint32 getSourceHeight() { return _sourceSize.height; }
|
||||
uint32 getTextureWidth() { return _textureSize.width; }
|
||||
uint32 getTextureHeight() { return _textureSize.height; }
|
||||
PSPPixelFormat::Type getPixelFormat() { return _pixelFormat.format; }
|
||||
uint32 getBitsPerPixel() { return _pixelFormat.bitsPerPixel; }
|
||||
uint32 getBytesPerPixel() { return getBitsPerPixel() >> 3; } /* won't work for 4-bit */
|
||||
byte *getPixels() { return _pixels; }
|
||||
uint32 getSizeInBytes() { return _pixelFormat.pixelsToBytes(_width * _height); }
|
||||
|
||||
bool hasPalette();
|
||||
void copyFromArray(const byte *buffer, int pitch);
|
||||
void copyFromRect(const byte *buf, uint32 pitch, int destX, int destY, uint32 recWidth, uint32 recHeight);
|
||||
void copyToArray(byte *dst, int pitch);
|
||||
bool allocate(bool inVram = false);
|
||||
void deallocate();
|
||||
bool isAllocated() { return (_pixels != 0) ; }
|
||||
void clear();
|
||||
void flipNibbles(); // To handle peculiarities of PSP's 4 bit textures
|
||||
static uint32 scaleUpToPowerOfTwo(uint32 size);
|
||||
void print(uint32 mask, uint32 numToPrint = 0);
|
||||
|
||||
protected:
|
||||
friend class GuRenderer;
|
||||
byte *_pixels;
|
||||
uint32 _width; ///< True allocated width
|
||||
uint32 _height; ///< True allocated height
|
||||
Dimensions _textureSize; ///< Size rounded up to power of 2. Used for drawing
|
||||
Dimensions _sourceSize; ///< Original size of the buffer
|
||||
PSPPixelFormat _pixelFormat; ///< Format of the buffer
|
||||
};
|
||||
|
||||
/**
|
||||
* Universal rendering class for PSP
|
||||
* Use this if you want to draw to the screen.
|
||||
* Needs to be supplied with a Buffer and a Palette
|
||||
*/
|
||||
class GuRenderer {
|
||||
public:
|
||||
// Constructors
|
||||
GuRenderer() : _useGlobalScaler(false), _buffer(0), _palette(0), _blending(false), _alphaReverse(false), _colorTest(false), _keyColor(0), _fullScreen(false) {}
|
||||
GuRenderer(Buffer *buffer, Palette *palette) : _useGlobalScaler(false), _buffer(buffer), _palette(palette), _blending(false), _alphaReverse(false), _colorTest(false), _keyColor(0), _fullScreen(false) {}
|
||||
static void setDisplayManager(DisplayManager *dm) { _displayManager = dm; } // Called by the Display Manager
|
||||
|
||||
// Setters
|
||||
void setDrawSize(uint32 width, uint32 height) { // How big of an area to draw
|
||||
_drawSize.width = width;
|
||||
_drawSize.height = height;
|
||||
}
|
||||
void setDrawWholeBuffer() { // Draw the full size of the current buffer
|
||||
assert(_buffer);
|
||||
_drawSize.width = _buffer->getSourceWidth();
|
||||
_drawSize.height = _buffer->getSourceHeight();
|
||||
}
|
||||
void setBuffer(Buffer *buffer) { _buffer = buffer; }
|
||||
void setPalette(Palette *palette) { _palette = palette; }
|
||||
void setMaxTextureOffsetByIndex(uint32 x, uint32 y); // For drawing multiple textures
|
||||
void setOffsetOnScreen(uint32 x, uint32 y) { _offsetOnScreen.x = x; _offsetOnScreen.y = y; }
|
||||
void setOffsetInBuffer(uint32 x, uint32 y) { _offsetInBuffer.x = x; _offsetInBuffer.y = y; }
|
||||
void setColorTest(bool value) { _colorTest = value; }
|
||||
void setKeyColor(uint32 value) { _keyColor = _buffer->_pixelFormat.convertTo32BitColor(value); }
|
||||
void setAlphaBlending(bool value) { _blending = value; }
|
||||
void setAlphaReverse(bool value) { _alphaReverse = value; }
|
||||
void setFullScreen(bool value) { _fullScreen = value; } // Shortcut for rendering
|
||||
void setUseGlobalScaler(bool value) { _useGlobalScaler = value; } // Scale to screen
|
||||
|
||||
static void cacheInvalidate(void *pointer, uint32 size);
|
||||
|
||||
void render(); // Default rendering function. This should be good enough for most purposes
|
||||
|
||||
protected:
|
||||
// Gu functions
|
||||
void fillVertices(Vertex *vertices); // Fill in vertices with coordinates
|
||||
void guProgramDrawBehavior();
|
||||
Vertex *guGetVertices();
|
||||
void guLoadTexture();
|
||||
void guLoadPalette();
|
||||
void guProgramTextureFormat();
|
||||
void guProgramTextureBitDepth();
|
||||
void guDrawVertices(Vertex *vertices);
|
||||
|
||||
uint32 convertToGuPixelFormat(PSPPixelFormat::Type format);
|
||||
float scaleSourceToOutputX(float offset);
|
||||
float scaleSourceToOutputY(float offset);
|
||||
|
||||
friend class MasterGuRenderer;
|
||||
Point _maxTextureOffset; ///> For rendering textures > 512 pixels
|
||||
Point _offsetOnScreen; ///> Where on screen to draw
|
||||
Point _offsetInBuffer; ///> Where in the texture to draw
|
||||
bool _useGlobalScaler; ///> Scale to the output size on screen
|
||||
Buffer *_buffer;
|
||||
Palette *_palette;
|
||||
static DisplayManager *_displayManager;
|
||||
Dimensions _drawSize; ///> Actual size to draw out of the Buffer
|
||||
bool _blending;
|
||||
bool _alphaReverse; ///> 0 counts as full alpha
|
||||
bool _colorTest;
|
||||
uint32 _keyColor; ///> Color to test against for color test. in 32 bits.
|
||||
bool _fullScreen; ///> Speeds up for fullscreen rendering
|
||||
};
|
||||
|
||||
#endif /* PSP_SCREEN_H */
|
336
backends/platform/psp/display_manager.cpp
Normal file
336
backends/platform/psp/display_manager.cpp
Normal file
|
@ -0,0 +1,336 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
|
||||
* $Id: osys_psp.cpp 47541 2010-01-25 01:39:44Z lordhoto $
|
||||
*
|
||||
*/
|
||||
|
||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
|
||||
//#define __PSP_DEBUG_PRINT__ /* For debug printouts */
|
||||
|
||||
//#define ENABLE_RENDER_MEASURE
|
||||
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
#include <pspgu.h>
|
||||
#include <pspdisplay.h>
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "backends/base-backend.h"
|
||||
#include "backends/platform/psp/display_client.h"
|
||||
#include "backends/platform/psp/default_display_client.h"
|
||||
#include "backends/platform/psp/cursor.h"
|
||||
#include "backends/platform/psp/pspkeyboard.h"
|
||||
#include "backends/platform/psp/display_manager.h"
|
||||
|
||||
#define PSP_BUFFER_WIDTH (512)
|
||||
#define PSP_SCREEN_WIDTH 480
|
||||
#define PSP_SCREEN_HEIGHT 272
|
||||
#define PSP_FRAME_SIZE (PSP_BUFFER_WIDTH * PSP_SCREEN_HEIGHT)
|
||||
|
||||
uint32 __attribute__((aligned(16))) MasterGuRenderer::_displayList[2048];
|
||||
|
||||
const OSystem::GraphicsMode DisplayManager::_supportedModes[] = {
|
||||
{ "320x200 (centered)", "320x200 16-bit centered", CENTERED_320X200 },
|
||||
{ "435x272 (best-fit, centered)", "435x272 16-bit centered", CENTERED_435X272 },
|
||||
{ "480x272 (full screen)", "480x272 16-bit stretched", STRETCHED_480X272 },
|
||||
{ "362x272 (4:3, centered)", "362x272 16-bit centered", CENTERED_362X272 },
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
// Class MasterGuRenderer ----------------------------------------------
|
||||
|
||||
void MasterGuRenderer::guInit() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
sceGuInit();
|
||||
sceGuStart(0, _displayList);
|
||||
|
||||
guProgramDisplayBufferSizes();
|
||||
|
||||
sceGuOffset(2048 - (PSP_SCREEN_WIDTH/2), 2048 - (PSP_SCREEN_HEIGHT/2));
|
||||
sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
|
||||
sceGuDepthRange(0xC350, 0x2710);
|
||||
sceGuDisable(GU_DEPTH_TEST); // We'll use depth buffer area
|
||||
sceGuDepthMask(GU_TRUE); // Prevent writes to depth buffer
|
||||
sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
|
||||
sceGuEnable(GU_SCISSOR_TEST);
|
||||
sceGuFrontFace(GU_CW);
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
|
||||
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
|
||||
sceGuFinish();
|
||||
sceGuSync(0,0);
|
||||
|
||||
sceDisplayWaitVblankStart();
|
||||
sceGuDisplay(1);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void MasterGuRenderer::guProgramDisplayBufferSizes() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
PSP_DEBUG_PRINT("Outputbits[%u]\n", GuRenderer::_displayManager->getOutputBitsPerPixel());
|
||||
|
||||
switch (GuRenderer::_displayManager->getOutputBitsPerPixel()) {
|
||||
case 16:
|
||||
sceGuDrawBuffer(GU_PSM_4444, (void *)0, PSP_BUFFER_WIDTH);
|
||||
sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)(PSP_FRAME_SIZE * sizeof(uint16)), PSP_BUFFER_WIDTH);
|
||||
sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * sizeof(uint16) * 2), PSP_BUFFER_WIDTH);
|
||||
VramAllocator::instance().allocate(PSP_FRAME_SIZE * sizeof(uint16) * 2);
|
||||
break;
|
||||
case 32:
|
||||
sceGuDrawBuffer(GU_PSM_8888, (void *)0, PSP_BUFFER_WIDTH);
|
||||
sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)(PSP_FRAME_SIZE * sizeof(uint32)), PSP_BUFFER_WIDTH);
|
||||
sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * sizeof(uint32) * 2), PSP_BUFFER_WIDTH);
|
||||
VramAllocator::instance().allocate(PSP_FRAME_SIZE * sizeof(uint32) * 2);
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// These are GU commands that should always stay the same
|
||||
inline void MasterGuRenderer::guPreRender() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
#ifdef ENABLE_RENDER_MEASURE
|
||||
_lastRenderTime = g_system->getMillis();
|
||||
#endif /* ENABLE_RENDER_MEASURE */
|
||||
|
||||
sceGuStart(0, _displayList);
|
||||
|
||||
sceGuClearColor(0xFF000000);
|
||||
sceGuClear(GU_COLOR_BUFFER_BIT);
|
||||
|
||||
sceGuAmbientColor(0xFFFFFFFF);
|
||||
sceGuColor(0xFFFFFFFF);
|
||||
sceGuTexOffset(0,0);
|
||||
sceGuTexFilter(GU_LINEAR, GU_LINEAR);
|
||||
|
||||
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); // Also good enough for all purposes
|
||||
sceGuAlphaFunc(GU_GREATER, 0, 0xFF); // Also good enough for all purposes
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline void MasterGuRenderer::guPostRender() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
sceGuFinish();
|
||||
sceGuSync(0,0);
|
||||
|
||||
#ifdef ENABLE_RENDER_MEASURE
|
||||
uint32 now = g_system->getMillis();
|
||||
PSP_INFO_PRINT("Render took %d milliseconds\n", now - _lastRenderTime);
|
||||
#endif /* ENABLE_RENDER_MEASURE */
|
||||
|
||||
sceDisplayWaitVblankStart();
|
||||
sceGuSwapBuffers();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void MasterGuRenderer::guShutDown() {
|
||||
sceGuTerm();
|
||||
}
|
||||
|
||||
|
||||
// Class DisplayManager -----------------------------------------------------
|
||||
|
||||
DisplayManager::~DisplayManager() {
|
||||
_masterGuRenderer.guShutDown();
|
||||
}
|
||||
|
||||
void DisplayManager::init() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_displayParams.outputBitsPerPixel = 32; // can be changed to produce 16-bit output
|
||||
|
||||
GuRenderer::setDisplayManager(this);
|
||||
_screen->init();
|
||||
_overlay->init();
|
||||
_cursor->init();
|
||||
|
||||
_masterGuRenderer.guInit(); // start up the renderer
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
void DisplayManager::setSizeAndPixelFormat(uint width, uint height, const Graphics::PixelFormat *format) {
|
||||
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("w[%u], h[%u], pformat[%p]\n", width, height, format);
|
||||
|
||||
_overlay->deallocate();
|
||||
_screen->deallocate();
|
||||
|
||||
_screen->setScummvmPixelFormat(format);
|
||||
_screen->setSize(width, height);
|
||||
_screen->allocate();
|
||||
|
||||
_cursor->setScreenPaletteScummvmPixelFormat(format);
|
||||
|
||||
_overlay->setBytesPerPixel(sizeof(OverlayColor));
|
||||
_overlay->setSize(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
|
||||
_overlay->allocate();
|
||||
|
||||
_displayParams.screenSource.width = width;
|
||||
_displayParams.screenSource.height = height;
|
||||
calculateScaleParams();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
bool DisplayManager::setGraphicsMode(const char *name) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (_supportedModes[i].name) {
|
||||
if (!strcmpi(_supportedModes[i].name, name)) {
|
||||
setGraphicsMode(_supportedModes[i].id);
|
||||
DEBUG_EXIT_FUNC();
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DisplayManager::setGraphicsMode(int mode) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_graphicsMode = mode;
|
||||
|
||||
switch (_graphicsMode) {
|
||||
case CENTERED_320X200:
|
||||
_displayParams.screenOutput.width = 320;
|
||||
_displayParams.screenOutput.height = 200;
|
||||
break;
|
||||
case CENTERED_435X272:
|
||||
_displayParams.screenOutput.width = 435;
|
||||
_displayParams.screenOutput.height = 272;
|
||||
break;
|
||||
case STRETCHED_480X272:
|
||||
_displayParams.screenOutput.width = 480;
|
||||
_displayParams.screenOutput.height = 272;
|
||||
break;
|
||||
case CENTERED_362X272:
|
||||
_displayParams.screenOutput.width = 362;
|
||||
_displayParams.screenOutput.height = 272;
|
||||
break;
|
||||
default:
|
||||
PSP_ERROR("Unsupported graphics mode[%d].\n", _graphicsMode);
|
||||
}
|
||||
|
||||
calculateScaleParams();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DisplayManager::calculateScaleParams() {
|
||||
if (_displayParams.screenOutput.width && _displayParams.screenSource.width &&
|
||||
_displayParams.screenOutput.height && _displayParams.screenSource.height) {
|
||||
_displayParams.scaleX = ((float)_displayParams.screenOutput.width) / _displayParams.screenSource.width;
|
||||
_displayParams.scaleY = ((float)_displayParams.screenOutput.height) / _displayParams.screenSource.height;
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayManager::renderAll() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
if (!isTimeToUpdate()) {
|
||||
DEBUG_EXIT_FUNC();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_screen->isDirty() &&
|
||||
(!_overlay->isDirty()) &&
|
||||
(!_cursor->isDirty()) &&
|
||||
(!_keyboard->isDirty())) {
|
||||
PSP_DEBUG_PRINT("Nothing dirty\n");
|
||||
DEBUG_EXIT_FUNC();
|
||||
return;
|
||||
}
|
||||
|
||||
PSP_DEBUG_PRINT("screen[%s], overlay[%s], cursor[%s], keyboard[%s]\n",
|
||||
_screen->isDirty() ? "true" : "false",
|
||||
_overlay->isDirty() ? "true" : "false",
|
||||
_cursor->isDirty() ? "true" : "false",
|
||||
_keyboard->isDirty() ? "true" : "false"
|
||||
);
|
||||
|
||||
_masterGuRenderer.guPreRender(); // Set up rendering
|
||||
|
||||
_screen->render();
|
||||
|
||||
_screen->setClean(); // clean out dirty bit
|
||||
|
||||
if (_overlay->isVisible())
|
||||
_overlay->render();
|
||||
|
||||
_overlay->setClean();
|
||||
|
||||
if (_cursor->isVisible())
|
||||
_cursor->render();
|
||||
|
||||
_cursor->setClean();
|
||||
|
||||
if (_keyboard->isVisible())
|
||||
_keyboard->render();
|
||||
|
||||
_keyboard->setClean();
|
||||
|
||||
_masterGuRenderer.guPostRender();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline bool DisplayManager::isTimeToUpdate() {
|
||||
|
||||
#define MAX_FPS 30
|
||||
|
||||
uint32 now = g_system->getMillis();
|
||||
if (now - _lastUpdateTime < (1000 / MAX_FPS))
|
||||
return false;
|
||||
|
||||
_lastUpdateTime = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::List<Graphics::PixelFormat> DisplayManager::getSupportedPixelFormats() {
|
||||
Common::List<Graphics::PixelFormat> list;
|
||||
|
||||
// In order of preference
|
||||
list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_5650));
|
||||
list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_5551));
|
||||
list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_4444));
|
||||
list.push_back(Graphics::PixelFormat::createFormatCLUT8());
|
||||
|
||||
return list;
|
||||
}
|
||||
|
114
backends/platform/psp/display_manager.h
Normal file
114
backends/platform/psp/display_manager.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
|
||||
* $Id: osys_psp.cpp 47541 2010-01-25 01:39:44Z lordhoto $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSP_DISPLAY_MAN_H
|
||||
#define PSP_DISPLAY_MAN_H
|
||||
|
||||
/**
|
||||
* Class used only by DisplayManager to start/stop GU rendering
|
||||
*/
|
||||
class MasterGuRenderer {
|
||||
public:
|
||||
MasterGuRenderer() : _lastRenderTime(0) {}
|
||||
void guInit();
|
||||
void guPreRender();
|
||||
void guPostRender();
|
||||
void guShutDown();
|
||||
private:
|
||||
static uint32 _displayList[];
|
||||
uint32 _lastRenderTime; // For measuring rendering
|
||||
void guProgramDisplayBufferSizes();
|
||||
};
|
||||
|
||||
class Screen;
|
||||
class Overlay;
|
||||
class Cursor;
|
||||
class PSPKeyboard;
|
||||
|
||||
/**
|
||||
* Class that manages all display clients
|
||||
*/
|
||||
class DisplayManager {
|
||||
public:
|
||||
enum GraphicsModeID { ///> Possible output formats onscreen
|
||||
CENTERED_320X200,
|
||||
CENTERED_435X272,
|
||||
STRETCHED_480X272,
|
||||
CENTERED_362X272
|
||||
};
|
||||
DisplayManager() : _screen(0), _cursor(0), _overlay(0), _keyboard(0), _lastUpdateTime(0), _graphicsMode(0) {}
|
||||
~DisplayManager();
|
||||
|
||||
void init();
|
||||
void renderAll();
|
||||
bool setGraphicsMode(int mode);
|
||||
bool setGraphicsMode(const char *name);
|
||||
int getGraphicsMode() const { return _graphicsMode; }
|
||||
uint32 getDefaultGraphicsMode() const { return STRETCHED_480X272; }
|
||||
const OSystem::GraphicsMode* getSupportedGraphicsModes() const { return _supportedModes; }
|
||||
|
||||
// Setters
|
||||
void setScreen(Screen *screen) { _screen = screen; }
|
||||
void setCursor(Cursor *cursor) { _cursor = cursor; }
|
||||
void setOverlay(Overlay *overlay) { _overlay = overlay; }
|
||||
void setKeyboard(PSPKeyboard *keyboard) { _keyboard = keyboard; }
|
||||
void setSizeAndPixelFormat(uint width, uint height, const Graphics::PixelFormat *format);
|
||||
|
||||
// Getters
|
||||
float getScaleX() { return _displayParams.scaleX; }
|
||||
float getScaleY() { return _displayParams.scaleY; }
|
||||
uint32 getOutputWidth() { return _displayParams.screenOutput.width; }
|
||||
uint32 getOutputHeight() { return _displayParams.screenOutput.height; }
|
||||
uint32 getOutputBitsPerPixel() { return _displayParams.outputBitsPerPixel; }
|
||||
Common::List<Graphics::PixelFormat> getSupportedPixelFormats();
|
||||
|
||||
private:
|
||||
struct GlobalDisplayParams {
|
||||
Dimensions screenOutput;
|
||||
Dimensions screenSource;
|
||||
float scaleX;
|
||||
float scaleY;
|
||||
uint32 outputBitsPerPixel; // How many bits end up on-screen
|
||||
GlobalDisplayParams() : scaleX(0.0f), scaleY(0.0f), outputBitsPerPixel(0) {}
|
||||
};
|
||||
|
||||
// Pointers to DisplayClients
|
||||
Screen *_screen;
|
||||
Cursor *_cursor;
|
||||
Overlay *_overlay;
|
||||
PSPKeyboard *_keyboard;
|
||||
|
||||
MasterGuRenderer _masterGuRenderer;
|
||||
uint32 _lastUpdateTime; // For limiting FPS
|
||||
int _graphicsMode;
|
||||
GlobalDisplayParams _displayParams;
|
||||
static const OSystem::GraphicsMode _supportedModes[];
|
||||
|
||||
void calculateScaleParams(); // calculates scaling factor
|
||||
bool isTimeToUpdate(); // should we update the screen now
|
||||
};
|
||||
|
||||
|
||||
#endif /* PSP_DISPLAY_MAN_H */
|
317
backends/platform/psp/input.cpp
Normal file
317
backends/platform/psp/input.cpp
Normal file
|
@ -0,0 +1,317 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
|
||||
* $Id: osys_psp.cpp 43618 2009-08-21 22:44:49Z joostp $
|
||||
*
|
||||
*/
|
||||
|
||||
// Todo: handle events that should fire because of shift going off
|
||||
// Solution: handle shift on a button-by-button basis, only allowing it when the button is up. Also a inputmap-wide button. At buttonup, shiftstate is inspected per button.
|
||||
|
||||
//#define __PSP_DEBUG_FUNCS__ /* Uncomment for debugging the stack */
|
||||
//#define __PSP_DEBUG_PRINT__ /* Uncomment for debug prints */
|
||||
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
#include "backends/platform/psp/input.h"
|
||||
|
||||
// Defines for working with PSP buttons
|
||||
#define CHANGED(x) (_buttonsChanged & (x))
|
||||
#define PRESSED(x) ((_buttonsChanged & (x)) && (pad.Buttons & (x)))
|
||||
#define UNPRESSED(x) ((_buttonsChanged & (x)) && !(pad.Buttons & (x)))
|
||||
#define DOWN(x) (pad.Buttons & (x))
|
||||
#define UP(x) (!(pad.Buttons & (x)))
|
||||
#define PSP_DPAD (PSP_CTRL_DOWN|PSP_CTRL_UP|PSP_CTRL_LEFT|PSP_CTRL_RIGHT)
|
||||
#define PSP_4BUTTONS (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)
|
||||
#define PSP_TRIGGERS (PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER)
|
||||
|
||||
#define PAD_CHECK_TIME 53
|
||||
|
||||
void InputHandler::init() {
|
||||
sceCtrlSetSamplingCycle(0); // set sampling to vsync. n = n usecs
|
||||
sceCtrlSetSamplingMode(1); // analog
|
||||
}
|
||||
|
||||
bool InputHandler::getAllInputs(Common::Event &event) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
uint32 time = g_system->getMillis(); // may not be necessary with read
|
||||
if (time - _lastPadCheckTime < PAD_CHECK_TIME) {
|
||||
DEBUG_EXIT_FUNC();
|
||||
return false;
|
||||
}
|
||||
|
||||
_lastPadCheckTime = time;
|
||||
SceCtrlData pad;
|
||||
|
||||
sceCtrlPeekBufferPositive(&pad, 1); // Peek ignores sleep. Read sleeps thread
|
||||
|
||||
bool haveEvent;
|
||||
|
||||
memset(&event, 0, sizeof(event));
|
||||
|
||||
if (_keyboard->isVisible())
|
||||
haveEvent = _keyboard->processInput(event, pad);
|
||||
else
|
||||
haveEvent = getEvent(event, pad);
|
||||
|
||||
if (haveEvent)
|
||||
{
|
||||
PSP_DEBUG_PRINT("Have event[%s]\n", haveEvent ? "true" : "false");
|
||||
PSP_DEBUG_PRINT("event.type[%d]\n", event.type);
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
|
||||
return haveEvent;
|
||||
}
|
||||
|
||||
bool InputHandler::getEvent(Common::Event &event, SceCtrlData &pad) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_buttonsChanged = pad.Buttons ^ _prevButtons;
|
||||
bool haveEvent = false;
|
||||
|
||||
// Collect events from different sources
|
||||
haveEvent = getDpadEvent(event, pad);
|
||||
|
||||
if (!haveEvent)
|
||||
haveEvent = getButtonEvent(event, pad);
|
||||
|
||||
if (!haveEvent)
|
||||
haveEvent = getNubEvent(event, pad);
|
||||
|
||||
_prevButtons = pad.Buttons;
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return haveEvent;
|
||||
}
|
||||
|
||||
bool InputHandler::getDpadEvent(Common::Event &event, SceCtrlData &pad) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
int newDpadX = 0, newDpadY = 0;
|
||||
bool haveEvent = false;
|
||||
|
||||
if (DOWN(PSP_CTRL_UP)) {
|
||||
newDpadY++;
|
||||
if (DOWN(PSP_CTRL_RTRIGGER)) // Shifting causes diagonals
|
||||
newDpadX++;
|
||||
}
|
||||
if (DOWN(PSP_CTRL_RIGHT)) {
|
||||
newDpadX++;
|
||||
if (DOWN(PSP_CTRL_RTRIGGER))
|
||||
newDpadY--;
|
||||
}
|
||||
if (DOWN(PSP_CTRL_DOWN)) {
|
||||
newDpadY--;
|
||||
if (DOWN(PSP_CTRL_RTRIGGER))
|
||||
newDpadX--;
|
||||
}
|
||||
if (DOWN(PSP_CTRL_LEFT)) {
|
||||
newDpadX--;
|
||||
if (DOWN(PSP_CTRL_RTRIGGER))
|
||||
newDpadY++;
|
||||
}
|
||||
|
||||
if (newDpadX != _dpadX || newDpadY != _dpadY) {
|
||||
if (_dpadX == 0 && _dpadY == 0) { // We were in the middle so we pressed dpad
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
event.kbd.keycode = translateDpad(newDpadX, newDpadY);
|
||||
event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0'; // Get ascii
|
||||
_dpadX = newDpadX;
|
||||
_dpadY = newDpadY;
|
||||
}
|
||||
else if (newDpadX == 0 && newDpadY == 0) {// We're now centered so we unpressed dpad
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
event.kbd.keycode = translateDpad(_dpadX, _dpadY);
|
||||
event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
|
||||
_dpadX = newDpadX;
|
||||
_dpadY = newDpadY;
|
||||
} else { // we moved from one pressed dpad direction to another one
|
||||
event.type = Common::EVENT_KEYUP; // first release the last dpad direction
|
||||
event.kbd.keycode = translateDpad(_dpadX, _dpadY);
|
||||
event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
|
||||
_dpadX = 0; // so that we'll pick up a new dpad movement the next round
|
||||
_dpadY = 0;
|
||||
}
|
||||
|
||||
PSP_DEBUG_PRINT("Keypad event. DpadX[%d], DpadY[%d]\n", _dpadX, _dpadY);
|
||||
haveEvent = true;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return haveEvent;
|
||||
}
|
||||
|
||||
inline Common::KeyCode InputHandler::translateDpad(int x, int y) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
Common::KeyCode key;
|
||||
|
||||
if (x == -1) {
|
||||
if (y == -1)
|
||||
key = Common::KEYCODE_KP1;
|
||||
else if (y == 0)
|
||||
key = Common::KEYCODE_KP4;
|
||||
else /* y == 1 */
|
||||
key = Common::KEYCODE_KP7;
|
||||
} else if (x == 0) {
|
||||
if (y == -1)
|
||||
key = Common::KEYCODE_KP2;
|
||||
else /* y == 1 */
|
||||
key = Common::KEYCODE_KP8;
|
||||
} else {/* x == 1 */
|
||||
if (y == -1)
|
||||
key = Common::KEYCODE_KP3;
|
||||
else if (y == 0)
|
||||
key = Common::KEYCODE_KP6;
|
||||
else /* y == 1 */
|
||||
key = Common::KEYCODE_KP9;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
bool InputHandler::getButtonEvent(Common::Event &event, SceCtrlData &pad) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
bool haveEvent = false;
|
||||
|
||||
if (PRESSED(PSP_CTRL_SELECT))
|
||||
_keyboard->setVisible(true);
|
||||
|
||||
else if (CHANGED(PSP_4BUTTONS | PSP_TRIGGERS | PSP_CTRL_START)) {
|
||||
if (CHANGED(PSP_CTRL_CROSS)) {
|
||||
event.type = DOWN(PSP_CTRL_CROSS) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP;
|
||||
event.mouse.x = _cursor->getX(); // Could this have to do with SCI enter problem?
|
||||
event.mouse.y = _cursor->getY();
|
||||
PSP_DEBUG_PRINT("%s\n", event.type == Common::EVENT_LBUTTONDOWN ? "LButtonDown" : "LButtonUp");
|
||||
} else if (CHANGED(PSP_CTRL_CIRCLE)) {
|
||||
event.type = DOWN(PSP_CTRL_CIRCLE) ? Common::EVENT_RBUTTONDOWN : Common::EVENT_RBUTTONUP;
|
||||
event.mouse.x = _cursor->getX();
|
||||
event.mouse.y = _cursor->getY();
|
||||
PSP_DEBUG_PRINT("%s\n", event.type == Common::EVENT_LBUTTONDOWN ? "RButtonDown" : "RButtonUp");
|
||||
} 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 (CHANGED(PSP_CTRL_LTRIGGER)) {
|
||||
event.kbd.keycode = Common::KEYCODE_ESCAPE;
|
||||
event.kbd.ascii = 27;
|
||||
} else if (CHANGED(PSP_CTRL_START)) {
|
||||
event.kbd.keycode = Common::KEYCODE_F5;
|
||||
event.kbd.ascii = Common::ASCII_F5;
|
||||
if (DOWN(PSP_CTRL_RTRIGGER)) {
|
||||
event.kbd.flags |= Common::KBD_CTRL; // Main menu to allow RTL
|
||||
}
|
||||
} else if (CHANGED(PSP_CTRL_SQUARE)) {
|
||||
event.kbd.keycode = Common::KEYCODE_PERIOD;
|
||||
event.kbd.ascii = '.';
|
||||
} else if (CHANGED(PSP_CTRL_TRIANGLE)) {
|
||||
event.kbd.keycode = Common::KEYCODE_RETURN;
|
||||
event.kbd.ascii = '\r';
|
||||
} else if (DOWN(PSP_CTRL_RTRIGGER)) { // An event
|
||||
event.kbd.flags |= Common::KBD_SHIFT;
|
||||
}
|
||||
PSP_DEBUG_PRINT("Ascii[%d]. Key %s.\n", event.kbd.ascii, event.type == Common::EVENT_KEYDOWN ? "down" : "up" );
|
||||
}
|
||||
|
||||
haveEvent = true;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return haveEvent;
|
||||
}
|
||||
|
||||
bool InputHandler::getNubEvent(Common::Event &event, SceCtrlData &pad) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
bool haveEvent = false;
|
||||
int32 analogStepX = pad.Lx; // Goes up to 255.
|
||||
int32 analogStepY = pad.Ly;
|
||||
|
||||
int32 oldX = _cursor->getX();
|
||||
int32 oldY = _cursor->getY();
|
||||
|
||||
analogStepX = modifyNubAxisMotion(analogStepX);
|
||||
analogStepY = modifyNubAxisMotion(analogStepY);
|
||||
|
||||
if (analogStepX != 0 || analogStepY != 0) {
|
||||
|
||||
PSP_DEBUG_PRINT("raw x[%d], y[%d]\n", analogStepX, analogStepY);
|
||||
|
||||
// If no movement then this has no effect
|
||||
if (DOWN(PSP_CTRL_RTRIGGER)) {
|
||||
// Fine control mode for analog
|
||||
if (analogStepX != 0) {
|
||||
if (analogStepX > 0)
|
||||
_cursor->increaseXY(2, 0);
|
||||
else
|
||||
_cursor->increaseXY(-2, 0);
|
||||
}
|
||||
|
||||
if (analogStepY != 0) {
|
||||
if (analogStepY > 0)
|
||||
_cursor->increaseXY(0, 2);
|
||||
else
|
||||
_cursor->increaseXY(0, -2);
|
||||
}
|
||||
} else { // Regular speed movement
|
||||
_cursor->increaseXY(analogStepX, 0);
|
||||
_cursor->increaseXY(0, analogStepY);
|
||||
}
|
||||
|
||||
int32 newX = _cursor->getX();
|
||||
int32 newY = _cursor->getY();
|
||||
|
||||
if ((oldX != newX) || (oldY != newY)) {
|
||||
event.type = Common::EVENT_MOUSEMOVE;
|
||||
event.mouse.x = newX;
|
||||
event.mouse.y = newY;
|
||||
haveEvent = true;
|
||||
|
||||
PSP_DEBUG_PRINT("Nub event. X[%d], Y[%d]\n", newX, newY);
|
||||
}
|
||||
}
|
||||
DEBUG_EXIT_FUNC();
|
||||
return haveEvent;
|
||||
}
|
||||
|
||||
inline int32 InputHandler::modifyNubAxisMotion(int32 input) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
const int MIN_NUB_MOTION = 30;
|
||||
|
||||
input -= 128; // Center on 0.
|
||||
|
||||
if (input < -MIN_NUB_MOTION - 1)
|
||||
input += MIN_NUB_MOTION + 1; // reduce the velocity
|
||||
else if (input > MIN_NUB_MOTION)
|
||||
input -= MIN_NUB_MOTION; // same
|
||||
else // between these points, dampen the response to 0
|
||||
input = 0;
|
||||
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return input;
|
||||
}
|
63
backends/platform/psp/input.h
Normal file
63
backends/platform/psp/input.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
|
||||
* $Id: osys_psp.cpp 43618 2009-08-21 22:44:49Z joostp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSP_INPUT_H
|
||||
#define PSP_INPUT_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/events.h"
|
||||
#include "backends/platform/psp/display_client.h"
|
||||
#include "backends/platform/psp/default_display_client.h"
|
||||
#include "backends/platform/psp/pspkeyboard.h"
|
||||
#include "backends/platform/psp/cursor.h"
|
||||
#include <pspctrl.h>
|
||||
|
||||
class InputHandler {
|
||||
public:
|
||||
InputHandler() : _cursor(0), _keyboard(0), _prevButtons(0), _lastPadCheckTime(0), _buttonsChanged(0), _dpadX(0), _dpadY(0) {}
|
||||
|
||||
void init();
|
||||
bool getAllInputs(Common::Event &event);
|
||||
void setKeyboard(PSPKeyboard *keyboard) { _keyboard = keyboard; }
|
||||
void setCursor(Cursor *cursor) { _cursor = cursor; }
|
||||
|
||||
private:
|
||||
Cursor *_cursor;
|
||||
PSPKeyboard *_keyboard;
|
||||
uint32 _prevButtons;
|
||||
uint32 _lastPadCheckTime;
|
||||
uint32 _buttonsChanged;
|
||||
int32 _dpadX, _dpadY;
|
||||
int32 _accelX, _accelY;
|
||||
|
||||
bool getEvent(Common::Event &event, SceCtrlData &pad);
|
||||
bool getDpadEvent(Common::Event &event, SceCtrlData &pad);
|
||||
bool getButtonEvent(Common::Event &event, SceCtrlData &pad);
|
||||
bool getNubEvent(Common::Event &event, SceCtrlData &pad);
|
||||
int32 modifyNubAxisMotion(int32 input);
|
||||
Common::KeyCode translateDpad(int x, int y);
|
||||
};
|
||||
|
||||
#endif /* PSP_INPUT_H */
|
227
backends/platform/psp/memory.cpp
Normal file
227
backends/platform/psp/memory.cpp
Normal file
|
@ -0,0 +1,227 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
|
||||
* $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/singleton.h"
|
||||
#include "common/list.h"
|
||||
#include "backends/platform/psp/psppixelformat.h"
|
||||
#include "backends/platform/psp/memory.h"
|
||||
|
||||
// Class Copier --------------------------------------------------------------------------
|
||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
|
||||
//#define __PSP_DEBUG_PRINT__
|
||||
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
void Copier::copy(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat *format /* = NULL */) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
uint32 prefixDst = (((uint32)dst) & 0x3);
|
||||
prefixDst = prefixDst ? 4 - prefixDst : 0; // prefix only if we have address % 4 != 0
|
||||
uint32 prefixSrc = (((uint32)src) & 0x3);
|
||||
prefixSrc = prefixSrc ? 4 - prefixSrc : 0; // prefix only if we have address % 4 != 0
|
||||
uint32 *dst32, *src32;
|
||||
bool swapRB = format ? format->swapRB : false; // take swap value from pixelformat if it's given
|
||||
#ifdef __PSP_DEBUG_PRINT__
|
||||
uint32 debugBytes = bytes;
|
||||
const byte *debugDst = dst, *debugSrc = src;
|
||||
#endif
|
||||
uint32 words, remainingBytes;
|
||||
|
||||
//PSP_DEBUG_PRINT("dst[%p], src[%p], bytes[%d], swap[%s], prefixDst[%u], prefixSrc[%u]\n", dst, src, bytes, swapRB ? "true" : "false", prefixDst, prefixSrc);
|
||||
|
||||
if (prefixDst || prefixSrc) { // we're not aligned to word boundaries
|
||||
if (prefixDst != prefixSrc) { // worst case: we can never be aligned. this mode is highly inefficient. try to get engines not to use this mode too much
|
||||
PSP_DEBUG_PRINT("misaligned copy of %u bytes from %p to %p\n", bytes, src, dst);
|
||||
if ((prefixDst & 1) || (prefixSrc & 1))
|
||||
copy8(dst, src, bytes); // no swap is possible on 8 bit
|
||||
else
|
||||
copy16((uint16 *)dst, (uint16 *)src, bytes, format);
|
||||
|
||||
goto test;
|
||||
}
|
||||
|
||||
// Do the prefix: the part to get us aligned
|
||||
if (prefixDst & 1) { // byte
|
||||
copy8(dst, src, prefixDst); // no swap available
|
||||
} else { // short
|
||||
copy16((uint16 *)dst, (uint16 *)src, prefixDst, format);
|
||||
}
|
||||
if (bytes > prefixDst) // check that we can afford to subtract from bytes
|
||||
bytes -= prefixDst;
|
||||
else {
|
||||
DEBUG_EXIT_FUNC();
|
||||
return;
|
||||
}
|
||||
dst32 = (uint32 *)(dst + prefixDst);
|
||||
src32 = (uint32 *)(src + prefixSrc);
|
||||
} else { // We're aligned to word boundaries
|
||||
dst32 = (uint32 *)dst;
|
||||
src32 = (uint32 *)src;
|
||||
}
|
||||
|
||||
words = bytes >> 2;
|
||||
remainingBytes = bytes & 0x3;
|
||||
|
||||
if (swapRB) { // need to swap
|
||||
for (; words > 0; words--) {
|
||||
*dst32 = format->swapRedBlue32(*src32);
|
||||
dst32++;
|
||||
src32++;
|
||||
}
|
||||
} else { // no swapping
|
||||
for (; words > 0; words--) {
|
||||
*dst32 = *src32;
|
||||
dst32++;
|
||||
src32++;
|
||||
}
|
||||
}
|
||||
|
||||
// Do any remaining bytes
|
||||
if (remainingBytes) {
|
||||
if (remainingBytes & 1) // we have bytes left
|
||||
copy8((byte *)dst32, (byte *)src32, remainingBytes);
|
||||
else // 16bits left
|
||||
copy16((uint16*)dst32, (uint16 *)src32, remainingBytes, format);
|
||||
}
|
||||
|
||||
test:
|
||||
// debug
|
||||
#ifdef __PSP_DEBUG_PRINT__
|
||||
bool mismatch = false;
|
||||
|
||||
for (uint32 i=0; i<debugBytes; i++) {
|
||||
if (debugDst[i] != debugSrc[i]) {
|
||||
if (mismatch == false) {
|
||||
PSP_DEBUG_PRINT_SAMELN("mismatch in copy:\n");
|
||||
PSP_DEBUG_PRINT("dst[%p], src[%p], bytes[%u], swap[%s], prefixDst[%u], prefixSrc[%u]\n", debugDst, debugSrc, debugBytes, swapRB ? "true" : "false", prefixDst, prefixSrc);
|
||||
mismatch = true;
|
||||
}
|
||||
PSP_DEBUG_PRINT_SAMELN("%x!=%x ", debugSrc[i], debugDst[i]);
|
||||
}
|
||||
}
|
||||
if (mismatch)
|
||||
PSP_DEBUG_PRINT("\n");
|
||||
#endif
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
inline void Copier::copy8(byte *dst, const byte *src, uint32 bytes) {
|
||||
for (; bytes > 0; bytes--) {
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Copier::copy16(uint16 *dst, const uint16 *src, uint32 bytes, PSPPixelFormat *format /* = NULL */) {
|
||||
uint32 shorts = bytes >> 1;
|
||||
uint32 remainingBytes = bytes & 1;
|
||||
bool swapRB = format ? format->swapRB : false;
|
||||
|
||||
if (swapRB) {
|
||||
for (; shorts > 0 ; shorts--) {
|
||||
*dst = format->swapRedBlue16(*src);
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
} else {
|
||||
for (; shorts > 0 ; shorts--) {
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
if (remainingBytes)
|
||||
*(byte *)dst = *(byte *)src;
|
||||
}
|
||||
|
||||
|
||||
// Class VramAllocator -----------------------------------
|
||||
|
||||
DECLARE_SINGLETON(VramAllocator)
|
||||
|
||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
|
||||
//#define __PSP_DEBUG_PRINT__
|
||||
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
|
||||
void *VramAllocator::allocate(int32 size, bool smallAllocation /* = false */) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
assert (size > 0);
|
||||
|
||||
byte *lastAddress = smallAllocation ? (byte *)VRAM_SMALL_ADDRESS : (byte *)VRAM_START_ADDRESS;
|
||||
Common::List<Allocation>::iterator i;
|
||||
|
||||
// Find a block that fits, starting from the beginning
|
||||
for (i = _allocList.begin(); i != _allocList.end(); ++i) {
|
||||
byte *currAddress = (*i).address;
|
||||
|
||||
if (currAddress - lastAddress >= size) // We found a match
|
||||
break;
|
||||
|
||||
if ((*i).getEnd() > lastAddress)
|
||||
lastAddress = (byte *)(*i).getEnd();
|
||||
}
|
||||
|
||||
if (lastAddress + size > (byte *)VRAM_END_ADDRESS) {
|
||||
PSP_DEBUG_PRINT("No space for allocation of %d bytes. %d bytes already allocated.\n",
|
||||
size, _bytesAllocated);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_allocList.insert(i, Allocation(lastAddress, size));
|
||||
_bytesAllocated += size;
|
||||
|
||||
PSP_DEBUG_PRINT("Allocated in VRAM, size %u at %p.\n", size, lastAddress);
|
||||
PSP_DEBUG_PRINT("Total allocated %u, remaining %u.\n", _bytesAllocated, (2 * 1024 * 1024) - _bytesAllocated);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return lastAddress;
|
||||
}
|
||||
|
||||
// Deallocate a block from VRAM
|
||||
void VramAllocator::deallocate(void *address) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
address = (byte *)CACHED(address); // Make sure all addresses are the same
|
||||
|
||||
Common::List<Allocation>::iterator i;
|
||||
|
||||
// Find the Allocator to deallocate
|
||||
for (i = _allocList.begin(); i != _allocList.end(); ++i) {
|
||||
if ((*i).address == address) {
|
||||
_bytesAllocated -= (*i).size;
|
||||
_allocList.erase(i);
|
||||
PSP_DEBUG_PRINT("Deallocated address[%p], size[%u]\n", (*i).address, (*i).size);
|
||||
DEBUG_EXIT_FUNC();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PSP_DEBUG_PRINT("Address[%p] not allocated.\n", address);
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
80
backends/platform/psp/memory.h
Normal file
80
backends/platform/psp/memory.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
|
||||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
|
||||
* $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSP_MEMORY_H
|
||||
#define PSP_MEMORY_H
|
||||
|
||||
#define UNCACHED(x) ((byte *)(((uint32)(x)) | 0x40000000)) /* make an uncached access */
|
||||
#define CACHED(x) ((byte *)(((uint32)(x)) & 0xBFFFFFFF)) /* make an uncached access into a cached one */
|
||||
|
||||
/**
|
||||
* Class that does memory copying and swapping if needed
|
||||
*/
|
||||
class Copier {
|
||||
public:
|
||||
static void copy(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat *format = NULL);
|
||||
static void copy8(byte *dst, const byte *src, uint32 bytes);
|
||||
static void copy16(uint16 *dst, const uint16 *src, uint32 bytes, PSPPixelFormat *format = NULL);
|
||||
};
|
||||
|
||||
/**
|
||||
* Class that allocates memory in the VRAM
|
||||
*/
|
||||
class VramAllocator : public Common::Singleton<VramAllocator> {
|
||||
public:
|
||||
VramAllocator() : _bytesAllocated(0) {}
|
||||
void *allocate(int32 size, bool smallAllocation = false); // smallAllocation e.g. palettes
|
||||
void deallocate(void *pointer);
|
||||
|
||||
static inline bool isAddressInVram(void *address) {
|
||||
if ((uint32)(CACHED(address)) >= VRAM_START_ADDRESS && (uint32)(CACHED(address)) < VRAM_END_ADDRESS)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
* Used to allocate in VRAM
|
||||
*/
|
||||
struct Allocation {
|
||||
byte *address;
|
||||
uint32 size;
|
||||
void *getEnd() { return address + size; }
|
||||
Allocation(void *Address, uint32 Size) : address((byte *)Address), size(Size) {}
|
||||
Allocation() : address(0), size(0) {}
|
||||
};
|
||||
|
||||
enum {
|
||||
VRAM_START_ADDRESS = 0x04000000,
|
||||
VRAM_END_ADDRESS = 0x04200000,
|
||||
VRAM_SMALL_ADDRESS = VRAM_END_ADDRESS - (4*1024) // 4K in the end for small allocations
|
||||
};
|
||||
Common::List <Allocation> _allocList; // List of allocations
|
||||
uint32 _bytesAllocated;
|
||||
};
|
||||
|
||||
#endif /* PSP_MEMORY_H */
|
|
@ -1,9 +1,15 @@
|
|||
MODULE := backends/platform/psp
|
||||
|
||||
MODULE_OBJS := \
|
||||
powerman.o \
|
||||
MODULE_OBJS := powerman.o \
|
||||
psp_main.o \
|
||||
osys_psp.o \
|
||||
psppixelformat.o \
|
||||
memory.o \
|
||||
display_manager.o \
|
||||
display_client.o \
|
||||
default_display_client.o \
|
||||
input.o \
|
||||
cursor.o \
|
||||
trace.o \
|
||||
psploader.o \
|
||||
pspkeyboard.o
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -32,139 +32,123 @@
|
|||
#include "sound/mixer_intern.h"
|
||||
#include "backends/base-backend.h"
|
||||
#include "backends/fs/psp/psp-fs-factory.h"
|
||||
#include "backends/platform/psp/display_client.h"
|
||||
#include "backends/platform/psp/default_display_client.h"
|
||||
#include "backends/platform/psp/cursor.h"
|
||||
#include "backends/platform/psp/pspkeyboard.h"
|
||||
#include "backends/platform/psp/display_manager.h"
|
||||
#include "backends/platform/psp/input.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <pspctrl.h>
|
||||
|
||||
enum GraphicModeID {
|
||||
CENTERED_320X200,
|
||||
CENTERED_435X272,
|
||||
STRETCHED_480X272,
|
||||
CENTERED_362X272
|
||||
};
|
||||
|
||||
class OSystem_PSP : public BaseBackend {
|
||||
public:
|
||||
static const OSystem::GraphicsMode s_supportedGraphicsModes[];
|
||||
static OSystem *instance();
|
||||
|
||||
protected:
|
||||
struct Vertex {
|
||||
float u,v;
|
||||
float x,y,z;
|
||||
};
|
||||
|
||||
uint16 _screenWidth;
|
||||
uint16 _screenHeight;
|
||||
uint16 _overlayWidth;
|
||||
uint16 _overlayHeight;
|
||||
byte *_offscreen;
|
||||
OverlayColor *_overlayBuffer;
|
||||
uint16 _palette[256];
|
||||
bool _overlayVisible;
|
||||
uint32 _shakePos;
|
||||
uint32 _lastScreenUpdate;
|
||||
|
||||
Graphics::Surface _framebuffer;
|
||||
|
||||
bool _mouseVisible;
|
||||
int _mouseX, _mouseY;
|
||||
int _dpadX, _dpadY;
|
||||
int _mouseWidth, _mouseHeight;
|
||||
int _mouseHotspotX, _mouseHotspotY;
|
||||
byte _mouseKeyColour;
|
||||
byte *_mouseBuf;
|
||||
bool _cursorPaletteDisabled;
|
||||
|
||||
int _graphicMode;
|
||||
unsigned short* _clut;
|
||||
PSPKeyboard *_keyboard;
|
||||
|
||||
uint32 _prevButtons;
|
||||
uint32 _lastPadCheck;
|
||||
uint32 _padAccel;
|
||||
|
||||
SceCtrlData pad;
|
||||
|
||||
private:
|
||||
|
||||
Common::SaveFileManager *_savefile;
|
||||
Audio::MixerImpl *_mixer;
|
||||
Common::TimerManager *_timer;
|
||||
|
||||
Common::KeyCode getDpadEvent(int x, int y);
|
||||
// All needed sub-members
|
||||
Screen _screen;
|
||||
Overlay _overlay;
|
||||
Cursor _cursor;
|
||||
DisplayManager _displayManager;
|
||||
PSPKeyboard _keyboard;
|
||||
InputHandler _inputHandler;
|
||||
|
||||
void initSDL();
|
||||
|
||||
public:
|
||||
OSystem_PSP();
|
||||
virtual ~OSystem_PSP();
|
||||
OSystem_PSP() : _savefile(0), _mixer(0), _timer(0) {}
|
||||
~OSystem_PSP();
|
||||
|
||||
virtual void initBackend();
|
||||
|
||||
virtual bool hasFeature(Feature f);
|
||||
virtual void setFeatureState(Feature f, bool enable);
|
||||
virtual bool getFeatureState(Feature f);
|
||||
|
||||
virtual const GraphicsMode *getSupportedGraphicsModes() const;
|
||||
virtual int getDefaultGraphicsMode() const;
|
||||
virtual bool setGraphicsMode(int mode);
|
||||
static OSystem *instance();
|
||||
|
||||
void initBackend();
|
||||
|
||||
// Feature related
|
||||
bool hasFeature(Feature f);
|
||||
void setFeatureState(Feature f, bool enable);
|
||||
bool getFeatureState(Feature f);
|
||||
|
||||
// Graphics related
|
||||
const GraphicsMode *getSupportedGraphicsModes() const;
|
||||
int getDefaultGraphicsMode() const;
|
||||
bool setGraphicsMode(int mode);
|
||||
bool setGraphicsMode(const char *name);
|
||||
virtual int getGraphicsMode() const;
|
||||
int getGraphicsMode() const;
|
||||
#ifdef USE_RGB_COLOR
|
||||
virtual Graphics::PixelFormat getScreenFormat() const;
|
||||
virtual Common::List<Graphics::PixelFormat> getSupportedFormats();
|
||||
#endif
|
||||
|
||||
// Screen size
|
||||
void initSize(uint width, uint height, const Graphics::PixelFormat *format);
|
||||
int16 getWidth();
|
||||
int16 getHeight();
|
||||
|
||||
// Palette related
|
||||
void setPalette(const byte *colors, uint start, uint num);
|
||||
void grabPalette(byte *colors, uint start, uint num);
|
||||
void setCursorPalette(const byte *colors, uint start, uint num);
|
||||
void disableCursorPalette(bool disable);
|
||||
|
||||
// Screen related
|
||||
void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
|
||||
Graphics::Surface *lockScreen();
|
||||
void unlockScreen();
|
||||
void updateScreen();
|
||||
void setShakePos(int shakeOffset);
|
||||
|
||||
// Overlay related
|
||||
void showOverlay();
|
||||
void hideOverlay();
|
||||
void clearOverlay();
|
||||
void grabOverlay(OverlayColor *buf, int pitch);
|
||||
void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
|
||||
int16 getOverlayHeight();
|
||||
int16 getOverlayWidth();
|
||||
Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<4444>(); }
|
||||
|
||||
// Mouse related
|
||||
bool showMouse(bool visible);
|
||||
void warpMouse(int x, int y);
|
||||
void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
|
||||
|
||||
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
|
||||
virtual int16 getWidth();
|
||||
virtual int16 getHeight();
|
||||
// Events and input
|
||||
bool pollEvent(Common::Event &event);
|
||||
bool processInput(Common::Event &event);
|
||||
|
||||
virtual void setPalette(const byte *colors, uint start, uint num);
|
||||
virtual void grabPalette(byte *colors, uint start, uint num);
|
||||
virtual void setCursorPalette(const byte *colors, uint start, uint num);
|
||||
virtual void disableCursorPalette(bool disable);
|
||||
virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
|
||||
virtual Graphics::Surface *lockScreen();
|
||||
virtual void unlockScreen();
|
||||
virtual void updateScreen();
|
||||
virtual void setShakePos(int shakeOffset);
|
||||
|
||||
virtual void showOverlay();
|
||||
virtual void hideOverlay();
|
||||
virtual void clearOverlay();
|
||||
virtual void grabOverlay(OverlayColor *buf, int pitch);
|
||||
virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
|
||||
virtual int16 getOverlayHeight();
|
||||
virtual int16 getOverlayWidth();
|
||||
virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<4444>(); }
|
||||
|
||||
virtual bool showMouse(bool visible);
|
||||
virtual void warpMouse(int x, int y);
|
||||
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
|
||||
|
||||
virtual bool pollEvent(Common::Event &event);
|
||||
virtual bool processInput(Common::Event &event);
|
||||
|
||||
virtual uint32 getMillis();
|
||||
virtual void delayMillis(uint msecs);
|
||||
// Time
|
||||
uint32 getMillis();
|
||||
void delayMillis(uint msecs);
|
||||
|
||||
// Timer
|
||||
typedef int (*TimerProc)(int interval);
|
||||
virtual void setTimerCallback(TimerProc callback, int interval);
|
||||
|
||||
virtual MutexRef createMutex(void);
|
||||
virtual void lockMutex(MutexRef mutex);
|
||||
virtual void unlockMutex(MutexRef mutex);
|
||||
virtual void deleteMutex(MutexRef mutex);
|
||||
|
||||
static void mixCallback(void *sys, byte *samples, int len);
|
||||
virtual void setupMixer(void);
|
||||
|
||||
Common::SaveFileManager *getSavefileManager() { return _savefile; }
|
||||
Audio::Mixer *getMixer() { return _mixer; }
|
||||
void setTimerCallback(TimerProc callback, int interval);
|
||||
Common::TimerManager *getTimerManager() { return _timer; }
|
||||
|
||||
// Mutex
|
||||
MutexRef createMutex(void);
|
||||
void lockMutex(MutexRef mutex);
|
||||
void unlockMutex(MutexRef mutex);
|
||||
void deleteMutex(MutexRef mutex);
|
||||
|
||||
// Sound
|
||||
static void mixCallback(void *sys, byte *samples, int len);
|
||||
void setupMixer(void);
|
||||
Audio::Mixer *getMixer() { return _mixer; }
|
||||
|
||||
// Misc
|
||||
Common::SaveFileManager *getSavefileManager() { return _savefile; }
|
||||
FilesystemFactory *getFilesystemFactory() { return &PSPFilesystemFactory::instance(); }
|
||||
void getTimeAndDate(TimeDate &t) const;
|
||||
|
||||
virtual void quit();
|
||||
void quit();
|
||||
|
||||
Common::SeekableReadStream *createConfigReadStream();
|
||||
Common::WriteStream *createConfigWriteStream();
|
||||
|
||||
virtual Common::SeekableReadStream *createConfigReadStream();
|
||||
virtual Common::WriteStream *createConfigWriteStream();
|
||||
};
|
||||
|
||||
|
||||
#endif /* OSYS_PSP_H */
|
||||
|
|
|
@ -23,24 +23,23 @@
|
|||
*
|
||||
*/
|
||||
|
||||
//#define __PSP_DEBUG_FUNCS__ /* can put this locally too */
|
||||
//#define __PSP_DEBUG_PRINT__
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
#include <psppower.h>
|
||||
#include <pspthreadman.h>
|
||||
|
||||
#include "./powerman.h"
|
||||
#include "./trace.h"
|
||||
#include "backends/platform/psp/powerman.h"
|
||||
#include "engine.h"
|
||||
|
||||
DECLARE_SINGLETON(PowerManager)
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
void PowerManager::debugPM() {
|
||||
PSPDebugTrace("PM status is %d. Listcount is %d. CriticalCount is %d. ThreadId is %x. Error = %d\n", _PMStatus, _listCounter,
|
||||
_criticalCounter, sceKernelGetThreadId(), _error);
|
||||
// Function to debug the Power Manager (we have no output to screen)
|
||||
inline void PowerManager::debugPM() {
|
||||
PSP_DEBUG_PRINT("PM status[%d]. Listcount[%d]. CriticalCount[%d]. ThreadId[%x]. Error[%d]\n",
|
||||
_PMStatus, _listCounter, _criticalCounter, sceKernelGetThreadId(), _error);
|
||||
}
|
||||
#else
|
||||
#define debugPM()
|
||||
#define PMStatusSet(x)
|
||||
#endif /* __PSP_DEBUG_SUSPEND__ */
|
||||
|
||||
|
||||
/*******************************************
|
||||
|
@ -49,7 +48,8 @@ void PowerManager::debugPM() {
|
|||
*
|
||||
********************************************/
|
||||
PowerManager::PowerManager() {
|
||||
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
_flagMutex = NULL; /* Init mutex handle */
|
||||
_listMutex = NULL; /* Init mutex handle */
|
||||
_condSuspendable = NULL; /* Init condition variable */
|
||||
|
@ -57,33 +57,34 @@ PowerManager::PowerManager() {
|
|||
|
||||
_condSuspendable = SDL_CreateCond();
|
||||
if (_condSuspendable <= 0) {
|
||||
PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create condSuspendable\n");
|
||||
PSP_ERROR("Couldn't create Suspendable condition variable\n");
|
||||
}
|
||||
|
||||
_condPM = SDL_CreateCond();
|
||||
if (_condPM <= 0) {
|
||||
PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create condPM\n");
|
||||
PSP_ERROR("Couldn't create PM condition variable\n");
|
||||
}
|
||||
|
||||
_flagMutex = SDL_CreateMutex();
|
||||
if (_flagMutex <= 0) {
|
||||
PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create flagMutex\n");
|
||||
PSP_ERROR("Couldn't create flag Mutex\n");
|
||||
}
|
||||
|
||||
_listMutex = SDL_CreateMutex();
|
||||
if (_listMutex <= 0) {
|
||||
PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create listMutex\n");
|
||||
PSP_ERROR("Couldn't create list Mutex\n");
|
||||
}
|
||||
|
||||
_suspendFlag = false;
|
||||
_criticalCounter = 0;
|
||||
_pauseFlag = 0; _pauseFlagOld = 0; _pauseClientState = 0;
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
_criticalCounter = 0; // How many are in the critical section
|
||||
_pauseFlag = 0;
|
||||
_pauseFlagOld = 0;
|
||||
_pauseClientState = 0;
|
||||
_listCounter = 0;
|
||||
PMStatusSet(kInitDone);
|
||||
_error = 0;
|
||||
#endif
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
|
@ -92,26 +93,24 @@ PowerManager::PowerManager() {
|
|||
*
|
||||
********************************************/
|
||||
int PowerManager::registerSuspend(Suspendable *item) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
// Register in list
|
||||
PSPDebugSuspend("In registerSuspend\n");
|
||||
debugPM();
|
||||
|
||||
if (SDL_mutexP(_listMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::registerSuspend(): Couldn't lock _listMutex %d\n", _listMutex);
|
||||
PSP_ERROR("Couldn't lock _listMutex[%p]\n", _listMutex);
|
||||
}
|
||||
|
||||
_suspendList.push_front(item);
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
_listCounter++;
|
||||
#endif
|
||||
|
||||
if (SDL_mutexV(_listMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::registerSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
|
||||
PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
|
||||
}
|
||||
|
||||
PSPDebugSuspend("Out of registerSuspend\n");
|
||||
|
||||
debugPM();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -121,27 +120,25 @@ int PowerManager::registerSuspend(Suspendable *item) {
|
|||
*
|
||||
********************************************/
|
||||
int PowerManager::unregisterSuspend(Suspendable *item) {
|
||||
|
||||
PSPDebugSuspend("In unregisterSuspend\n");
|
||||
DEBUG_ENTER_FUNC();
|
||||
debugPM();
|
||||
|
||||
// Unregister from stream list
|
||||
if (SDL_mutexP(_listMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
|
||||
PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
|
||||
}
|
||||
|
||||
_suspendList.remove(item);
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
_listCounter--;
|
||||
#endif
|
||||
|
||||
if (SDL_mutexV(_listMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
|
||||
PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
|
||||
}
|
||||
|
||||
PSPDebugSuspend("Out of unregisterSuspend\n");
|
||||
PSP_DEBUG_PRINT("Out of unregisterSuspend\n");
|
||||
debugPM();
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -151,10 +148,9 @@ int PowerManager::unregisterSuspend(Suspendable *item) {
|
|||
*
|
||||
********************************************/
|
||||
PowerManager::~PowerManager() {
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
PMStatusSet(kDestroyPM);
|
||||
#endif
|
||||
|
||||
SDL_DestroyCond(_condSuspendable);
|
||||
_condSuspendable = 0;
|
||||
|
@ -167,6 +163,8 @@ int PowerManager::unregisterSuspend(Suspendable *item) {
|
|||
|
||||
SDL_DestroyMutex(_listMutex);
|
||||
_listMutex = 0;
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
|
@ -184,14 +182,14 @@ void PowerManager::pollPauseEngine() {
|
|||
|
||||
if ((pause != _pauseFlagOld) && g_engine) { // Check to see if we have an engine
|
||||
if (pause && _pauseClientState == PowerManager::Unpaused) {
|
||||
_pauseClientState = PowerManager::Pausing; // Tell PM we're in the middle of pausing
|
||||
_pauseClientState = PowerManager::Pausing; // Tell PM we're in the middle of pausing
|
||||
g_engine->pauseEngine(true);
|
||||
PSPDebugSuspend("Pausing engine in PowerManager::pollPauseEngine()\n");
|
||||
PSP_DEBUG_PRINT_FUNC("Pausing engine\n");
|
||||
_pauseClientState = PowerManager::Paused; // Tell PM we're done pausing
|
||||
}
|
||||
else if (!pause && _pauseClientState == PowerManager::Paused) {
|
||||
g_engine->pauseEngine(false);
|
||||
PSPDebugSuspend("Unpausing for resume in PowerManager::pollPauseEngine()\n");
|
||||
PSP_DEBUG_PRINT_FUNC("Unpausing for resume\n");
|
||||
_pauseClientState = PowerManager::Unpaused; // Tell PM we're in the middle of pausing
|
||||
}
|
||||
|
||||
|
@ -205,7 +203,7 @@ void PowerManager::pollPauseEngine() {
|
|||
* Use this for small critical sections where you can easily restore the previous state.
|
||||
*
|
||||
********************************************/
|
||||
int PowerManager::blockOnSuspend() {
|
||||
int PowerManager::blockOnSuspend() {
|
||||
return beginCriticalSection(true);
|
||||
}
|
||||
|
||||
|
@ -216,26 +214,28 @@ void PowerManager::pollPauseEngine() {
|
|||
* Make sure to call endCriticalSection or the PSP won't suspend.
|
||||
********************************************/
|
||||
|
||||
int PowerManager::beginCriticalSection(bool justBlock) {
|
||||
int PowerManager::beginCriticalSection(bool justBlock) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
|
||||
int ret = NotBlocked;
|
||||
|
||||
if (SDL_mutexP(_flagMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't lock flagMutex %d\n", _flagMutex);
|
||||
PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't lock flagMutex[%p]\n", _flagMutex);
|
||||
ret = Error;
|
||||
}
|
||||
|
||||
// Check the access flag
|
||||
if (_suspendFlag == true) {
|
||||
PSPDebugSuspend("We're being blocked!\n");
|
||||
PSP_DEBUG_PRINT("We're being blocked!\n");
|
||||
debugPM();
|
||||
ret = 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);
|
||||
PSP_DEBUG_PRINT("PowerManager::blockOnSuspend(): Couldn't wait on cond[%p]\n", _condSuspendable);
|
||||
}
|
||||
|
||||
PSPDebugSuspend("We got blocked!!\n");
|
||||
PSP_DEBUG_PRINT("We got blocked!!\n");
|
||||
debugPM();
|
||||
}
|
||||
|
||||
|
@ -244,18 +244,20 @@ void PowerManager::pollPauseEngine() {
|
|||
_criticalCounter++;
|
||||
|
||||
if (SDL_mutexV(_flagMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
|
||||
PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex[%p]\n", _flagMutex);
|
||||
ret = Error;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int PowerManager::endCriticalSection() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
int ret = 0;
|
||||
|
||||
if (SDL_mutexP(_flagMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't lock flagMutex %d\n", _flagMutex);
|
||||
PSP_ERROR("PowerManager::endCriticalSection(): Couldn't lock flagMutex[%p]\n", _flagMutex);
|
||||
ret = Error;
|
||||
}
|
||||
|
||||
|
@ -264,26 +266,27 @@ int PowerManager::endCriticalSection() {
|
|||
|
||||
if (_criticalCounter <= 0) {
|
||||
if (_suspendFlag == true) { // If the PM is sleeping, this flag must be set
|
||||
PSPDebugSuspend("Unblocked thread waking up the PM.\n");
|
||||
PSP_DEBUG_PRINT("Unblocked thread waking up the PM.\n");
|
||||
debugPM();
|
||||
|
||||
SDL_CondBroadcast(_condPM);
|
||||
|
||||
PSPDebugSuspend("Woke up the PM\n");
|
||||
PSP_DEBUG_PRINT("Woke up the PM\n");
|
||||
debugPM();
|
||||
}
|
||||
|
||||
if (_criticalCounter < 0) { // Check for bad usage of critical sections
|
||||
PSPDebugTrace("PowerManager::endCriticalSection(): Error! Critical counter is %d\n", _criticalCounter);
|
||||
PSP_ERROR("Critical counter[%d]\n", _criticalCounter);
|
||||
debugPM();
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_mutexV(_flagMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't unlock flagMutex %d\n", _flagMutex);
|
||||
PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
|
||||
ret = Error;
|
||||
}
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -293,6 +296,7 @@ int PowerManager::endCriticalSection() {
|
|||
*
|
||||
********************************************/
|
||||
int PowerManager::suspend() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
int ret = 0;
|
||||
|
||||
if (_pauseFlag) return ret; // Very important - make sure we only suspend once
|
||||
|
@ -325,7 +329,7 @@ int PowerManager::suspend() {
|
|||
// Now we set the suspend flag to true to cause reading threads to block
|
||||
|
||||
if (SDL_mutexP(_flagMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::suspend(): Couldn't lock flagMutex %d\n", _flagMutex);
|
||||
PSP_ERROR("Couldn't lock flagMutex[%p]\n", _flagMutex);
|
||||
_error = Error;
|
||||
ret = Error;
|
||||
}
|
||||
|
@ -342,7 +346,7 @@ int PowerManager::suspend() {
|
|||
}
|
||||
|
||||
if (SDL_mutexV(_flagMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::suspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
|
||||
PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
|
||||
_error = Error;
|
||||
ret = Error;
|
||||
}
|
||||
|
@ -351,22 +355,22 @@ int PowerManager::suspend() {
|
|||
|
||||
// Loop over list, calling suspend()
|
||||
if (SDL_mutexP(_listMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::suspend(): Couldn't lock listMutex %d\n", _listMutex);
|
||||
PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex);
|
||||
_error = Error;
|
||||
ret = Error;
|
||||
}
|
||||
PMStatusSet(kIteratingListSuspend);
|
||||
// Iterate
|
||||
Common::List<Suspendable *>::iterator i = _suspendList.begin();
|
||||
Common::List<Suspendable *>::iterator i;
|
||||
|
||||
for (; i != _suspendList.end(); ++i) {
|
||||
for (i = _suspendList.begin(); i != _suspendList.end(); ++i) {
|
||||
(*i)->suspend();
|
||||
}
|
||||
|
||||
PMStatusSet(kDoneIteratingListSuspend);
|
||||
|
||||
if (SDL_mutexV(_listMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::suspend(): Couldn't unlock listMutex %d\n", _listMutex);
|
||||
PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
|
||||
_error = Error;
|
||||
ret = Error;
|
||||
}
|
||||
|
@ -374,6 +378,7 @@ int PowerManager::suspend() {
|
|||
|
||||
scePowerUnlock(0); // Allow the PSP to go to sleep now
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -383,6 +388,7 @@ int PowerManager::suspend() {
|
|||
*
|
||||
********************************************/
|
||||
int PowerManager::resume() {
|
||||
DEBUG_ENTER_FUNC();
|
||||
int ret = 0;
|
||||
|
||||
// Make sure we can't get another suspend
|
||||
|
@ -394,7 +400,7 @@ int PowerManager::resume() {
|
|||
|
||||
// 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);
|
||||
PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex);
|
||||
_error = Error;
|
||||
ret = Error;
|
||||
}
|
||||
|
@ -409,7 +415,7 @@ int PowerManager::resume() {
|
|||
PMStatusSet(kDoneIteratingListResume);
|
||||
|
||||
if (SDL_mutexV(_listMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::resume(): Couldn't unlock listMutex %d\n", _listMutex);
|
||||
PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
|
||||
_error = Error;
|
||||
ret = Error;
|
||||
}
|
||||
|
@ -418,7 +424,7 @@ int PowerManager::resume() {
|
|||
|
||||
// Now we set the suspend flag to false
|
||||
if (SDL_mutexP(_flagMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::resume(): Couldn't lock flagMutex %d\n", _flagMutex);
|
||||
PSP_ERROR("Couldn't lock flagMutex %p\n", _flagMutex);
|
||||
_error = Error;
|
||||
ret = Error;
|
||||
}
|
||||
|
@ -430,14 +436,14 @@ int PowerManager::resume() {
|
|||
|
||||
// Signal the other threads to wake up
|
||||
if (SDL_CondBroadcast(_condSuspendable) != 0) {
|
||||
PSPDebugTrace("PowerManager::resume(): Couldn't broadcast condition %d\n", _condSuspendable);
|
||||
PSP_ERROR("Couldn't broadcast condition[%p]\n", _condSuspendable);
|
||||
_error = Error;
|
||||
ret = Error;
|
||||
}
|
||||
PMStatusSet(kDoneSignallingSuspendedThreadsResume);
|
||||
|
||||
if (SDL_mutexV(_flagMutex) != 0) {
|
||||
PSPDebugTrace("PowerManager::resume(): Couldn't unlock flagMutex %d\n", _flagMutex);
|
||||
PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
|
||||
_error = Error;
|
||||
ret = Error;
|
||||
}
|
||||
|
@ -447,5 +453,6 @@ int PowerManager::resume() {
|
|||
|
||||
scePowerUnlock(0); // Allow new suspends
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,6 @@ public:
|
|||
kDoneSignallingSuspendedThreadsResume,
|
||||
kDoneResume
|
||||
};
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
|
||||
volatile int _listCounter; /* How many people are in the list - just for debugging */
|
||||
|
||||
|
@ -129,11 +128,9 @@ public:
|
|||
public:
|
||||
int getPMStatus() { return _PMStatus; }
|
||||
|
||||
#endif /* __PSP_DEBUG_SUSPEND__ */
|
||||
|
||||
};
|
||||
|
||||
// For easy access
|
||||
#define PowerMan PowerManager::instance()
|
||||
|
||||
#endif /* POWERMAN_H */
|
||||
#endif /* POWERMAN_H */
|
||||
|
|
|
@ -26,8 +26,10 @@
|
|||
#define USERSPACE_ONLY //don't use kernel mode features
|
||||
|
||||
#ifndef USERSPACE_ONLY
|
||||
#include <pspkernel.h>
|
||||
#include <pspdebug.h>
|
||||
#include <pspkernel.h>
|
||||
#include <pspdebug.h>
|
||||
#else
|
||||
#include <pspuser.h>
|
||||
#endif
|
||||
|
||||
#include <psppower.h>
|
||||
|
@ -118,10 +120,10 @@ int CallbackThread(SceSize /*size*/, void *arg) {
|
|||
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");
|
||||
PSP_ERROR("Couldn't register callback for power_callback\n");
|
||||
}
|
||||
} else {
|
||||
PSPDebugTrace("SetupCallbacks(): Couldn't create a callback for power_callback\n");
|
||||
PSP_ERROR("Couldn't create a callback for power_callback\n");
|
||||
}
|
||||
|
||||
sceKernelSleepThreadCB();
|
||||
|
@ -167,4 +169,3 @@ int main(void) {
|
|||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,13 +28,14 @@
|
|||
|
||||
#include "common/events.h"
|
||||
#include "common/stream.h"
|
||||
#include "backends/platform/psp/display_client.h"
|
||||
#include <pspctrl.h>
|
||||
|
||||
//number of modes
|
||||
#define MODE_COUNT 4
|
||||
#define guiStringsSize 8 /* size of guistrings array */
|
||||
|
||||
class PSPKeyboard {
|
||||
class PSPKeyboard : public DisplayClient {
|
||||
|
||||
private:
|
||||
enum State {
|
||||
|
@ -49,58 +50,20 @@ private:
|
|||
public:
|
||||
PSPKeyboard();
|
||||
~PSPKeyboard();
|
||||
|
||||
bool load(); // Load keyboard into memory
|
||||
bool isInit() { return _init; } // Check for initialization
|
||||
bool isDirty() { return _dirty; } // Check if needs redrawing
|
||||
void setDirty() { _dirty = true; }
|
||||
void setClean() { _dirty = false; }
|
||||
bool isVisible() { return _state != kInvisible; } // Check if visible
|
||||
bool processInput(Common::Event &event, SceCtrlData &pad, bool &usedInput); // Process input
|
||||
void setVisible(bool val);
|
||||
bool processInput(Common::Event &event, SceCtrlData &pad); // Process input
|
||||
void moveTo(const int newX, const int newY); // Move keyboard
|
||||
void render(); // Draw the keyboard onscreen
|
||||
|
||||
private:
|
||||
struct gu_surface {
|
||||
u32 surface_width;
|
||||
u32 surface_height;
|
||||
u32 texture_width;
|
||||
u32 texture_height;
|
||||
u8 *texture;
|
||||
u32 *palette;
|
||||
u32 paletteSize;
|
||||
};
|
||||
|
||||
|
||||
// structures used for drawing the keyboard
|
||||
struct Vertex {
|
||||
float u, v;
|
||||
unsigned int color;
|
||||
float x,y,z;
|
||||
};
|
||||
|
||||
void surface_draw_offset(struct gu_surface* surface,
|
||||
int screenX, int screenY, int offsetX, int offsetY, int intWidth, int intHeight);
|
||||
void block_copy(gu_surface* surface, u8 *texture);
|
||||
int load_png_image(Common::SeekableReadStream *, unsigned char *ImageBuffer, uint32 *palette);
|
||||
int get_png_image_size(Common::SeekableReadStream *, uint32 *png_width, uint32 *png_height, u32 *paletteSize);
|
||||
uint32 convert_pow2(uint32 size);
|
||||
void flipNibbles(gu_surface* surface); // Convert to PSP 4-bit format
|
||||
void increaseKeyboardLocationX(int amount); // Move keyboard onscreen
|
||||
void increaseKeyboardLocationY(int amount);
|
||||
|
||||
static short _modeChar[MODE_COUNT][5][6];
|
||||
static const char *_guiStrings[];
|
||||
bool _init;
|
||||
unsigned int _prevButtons; // A bit pattern.
|
||||
bool _dirty; // keyboard needs redrawing
|
||||
int _mode; // charset selected. (0 - letters or 1 - numbers)
|
||||
int _moved_x; // location we've moved the KB to onscreen
|
||||
int _moved_y;
|
||||
bool _moved; // whether the keyboard was moved
|
||||
gu_surface _keyTextures[guiStringsSize];
|
||||
|
||||
State _state; // State of keyboard Keyboard state machine
|
||||
State _lastState;
|
||||
|
||||
enum Cursor {
|
||||
enum CursorDirections {
|
||||
kUp = 0,
|
||||
kRight,
|
||||
kDown,
|
||||
|
@ -108,8 +71,42 @@ private:
|
|||
kCenter
|
||||
};
|
||||
|
||||
Cursor _oldCursor; // Point to place of last cursor
|
||||
Buffer _buffers[guiStringsSize];
|
||||
Palette _palettes[guiStringsSize];
|
||||
GuRenderer _renderer;
|
||||
|
||||
int loadPngImage(Common::SeekableReadStream *file, Buffer &buffer, Palette &palette);
|
||||
int getPngImageSize(Common::SeekableReadStream *, uint32 *png_width, uint32 *png_height, u32 *paletteSize);
|
||||
uint32 convert_pow2(uint32 size);
|
||||
void increaseKeyboardLocationX(int amount); // Move keyboard onscreen
|
||||
void increaseKeyboardLocationY(int amount);
|
||||
void convertCursorToXY(CursorDirections cur, int &x, int &y);
|
||||
|
||||
void handleMoveState(SceCtrlData &pad);
|
||||
bool handleDefaultState(Common::Event &event, SceCtrlData &pad);
|
||||
bool handleCornersSelectedState(Common::Event &event, SceCtrlData &pad);
|
||||
bool getInputChoice(Common::Event &event, SceCtrlData &pad);
|
||||
void getCursorMovement(SceCtrlData &pad);
|
||||
void handleRTriggerDownState(SceCtrlData &pad);
|
||||
void handleLTriggerDownState(SceCtrlData &pad);
|
||||
|
||||
static short _modeChar[MODE_COUNT][5][6];
|
||||
static const char *_guiStrings[];
|
||||
bool _init;
|
||||
uint32 _prevButtons; // A bit pattern.
|
||||
uint32 _buttonsChanged;
|
||||
|
||||
bool _dirty; // keyboard needs redrawing
|
||||
int _mode; // charset selected. (0 - letters or 1 - numbers)
|
||||
int _movedX; // location we've moved the KB to onscreen
|
||||
int _movedY;
|
||||
bool _moved; // whether the keyboard was moved
|
||||
|
||||
State _state; // State of keyboard Keyboard state machine
|
||||
State _lastState;
|
||||
|
||||
CursorDirections _oldCursor; // Point to place of last cursor
|
||||
|
||||
};
|
||||
|
||||
#endif /* PSPKEYBOARD_H */
|
||||
#endif /* PSPKEYBOARD_H */
|
||||
|
|
|
@ -135,4 +135,3 @@ extern "C" {
|
|||
}
|
||||
|
||||
#endif /* PSPLOADER_H */
|
||||
|
||||
|
|
166
backends/platform/psp/psppixelformat.cpp
Normal file
166
backends/platform/psp/psppixelformat.cpp
Normal file
|
@ -0,0 +1,166 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
|
||||
* $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "backends/platform/psp/psppixelformat.h"
|
||||
|
||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
|
||||
//#define __PSP_DEBUG_PRINT__ /* For debug printouts */
|
||||
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
// class PSPPixelFormat --------------------------------------
|
||||
|
||||
void PSPPixelFormat::set(Type type, bool swap /* = false */) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
PSP_DEBUG_PRINT("type = %d\n", type);
|
||||
|
||||
format = type;
|
||||
swapRB = swap;
|
||||
|
||||
switch (type) {
|
||||
case Type_4444:
|
||||
case Type_5551:
|
||||
case Type_5650:
|
||||
bitsPerPixel = 16;
|
||||
break;
|
||||
case Type_8888:
|
||||
bitsPerPixel = 32;
|
||||
break;
|
||||
case Type_Palette_8bit:
|
||||
bitsPerPixel = 8;
|
||||
break;
|
||||
case Type_Palette_4bit:
|
||||
bitsPerPixel = 4;
|
||||
break;
|
||||
case Type_None:
|
||||
bitsPerPixel = 0;
|
||||
break;
|
||||
default: // This is an error, but let's continue anyway
|
||||
PSP_ERROR("Unhandled value of pixel type[%d]\n", type);
|
||||
bitsPerPixel = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
PSP_DEBUG_PRINT("bitsPerPixel[%u]\n", bitsPerPixel);
|
||||
DEBUG_EXIT_FUNC();
|
||||
}
|
||||
|
||||
// Convert from ScummVM general PixelFormat to our pixel format
|
||||
// For buffer and palette.
|
||||
void PSPPixelFormat::convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf,
|
||||
PSPPixelFormat::Type &bufferType,
|
||||
PSPPixelFormat::Type &paletteType,
|
||||
bool &swapRedBlue) {
|
||||
swapRedBlue = false; // no red-blue swap by default
|
||||
PSPPixelFormat::Type *target = 0; // which one we'll be filling
|
||||
|
||||
if (!pf) { // Default, pf is NULL
|
||||
bufferType = Type_Palette_8bit;
|
||||
paletteType = Type_5551;
|
||||
} else { // We have a pf
|
||||
if (pf->bytesPerPixel == 1) {
|
||||
bufferType = Type_Palette_8bit;
|
||||
target = &paletteType; // The type describes the palette
|
||||
} else if (pf->bytesPerPixel == 2) {
|
||||
paletteType = Type_None;
|
||||
target = &bufferType; // The type describes the buffer
|
||||
} else {
|
||||
PSP_ERROR("Unknown bpp[%u] in pixeltype. Reverting to 8bpp\n", pf->bytesPerPixel);
|
||||
bufferType = Type_Palette_8bit;
|
||||
target = &paletteType; // The type describes the palette
|
||||
}
|
||||
|
||||
// Find out the exact type of the target
|
||||
if (pf->rLoss == 3 && pf->bLoss == 3) {
|
||||
if (pf->gLoss == 3)
|
||||
*target = Type_5551;
|
||||
else
|
||||
*target = Type_5650;
|
||||
} else if (pf->rLoss == 4 && pf->gLoss == 4 && pf->bLoss == 4) {
|
||||
*target = Type_4444;
|
||||
} else if (pf->gLoss == 0 && pf->gShift == 8) {
|
||||
*target = Type_8888;
|
||||
} else if ((pf->gLoss == 0 && pf->gShift == 0) ||
|
||||
(pf->gLoss == 8 && pf->gShift == 0)) { // Default CLUT8 can have weird values
|
||||
*target = Type_5551;
|
||||
} else {
|
||||
PSP_ERROR("Unknown Scummvm pixel format.\n");
|
||||
PSP_ERROR("\trLoss[%d], gLoss[%d], bLoss[%d], aLoss[%d]\n\trShift[%d], gShift[%d], bShift[%d], aShift[%d]\n",
|
||||
pf->rLoss, pf->gLoss, pf->bLoss, pf->aLoss,
|
||||
pf->rShift, pf->gShift, pf->bShift, pf->aShift);
|
||||
*target = Type_Unknown;
|
||||
}
|
||||
|
||||
if (pf->rShift != 0) {// We allow backend swap of red and blue
|
||||
swapRedBlue = true;
|
||||
PSP_DEBUG_PRINT("detected red/blue swap\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Graphics::PixelFormat PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type type) {
|
||||
Graphics::PixelFormat pf;
|
||||
|
||||
switch(type) {
|
||||
case Type_4444:
|
||||
pf.bytesPerPixel = 2;
|
||||
pf.aLoss = 4; pf.rLoss = 4; pf.gLoss = 4; pf.bLoss = 4;
|
||||
pf.aShift = 12; pf.rShift = 0; pf.gShift = 4; pf.bShift = 8;
|
||||
break;
|
||||
case Type_5551:
|
||||
pf.bytesPerPixel = 2;
|
||||
pf.aLoss = 7; pf.rLoss = 3; pf.gLoss = 3; pf.bLoss = 3;
|
||||
pf.aShift = 15; pf.rShift = 0; pf.gShift = 5; pf.bShift = 10;
|
||||
break;
|
||||
case Type_5650:
|
||||
pf.bytesPerPixel = 2;
|
||||
pf.aLoss = 8; pf.rLoss = 3; pf.gLoss = 2; pf.bLoss = 3;
|
||||
pf.aShift = 0; pf.rShift = 0; pf.gShift = 5; pf.bShift = 11;
|
||||
break;
|
||||
case Type_8888:
|
||||
pf.bytesPerPixel = 4;
|
||||
pf.aLoss = 0; pf.rLoss = 0; pf.gLoss = 0; pf.bLoss = 0;
|
||||
pf.aShift = 24; pf.rShift = 0; pf.gShift = 8; pf.bShift = 16;
|
||||
break;
|
||||
default:
|
||||
PSP_ERROR("Unhandled PSPPixelFormat[%u]\n", type);
|
||||
break;
|
||||
}
|
||||
|
||||
return pf;
|
||||
}
|
||||
|
||||
uint32 PSPPixelFormat::convertTo32BitColor(uint32 color) {
|
||||
DEBUG_ENTER_FUNC();
|
||||
uint32 r,g,b,a, output;
|
||||
|
||||
colorToRgba(color, r, g, b, a);
|
||||
output = ((b << 16) | (g << 8) | (r << 0) | (a << 24));
|
||||
PSP_DEBUG_PRINT_FUNC("input color[%x], output[%x]\n", color, output);
|
||||
|
||||
DEBUG_EXIT_FUNC();
|
||||
return output;
|
||||
}
|
240
backends/platform/psp/psppixelformat.h
Normal file
240
backends/platform/psp/psppixelformat.h
Normal file
|
@ -0,0 +1,240 @@
|
|||
/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
|
||||
* $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSP_PIXEL_FORMAT_H
|
||||
#define PSP_PIXEL_FORMAT_H
|
||||
|
||||
#include "graphics/pixelformat.h"
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
/**
|
||||
* Specialized PixelFormat class
|
||||
* Supports only those formats which the PSP allows, including 4 bit palettes.
|
||||
* Also provides accurate color conversion (needed for color masking)
|
||||
* As well as swapping of red and blue channels (needed by HE games, for example)
|
||||
*/
|
||||
struct PSPPixelFormat{
|
||||
enum Type {
|
||||
Type_None,
|
||||
Type_4444,
|
||||
Type_5551,
|
||||
Type_5650,
|
||||
Type_8888,
|
||||
Type_Palette_8bit,
|
||||
Type_Palette_4bit,
|
||||
Type_Unknown
|
||||
};
|
||||
|
||||
Type format;
|
||||
uint32 bitsPerPixel; ///< Must match bpp of selected type
|
||||
bool swapRB; ///< Swap red and blue values when reading and writing
|
||||
|
||||
PSPPixelFormat() : format(Type_Unknown), bitsPerPixel(0), swapRB(false) {}
|
||||
void set(Type type, bool swap = false);
|
||||
static void convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf,
|
||||
PSPPixelFormat::Type &bufferType,
|
||||
PSPPixelFormat::Type &paletteType,
|
||||
bool &swapRedBlue);
|
||||
static Graphics::PixelFormat convertToScummvmPixelFormat(PSPPixelFormat::Type type);
|
||||
uint32 convertTo32BitColor(uint32 color);
|
||||
|
||||
inline uint32 rgbaToColor(uint32 r, uint32 g, uint32 b, uint32 a) {
|
||||
uint32 color;
|
||||
|
||||
switch(format) {
|
||||
case Type_4444:
|
||||
color = (((b >> 4) << 8) | ((g >> 4) << 4) | ((r >> 4) << 0) | ((a >> 4) << 12));
|
||||
break;
|
||||
case Type_5551:
|
||||
color = (((b >> 3) << 10) | ((g >> 3) << 5) | ((r >> 3) << 0) | ((a >> 7) << 15));
|
||||
break;
|
||||
case Type_5650:
|
||||
color = (((b >> 3) << 11) | ((g >> 2) << 5) | ((r >> 3) << 0));
|
||||
break;
|
||||
case Type_8888:
|
||||
color = (((b >> 0) << 16) | ((g >> 0) << 8) | ((r >> 0) << 0) | ((a >> 0) << 24));
|
||||
break;
|
||||
default:
|
||||
color = 0;
|
||||
break;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
inline void colorToRgba(uint32 color, uint32 &r, uint32 &g, uint32 &b, uint32 &a) {
|
||||
switch(format) {
|
||||
case Type_4444:
|
||||
a = (color >> 12) & 0xF; // Interpolate to get true colors
|
||||
b = (color >> 8) & 0xF;
|
||||
g = (color >> 4) & 0xF;
|
||||
r = (color >> 0) & 0xF;
|
||||
a = a << 4 | a;
|
||||
b = b << 4 | b;
|
||||
g = g << 4 | g;
|
||||
r = r << 4 | r;
|
||||
break;
|
||||
case Type_5551:
|
||||
a = (color >> 15) ? 0xFF : 0;
|
||||
b = (color >> 10) & 0x1F;
|
||||
g = (color >> 5) & 0x1F;
|
||||
r = (color >> 0) & 0x1F;
|
||||
b = b << 3 | b >> 2;
|
||||
g = g << 3 | g >> 2;
|
||||
r = r << 3 | r >> 2;
|
||||
break;
|
||||
case Type_5650:
|
||||
a = 0xFF;
|
||||
b = (color >> 11) & 0x1F;
|
||||
g = (color >> 5) & 0x3F;
|
||||
r = (color >> 0) & 0x1F;
|
||||
b = b << 3 | b >> 2;
|
||||
g = g << 2 | g >> 4;
|
||||
r = r << 3 | r >> 2;
|
||||
break;
|
||||
case Type_8888:
|
||||
a = (color >> 24) & 0xFF;
|
||||
b = (color >> 16) & 0xFF;
|
||||
g = (color >> 8) & 0xFF;
|
||||
r = (color >> 0) & 0xFF;
|
||||
break;
|
||||
default:
|
||||
a = b = g = r = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32 setColorAlpha(uint32 color, byte alpha) {
|
||||
switch(format) {
|
||||
case Type_4444:
|
||||
color = (color & 0x0FFF) | (((uint32)alpha >> 4) << 12);
|
||||
break;
|
||||
case Type_5551:
|
||||
color = (color & 0x7FFF) | (((uint32)alpha >> 7) << 15);
|
||||
break;
|
||||
case Type_8888:
|
||||
color = (color & 0x00FFFFFF) | ((uint32)alpha << 24);
|
||||
break;
|
||||
case Type_5650:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
inline uint32 pixelsToBytes(uint32 pixels) {
|
||||
switch (bitsPerPixel) {
|
||||
case 4:
|
||||
pixels >>= 1;
|
||||
break;
|
||||
case 16:
|
||||
pixels <<= 1;
|
||||
break;
|
||||
case 32:
|
||||
pixels <<= 2;
|
||||
break;
|
||||
case 8:
|
||||
break;
|
||||
default:
|
||||
PSP_ERROR("Incorrect bitsPerPixel value[%u]. pixels[%u]\n", bitsPerPixel, pixels);
|
||||
break;
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
inline uint16 swapRedBlue16(uint16 color) {
|
||||
uint16 output;
|
||||
|
||||
switch (format) {
|
||||
case Type_4444:
|
||||
output = (color & 0xf0f0) | ((color & 0x000f)<<8) | ((color & 0x0f00)>>8);
|
||||
break;
|
||||
case Type_5551:
|
||||
output = (color & 0x83e0) | ((color & 0x001f)<<10) | ((color & 0x7c00)>>10);
|
||||
break;
|
||||
case Type_5650:
|
||||
output = (color & 0x07e0) | ((color & 0x001f)<<11) | ((color & 0xf800)>>11);
|
||||
break;
|
||||
default:
|
||||
PSP_ERROR("invalid format[%u] for swapping\n", format);
|
||||
output = 0;
|
||||
break;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
inline uint32 swapRedBlue32(uint32 color) {
|
||||
uint32 output;
|
||||
|
||||
switch (format) {
|
||||
case Type_4444:
|
||||
output = (color & 0xf0f0f0f0) |
|
||||
((color & 0x000f000f)<<8) | ((color & 0x0f000f00)>>8);
|
||||
break;
|
||||
case Type_5551:
|
||||
output = (color & 0x83e083e0) |
|
||||
((color & 0x001f001f)<<10) | ((color & 0x7c007c00)>>10);
|
||||
break;
|
||||
case Type_5650:
|
||||
output = (color & 0x07e007e0) |
|
||||
((color & 0x001f001f)<<11) | ((color & 0xf800f800)>>11);
|
||||
break;
|
||||
case Type_8888:
|
||||
output = (color & 0xff00ff00) |
|
||||
((color & 0x000000ff)<<16) | ((color & 0x00ff0000)>>16);
|
||||
break;
|
||||
default:
|
||||
PSP_ERROR("invalid format[%u] for swapping\n", format);
|
||||
output = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Return whatever color we point at
|
||||
inline uint32 getColorValueAt(byte *pointer) {
|
||||
uint32 result;
|
||||
|
||||
switch (bitsPerPixel) {
|
||||
case 4: // We can't distinguish a 4 bit color with a pointer
|
||||
case 8:
|
||||
result = (uint32)*pointer;
|
||||
break;
|
||||
case 16:
|
||||
result = (uint32)*(uint16 *)pointer;
|
||||
break;
|
||||
case 32:
|
||||
result = *(uint32 *)pointer;
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
PSP_ERROR("Incorrect bitsPerPixel value[%u].\n", bitsPerPixel);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* PSP_PIXEL_FORMAT_H */
|
|
@ -23,47 +23,33 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "./trace.h"
|
||||
#define TRACE_C
|
||||
#include <pspkernel.h>
|
||||
#include <pspdebug.h>
|
||||
#include "backends/platform/psp/trace.h"
|
||||
|
||||
|
||||
int psp_debug_indent = 0;
|
||||
|
||||
void PSPDebugTrace (const char *format, ...) {
|
||||
#ifdef __PSP_DEBUG__
|
||||
void PSPDebugTrace (bool alsoToScreen, const char *format, ...) {
|
||||
va_list opt;
|
||||
char buff[2048];
|
||||
int bufsz, fd;
|
||||
char buffer[2048];
|
||||
int bufsz;
|
||||
FILE *fd = 0;
|
||||
|
||||
va_start(opt, format);
|
||||
bufsz = vsnprintf( buff, (size_t) sizeof(buff), format, opt);
|
||||
bufsz = vsnprintf( buffer, (size_t) sizeof(buffer), format, opt);
|
||||
va_end(opt);
|
||||
|
||||
fd = sceIoOpen("MS0:/DTRACE.TXT", PSP_O_RDWR | PSP_O_CREAT | PSP_O_APPEND, 0777);
|
||||
|
||||
if (fd <= 0)
|
||||
//fd = fopen("MS0:/SCUMMTRACE.TXT", "ab");
|
||||
fd = fopen("SCUMMTRACE.TXT", "ab");
|
||||
|
||||
if (fd == 0)
|
||||
return;
|
||||
|
||||
sceIoWrite(fd, (const void*)buff, bufsz);
|
||||
sceIoClose(fd);
|
||||
#endif /* __PSP_DEBUG__ */
|
||||
}
|
||||
|
||||
void PSPDebugTrace (const char * filename, const char *format, ...) {
|
||||
#ifdef __PSP_DEBUG__
|
||||
va_list opt;
|
||||
char buff[2048];
|
||||
int bufsz, fd;
|
||||
|
||||
va_start(opt, format);
|
||||
bufsz = vsnprintf( buff, (size_t) sizeof(buff), format, opt);
|
||||
va_end(opt);
|
||||
|
||||
fd = sceIoOpen(filename, PSP_O_RDWR | PSP_O_CREAT | PSP_O_APPEND, 0777);
|
||||
|
||||
if (fd <= 0)
|
||||
return;
|
||||
|
||||
sceIoWrite(fd, (const void*)buff, bufsz);
|
||||
sceIoClose(fd);
|
||||
#endif /* __PSP_DEBUG__ */
|
||||
fwrite(buffer, 1, bufsz, fd);
|
||||
fclose(fd);
|
||||
|
||||
if (alsoToScreen)
|
||||
fprintf(stderr, buffer);
|
||||
}
|
||||
|
|
|
@ -29,25 +29,94 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <psptypes.h>
|
||||
#include <pspkernel.h>
|
||||
#include <stdarg.h>
|
||||
#include <pspdebug.h>
|
||||
|
||||
// Use these defines for debugging
|
||||
|
||||
//#define __PSP_DEBUG__
|
||||
//#define __PSP_DEBUG_SUSPEND__
|
||||
//#define __PSP_PRINT_TO_FILE__
|
||||
//#define __PSP_PRINT_TO_FILE_AND_SCREEN__
|
||||
//#define __PSP_DEBUG_FUNCS__ /* can put this locally too */
|
||||
//#define __PSP_DEBUG_PRINT__
|
||||
|
||||
void PSPDebugTrace (const char *filename, const char *format, ...);
|
||||
void PSPDebugTrace (const char *format, ...);
|
||||
void PSPDebugTrace (bool alsoToScreen, const char *format, ...);
|
||||
|
||||
#ifdef __PSP_DEBUG_SUSPEND__
|
||||
#define PSPDebugSuspend(format,...) PSPDebugTrace(format, ## __VA_ARGS__)
|
||||
#else
|
||||
#define PSPDegbugSuspend(x)
|
||||
#define PSPDebugSuspend(format,...)
|
||||
#endif /* __PSP_DEBUG_SUSPEND__ */
|
||||
#ifndef TRACE_C
|
||||
extern int psp_debug_indent;
|
||||
#endif
|
||||
|
||||
#endif /* TRACE_H */
|
||||
|
||||
#endif // TRACE_H
|
||||
// From here on, we allow multiple definitions
|
||||
#undef __PSP_PRINT__
|
||||
#undef PSP_ERROR
|
||||
#undef __PSP_INDENT__
|
||||
#undef PSP_INFO_PRINT
|
||||
#undef PSP_INFO_PRINT_INDENT
|
||||
#undef PSP_DEBUG_PRINT
|
||||
#undef PSP_DEBUG_PRINT_FUNC
|
||||
#undef PSP_DEBUG_PRINT_SAMELN
|
||||
#undef PSP_DEBUG_DO
|
||||
#undef DEBUG_ENTER_FUNC
|
||||
#undef DEBUG_EXIT_FUNC
|
||||
#undef INLINE
|
||||
|
||||
/* Choose to print to file/screen/both */
|
||||
#ifdef __PSP_PRINT_TO_FILE__
|
||||
#define __PSP_PRINT__(format,...) PSPDebugTrace(false, format, ## __VA_ARGS__)
|
||||
#elif defined __PSP_PRINT_TO_FILE_AND_SCREEN__
|
||||
#define __PSP_PRINT__(format,...) PSPDebugTrace(true, format, ## __VA_ARGS__)
|
||||
#else /* default - print to screen */
|
||||
#define __PSP_PRINT__(format,...) fprintf(stderr, format, ## __VA_ARGS__)
|
||||
#endif /* PSP_PRINT_TO_FILE/SCREEN */
|
||||
|
||||
/* Error function */
|
||||
#define PSP_ERROR(format,...) __PSP_PRINT__("Error in %s: " format, __PRETTY_FUNCTION__, ## __VA_ARGS__)
|
||||
|
||||
/* Do the indent */
|
||||
#define __PSP_INDENT__ for(int _i=psp_debug_indent; _i>0; _i--) \
|
||||
__PSP_PRINT__( " ")
|
||||
|
||||
/* always print */
|
||||
#define PSP_INFO_PRINT(format,...) __PSP_PRINT__(format, ## __VA_ARGS__)
|
||||
/* always print, with indent */
|
||||
#define PSP_INFO_PRINT_INDENT(format,...) { __PSP_INDENT__; \
|
||||
__PSP_PRINT__(format, ## __VA_ARGS__); }
|
||||
|
||||
#ifdef __PSP_DEBUG_PRINT__
|
||||
/* printf with indents */
|
||||
#define PSP_DEBUG_PRINT_SAMELN(format,...) __PSP_PRINT__(format, ## __VA_ARGS__)
|
||||
#define PSP_DEBUG_PRINT(format,...) { __PSP_INDENT__; \
|
||||
__PSP_PRINT__(format, ## __VA_ARGS__); }
|
||||
#define PSP_DEBUG_PRINT_FUNC(format,...) { __PSP_INDENT__; \
|
||||
__PSP_PRINT__("In %s: " format, __PRETTY_FUNCTION__, ## __VA_ARGS__); }
|
||||
#define PSP_DEBUG_DO(x) (x)
|
||||
|
||||
#else /* no debug print */
|
||||
#define PSP_DEBUG_PRINT_SAMELN(format,...)
|
||||
#define PSP_DEBUG_PRINT(format,...)
|
||||
#define PSP_DEBUG_PRINT_FUNC(format,...)
|
||||
#define PSP_DEBUG_DO(x)
|
||||
#endif /* __PSP_DEBUG_PRINT__ */
|
||||
|
||||
/* Debugging function calls */
|
||||
#ifdef __PSP_DEBUG_FUNCS__
|
||||
#define DEBUG_ENTER_FUNC() PSP_INFO_PRINT_INDENT("++ %s\n", __PRETTY_FUNCTION__); \
|
||||
psp_debug_indent++
|
||||
|
||||
#define DEBUG_EXIT_FUNC() psp_debug_indent--; \
|
||||
if (psp_debug_indent < 0) PSP_ERROR("debug indent < 0\n"); \
|
||||
PSP_INFO_PRINT_INDENT("-- %s\n", __PRETTY_FUNCTION__)
|
||||
|
||||
#define INLINE /* don't want to inline so we get function names properly */
|
||||
|
||||
#else /* Don't debug function calls */
|
||||
#define DEBUG_ENTER_FUNC()
|
||||
#define DEBUG_EXIT_FUNC()
|
||||
#define INLINE inline
|
||||
#endif /* __PSP_DEBUG_FUNCS__ */
|
||||
|
||||
// Undef the main defines for next time
|
||||
#undef __PSP_PRINT_TO_FILE__
|
||||
#undef __PSP_PRINT_TO_FILE_AND_SCREEN__
|
||||
#undef __PSP_DEBUG_FUNCS__
|
||||
#undef __PSP_DEBUG_PRINT__
|
||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -1649,7 +1649,7 @@ fi
|
|||
# Enable 16bit support only for backends which support it
|
||||
#
|
||||
case $_backend in
|
||||
dreamcast | samsungtv | sdl | wii)
|
||||
dreamcast | samsungtv | sdl | wii | psp)
|
||||
if test "$_16bit" = auto ; then
|
||||
_16bit=yes
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue