Merged from trunk, from Rev 49499 to HEAD

svn-id: r50840
This commit is contained in:
Alejandro Marzini 2010-07-13 04:31:15 +00:00
commit 609e08d5db
608 changed files with 146447 additions and 31050 deletions

25
AUTHORS
View file

@ -318,6 +318,29 @@ Other contributions
Chris Gray - (retired)
Johannes Schickel
Translations
------------
Thierry Crozat - Translation Lead
Catalan:
Jordi Vilalta Prat
French:
Thierry Crozat
German:
Simon Sawatzki
Lothar Serra Mari
Hungarian:
Alex Bevilacqua
Italian:
Matteo Angelino
Russian:
Eugene Sandulenko
Websites (design)
-----------------
Dobo Balazs - Website design
@ -395,7 +418,7 @@ Other contributions
Ravi I. - SCI0 sound resource specification
Ruediger Hanke - Port to the MorphOS platform
Rune Orsval - Configuration file editor
Rickard Lind - MT32->GM MIDI mapping magic, sound research
Rickard Lind - MT-32->GM MIDI mapping magic, sound research
Rink Springer - Port to the DOS platform, several bug fixes
Robey Pointer - Bug tracking system hosting
Sergey Lapin - Port of Carl's type 2 decompression code

View file

@ -25,7 +25,7 @@ ifeq "$(HAVE_GCC)" "1"
# Turn off some annoying and not-so-useful warnings
CXXFLAGS+= -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder
# Enable even more warnings...
CXXFLAGS+= -Wpointer-arith -Wcast-qual -Wcast-align
CXXFLAGS+= -Wpointer-arith -Wcast-qual
CXXFLAGS+= -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings
# Currently we disable this gcc flag, since it will also warn in cases,

View file

@ -28,6 +28,7 @@ MODULES += \
engines \
graphics \
common \
po
ifdef USE_MT32EMU
MODULES += sound/softsynth/mt32

25
NEWS
View file

@ -8,11 +8,36 @@ For a more comprehensive changelog for the latest experimental SVN code, see:
General:
- Switched to the "fast" DOSBox OPL emulator.
- Fixed a crash in the rjp1 player code affecting the FOTAQ Amiga version.
- Added support for more original media layouts.
- Added support for GUI localization.
- Improved GUI by adding tooltips and radiobuttons.
- Improved GUI usability by hiding more irrelevant options not supported by
specific games.
AGI:
- Fixed number of GFX glitches.
- Made PIC drawing code picture perfect.
- Added support of MIDI devices.
- Added support for accurate Tandy sound emulation. Switched to it as default.
Drascula:
- Fixed number of GFX glitches.
- Made many cutscenes smoother.
- Changed behavior of items menu. Now it shows up on mouse up.
Groovie:
- Added support for the Macintosh version of The 7th Guest.
- Added support for custom MT-32 instruments.
Parallaction:
- Made part one of The Big Red Adventure completable.
SAGA:
- Fixed graphics glitches in several scenes.
SCUMM:
- Several improvements in Maniac Mansion NES.
PSP port:
- Switched to new backend design which fixes minor graphical issues,
speeds things up, and provides 16-bit support.

View file

@ -213,6 +213,7 @@ bool SdlEventManager::pollSdlEvent(Common::Event &event) {
}
SDL_Event ev;
ev.type = SDL_NOEVENT;
while (SDL_PollEvent(&ev)) {
preprocessEvents(&ev);
if (dispatchSDLEvent(ev, event))

View file

@ -28,6 +28,7 @@
#include "backends/events/symbiansdl/symbiansdl-events.h"
#include "backends/platform/symbian/src/SymbianActions.h"
#include "gui/message.h"
#include "common/translation.h"
#include <bautils.h>
@ -183,7 +184,7 @@ bool SymbianSdlEventManager::remapKey(SDL_Event &ev, Common::Event &event) {
case GUI::ACTION_QUIT:
{
GUI::MessageDialog alert("Do you want to quit ?", "Yes", "No");
GUI::MessageDialog alert(_("Do you want to quit ?"), _("Yes"), _("No"));
if (alert.runModal() == GUI::kMessageOK)
g_system->quit();

View file

@ -368,7 +368,7 @@ bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b
}
if (ERROR_NO_MORE_ENTRIES != IDOS->IoErr() ) {
debug(6, "An error occured during ExamineDir");
debug(6, "An error occurred during ExamineDir");
ret = false;
} else {
ret = true;

View file

@ -27,7 +27,7 @@
#include "backends/fs/ds/ds-fs.h"
#include "dsmain.h" //for the isGBAMPAvailable() function
DECLARE_SINGLETON(DSFilesystemFactory);
DECLARE_SINGLETON(DSFilesystemFactory)
AbstractFSNode *DSFilesystemFactory::makeRootFileNode() const {
if (DS::isGBAMPAvailable()) {

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -178,10 +181,10 @@ AbstractFSNode* DSFileSystemNode::getParent() const {
DSFileSystemNode *p;
if (_path != "ds:/") {
char *path = (char *) _path.c_str();
const char *path = (const char *)_path.c_str();
int lastSlash = 4;
for (int r = 4; r < (int) _path.size(); r++) {
for (uint r = 4; r < _path.size(); r++) {
if (path[r] == '\\') {
lastSlash = r;
}
@ -259,7 +262,7 @@ GBAMPFileSystemNode::GBAMPFileSystemNode(const Common::String& path) {
_path = path;
}
GBAMPFileSystemNode::GBAMPFileSystemNode(const Common::String& path, bool isDirectory) {
GBAMPFileSystemNode::GBAMPFileSystemNode(const Common::String& path, bool isDir) {
//consolePrintf("'%s'",path.c_str());
int lastSlash = 3;
@ -272,7 +275,7 @@ GBAMPFileSystemNode::GBAMPFileSystemNode(const Common::String& path, bool isDire
_displayName = Common::String(path.c_str() + lastSlash + 1);
_path = path;
_isValid = true;
_isDirectory = isDirectory;
_isDirectory = isDir;
}
@ -353,10 +356,10 @@ AbstractFSNode* GBAMPFileSystemNode::getParent() const {
GBAMPFileSystemNode *p;
if (_path != "mp:/") {
char *path = (char *) _path.c_str();
const char *path = (const char *)_path.c_str();
int lastSlash = 4;
for (int r = 4; r < (int) strlen((char *) path); r++) {
for (uint r = 4; r < strlen(path); r++) {
if (path[r] == '/') {
lastSlash = r;
}
@ -413,18 +416,12 @@ bool DSFileStream::eos() const {
}
int32 DSFileStream::pos() const {
if (_writeBufferPos > 0) {
// Discard constness. Bad, but I can't see another way.
((DSFileStream *) (this))->flush();
}
assert(_writeBufferPos == 0); // This method may only be called when reading!
return std_ftell((FILE *)_handle);
}
int32 DSFileStream::size() const {
if (_writeBufferPos > 0) {
// Discard constness. Bad, but I can't see another way.
((DSFileStream *) (this))->flush();
}
assert(_writeBufferPos == 0); // This method may only be called when reading!
int32 oldPos = std_ftell((FILE *)_handle);
std_fseek((FILE *)_handle, 0, SEEK_END);
int32 length = std_ftell((FILE *)_handle);
@ -444,16 +441,15 @@ uint32 DSFileStream::read(void *ptr, uint32 len) {
if (_writeBufferPos > 0) {
flush();
}
return std_fread((byte *)ptr, 1, len, (FILE *)_handle);
return std_fread(ptr, 1, len, (FILE *)_handle);
}
uint32 DSFileStream::write(const void *ptr, uint32 len) {
if (_writeBufferPos + len < WRITE_BUFFER_SIZE) {
memcpy(_writeBuffer + _writeBufferPos, ptr, len);
_writeBufferPos += len;
}
else
{
return len;
} else {
if (_writeBufferPos > 0) {
flush();
}
@ -483,29 +479,31 @@ DSFileStream *DSFileStream::makeFromPath(const Common::String &path, bool writeM
// Stdio replacements
#define MAX_FILE_HANDLES 32
enum {
MAX_FILE_HANDLES = 32
};
bool inited = false;
DS::fileHandle handle[MAX_FILE_HANDLES];
static bool inited = false;
static DS::fileHandle s_handle[MAX_FILE_HANDLES];
FILE *std_fopen(const char *name, const char *mode) {
if (!inited) {
for (int r = 0; r < MAX_FILE_HANDLES; r++) {
handle[r].used = false;
s_handle[r].used = false;
}
inited = true;
currentDir[0] = '\0';
}
char* realName = (char *) name;
char realName[MAXPATHLEN];
// Remove file system prefix
if ((name[0] == 'd') && (name[1] == 's') && (name[2] == ':') && (name[3] == '/')) {
realName += 4;
}
if ((name[0] == 'm') && (name[1] == 'p') && (name[2] == ':') && (name[3] == '/')) {
realName += 4;
strlcpy(realName, name + 4, MAXPATHLEN);
} else if ((name[0] == 'm') && (name[1] == 'p') && (name[2] == ':') && (name[3] == '/')) {
strlcpy(realName, name + 4, MAXPATHLEN);
} else {
strlcpy(realName, name, MAXPATHLEN);
}
// consolePrintf("Open file:");
@ -517,7 +515,8 @@ FILE* std_fopen(const char* name, const char* mode) {
// Turn all back slashes into forward slashes for gba_nds_fat
char *p = realName;
while (*p) {
if (*p == '\\') *p = '/';
if (*p == '\\')
*p = '/';
p++;
}
@ -538,32 +537,11 @@ FILE* std_fopen(const char* name, const char* mode) {
// Allocate a file handle
int r = 0;
while (handle[r].used) {
while (s_handle[r].used) {
r++;
assert(r < MAX_FILE_HANDLES);
}
#ifdef GBA_SRAM_SAVE
if (strchr(mode, 'w')) {
// consolePrintf("Writing %s\n", realName);
handle[r].sramFile = (DSSaveFile *) DSSaveFileManager::instance()->openSavefile(realName, true);
} else {
// consolePrintf("Reading %s\n", realName);
handle[r].sramFile = (DSSaveFile *) DSSaveFileManager::instance()->openSavefile(realName, false);
}
#endif
if (handle[r].sramFile) {
handle[r].used = true;
handle[r].pos = 0;
handle[r].data = NULL;
handle[r].size = handle[r].sramFile->getSize();
// consolePrintf("Found it");
return &handle[r];
}
// consolePrintf("Not in SRAM!");
char *data;
ZipFile *zip = DSFileSystemNode::getZip();
@ -578,7 +556,7 @@ FILE* std_fopen(const char* name, const char* mode) {
if (currentDir[0] != 0) {
char nameWithPath[128];
sprintf(nameWithPath, "%s\%s", currentDir, realName);
sprintf(nameWithPath, "%s\\%s", currentDir, realName);
strcpy(realName, nameWithPath);
}
@ -589,17 +567,18 @@ FILE* std_fopen(const char* name, const char* mode) {
zip->setAllFilesVisible(false);
// Allocate a file handle
int r = 0;
while (handle[r].used) r++;
r = 0;
while (s_handle[r].used)
r++;
handle[r].used = true;
handle[r].pos = 0;
handle[r].data = data;
handle[r].size = zip->getFileSize();
s_handle[r].used = true;
s_handle[r].pos = 0;
s_handle[r].data = data;
s_handle[r].size = zip->getFileSize();
// consolePrintf("Opened file %d: %s (%s) ", r, realName, name);
return &handle[r];
return &s_handle[r];
} else {
zip->setAllFilesVisible(false);
// consolePrintf("Not found: %s (%s) ", realName, name);
@ -615,19 +594,15 @@ void std_fclose(FILE* handle) {
}
handle->used = false;
if (handle->sramFile) {
delete handle->sramFile;
handle->sramFile = NULL;
}
}
size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
size_t std_fread(void *ptr, size_t size, size_t numItems, FILE *handle) {
// consolePrintf("fread %d,%d %d ", size, numItems, ptr);
if (DS::isGBAMPAvailable()) {
readPastEndOfFile = false;
int bytes = FAT_fread((void *) ptr, size, numItems, (FAT_FILE *) handle);
int bytes = FAT_fread(ptr, size, numItems, (FAT_FILE *) handle);
if (!FAT_feof((FAT_FILE *) handle)) {
return numItems;
} else {
@ -638,36 +613,22 @@ size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
return numItems;
}
if (handle->sramFile) {
int bytes = 0;
int result = 1;
//consolePrintf("fread size=", size * numItems);
for (int r = 0; (r < (s32) size * (s32) numItems) && (result > 0); r++) {
result = handle->sramFile->read((void *) ( ((char *) (ptr)) + r), 1);
bytes += result;
//consolePrintf("'%d',", ((char *) (ptr))[0]);
}
handle->pos += bytes;
return bytes / size;
}
if ((int)(handle->pos + size * numItems) > handle->size) {
if (handle->pos > handle->size)
numItems = 0;
else if ((int)(handle->pos + size * numItems) > handle->size)
numItems = (handle->size - handle->pos) / size;
if (numItems < 0) numItems = 0;
}
// consolePrintf("read %d ", size * numItems);
memcpy((void *) ptr, handle->data + handle->pos, size * numItems);
memcpy(ptr, handle->data + handle->pos, size * numItems);
handle->pos += size * numItems;
return numItems;
}
size_t std_fwrite(const void *ptr, size_t size, size_t numItems, FILE *handle) {
if ((handle == stdin)) return 0;
if ((handle == stdin))
return 0;
if ((handle == stderr) || (handle == stdout)) {
// consolePrintf((char *) ptr);
@ -677,7 +638,7 @@ size_t std_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) {
//consolePrintf("fwrite size=%d\n", size * numItems);
if (DS::isGBAMPAvailable()) {
FAT_fwrite(((char *) (ptr)), size, numItems, (FAT_FILE *) handle);
FAT_fwrite(ptr, size, numItems, (FAT_FILE *) handle);
return numItems;
int length = size * numItems;
@ -694,13 +655,8 @@ size_t std_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) {
return numItems;
}
if (handle->sramFile) {
handle->sramFile->write(ptr, size);
return size;
} else {
return 0;
}
}
bool std_feof(FILE *handle) {
// consolePrintf("feof ");
@ -709,10 +665,6 @@ bool std_feof(FILE* handle) {
return readPastEndOfFile && FAT_feof((FAT_FILE *) handle);
}
if (handle->sramFile) {
return handle->sramFile->eos();
}
// consolePrintf("feof %s", handle->pos >= handle->size? "true": "false");
return handle->pos >= handle->size;
}

View file

@ -8,28 +8,31 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef _DS_FS_H
#define _DS_FS_H
//#include <NDS/ARM9/console.h>
#include "common/fs.h"
#include "zipreader.h"
#include "ramsave.h"
#include "fat/gba_nds_fat.h"
#include "common/stream.h"
#include "backends/fs/abstract-fs.h"
#include "zipreader.h"
#include "fat/gba_nds_fat.h"
namespace DS {
/**
@ -163,14 +166,14 @@ struct fileHandle {
bool used;
char *data;
int size;
DSSaveFile* sramFile;
};
class DSFileStream : public Common::SeekableReadStream, public Common::WriteStream, public Common::NonCopyable {
protected:
static const int WRITE_BUFFER_SIZE = 512;
enum {
WRITE_BUFFER_SIZE = 512
};
/** File handle to the actual file. */
void *_handle;
@ -215,7 +218,7 @@ public:
// Please do not remove any of these prototypes that appear not to be required.
FILE* std_fopen(const char *name, const char *mode);
void std_fclose(FILE *handle);
size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle);
size_t std_fread(void *ptr, size_t size, size_t numItems, FILE *handle);
size_t std_fwrite(const void *ptr, size_t size, size_t numItems, FILE *handle);
bool std_feof(FILE *handle);
long int std_ftell(FILE *handle);
@ -224,6 +227,6 @@ void std_clearerr(FILE* handle);
int std_fflush(FILE *handle);
int std_ferror(FILE *handle);
} //namespace DS
} // End of namespace DS
#endif //_DS_FS_H

View file

@ -81,10 +81,10 @@ PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode)
PSPIoStream::~PSPIoStream() {
DEBUG_ENTER_FUNC();
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
if (PowerMan.beginCriticalSection())
PSP_DEBUG_PRINT_FUNC("Suspended\n");
PowerMan.unregisterSuspend(this); // Unregister with powermanager to be suspended
PowerMan.unregisterForSuspend(this); // Unregister with powermanager to be suspended
// 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
@ -100,7 +100,7 @@ PSPIoStream::~PSPIoStream() {
*/
void *PSPIoStream::open() {
DEBUG_ENTER_FUNC();
if (PowerMan.beginCriticalSection() == PowerManager::Blocked) {
if (PowerMan.beginCriticalSection()) {
// No need to open. Just return the _handle resume() already opened.
PSP_DEBUG_PRINT_FUNC("Suspended\n");
}
@ -118,7 +118,7 @@ void *PSPIoStream::open() {
_cache = (char *)memalign(64, CACHE_SIZE);
}
PowerMan.registerSuspend(this); // Register with the powermanager to be suspended
PowerMan.registerForSuspend(this); // Register with the powermanager to be suspended
PowerMan.endCriticalSection();
@ -233,7 +233,7 @@ uint32 PSPIoStream::read(void *ptr, uint32 len) {
}
}
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
if (PowerMan.beginCriticalSection())
PSP_DEBUG_PRINT_FUNC("Suspended\n");
@ -309,7 +309,7 @@ inline bool PSPIoStream::isOffsetInCache(uint32 offset) {
uint32 PSPIoStream::write(const void *ptr, uint32 len) {
DEBUG_ENTER_FUNC();
// Check if we can access the file
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
if (PowerMan.beginCriticalSection())
PSP_DEBUG_PRINT_FUNC("Suspended\n");
PSP_DEBUG_PRINT_FUNC("filename[%s], len[0x%x]\n", _path.c_str(), len);
@ -346,7 +346,7 @@ uint32 PSPIoStream::write(const void *ptr, uint32 len) {
bool PSPIoStream::flush() {
DEBUG_ENTER_FUNC();
// Enter critical section
if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
if (PowerMan.beginCriticalSection())
PSP_DEBUG_PRINT_FUNC("Suspended\n");
int ret = fflush((FILE *)_handle);

View file

@ -48,7 +48,7 @@ public:
virtual int getGraphicsMode() const = 0;
#ifdef USE_RGB_COLOR
virtual Graphics::PixelFormat getScreenFormat() const = 0;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() = 0;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const = 0;
#endif
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL) = 0;
virtual int getScreenChangeID() const = 0;

View file

@ -53,7 +53,7 @@ public:
virtual int getGraphicsMode() const;
#ifdef USE_RGB_COLOR
virtual Graphics::PixelFormat getScreenFormat() const;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() = 0;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const = 0;
#endif
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL);
virtual int getScreenChangeID() const;

View file

@ -57,7 +57,7 @@ const Graphics::PixelFormat RGBList[] = {
Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0), // RGBA4444
};
Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormats() {
Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormats() const {
static Common::List<Graphics::PixelFormat> list;
static bool inited = false;

View file

@ -45,7 +45,7 @@ public:
virtual void init();
#ifdef USE_RGB_COLOR
virtual Common::List<Graphics::PixelFormat> getSupportedFormats();
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
#endif
virtual void warpMouse(int x, int y);

View file

@ -29,6 +29,7 @@
#include "common/system.h"
#include "common/config-manager.h"
#include "common/mutex.h"
#include "common/translation.h"
#include "common/util.h"
#ifdef USE_RGB_COLOR
#include "common/list.h"
@ -41,7 +42,7 @@
#include "backends/events/sdl/sdl-events.h"
static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
{"1x", "Normal (no scaling)", GFX_NORMAL},
{"1x", _s("Normal (no scaling)"), GFX_NORMAL},
#ifdef USE_SCALERS
{"2x", "2x", GFX_DOUBLESIZE},
{"3x", "3x", GFX_TRIPLESIZE},
@ -97,11 +98,11 @@ AspectRatio::AspectRatio(int w, int h) {
}
#if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) && defined(USE_SCALERS)
static const size_t AR_COUNT = 4;
static const char* desiredAspectRatioAsStrings[AR_COUNT] = { "auto", "4/3", "16/9", "16/10" };
static const AspectRatio desiredAspectRatios[AR_COUNT] = { AspectRatio(0, 0), AspectRatio(4,3), AspectRatio(16,9), AspectRatio(16,10) };
static AspectRatio getDesiredAspectRatio() {
const size_t AR_COUNT = 4;
const char* desiredAspectRatioAsStrings[AR_COUNT] = { "auto", "4/3", "16/9", "16/10" };
const AspectRatio desiredAspectRatios[AR_COUNT] = { AspectRatio(0, 0), AspectRatio(4,3), AspectRatio(16,9), AspectRatio(16,10) };
//TODO : We could parse an arbitrary string, if we code enough proper validation
Common::String desiredAspectRatio = ConfMan.get("desired_screen_aspect_ratio");
@ -359,6 +360,25 @@ OSystem::TransactionError SdlGraphicsManager::endGFXTransaction() {
}
#ifdef USE_RGB_COLOR
Common::List<Graphics::PixelFormat> SdlGraphicsManager::getSupportedFormats() const {
assert(!_supportedFormats.empty());
return _supportedFormats;
}
void SdlGraphicsManager::detectSupportedFormats() {
// Clear old list
_supportedFormats.clear();
// Some tables with standard formats that we always list
// as "supported". If frontend code tries to use one of
// these, we will perform the necessary format
// conversion in the background. Of course this incurs a
// performance hit, but on desktop ports this should not
// matter. We still push the currently active format to
// the front, so if frontend code just uses the first
// available format, it will get one that is "cheap" to
// use.
const Graphics::PixelFormat RGBList[] = {
#ifdef ENABLE_32BIT
// RGBA8888, ARGB8888, RGB888
@ -388,17 +408,6 @@ const Graphics::PixelFormat BGRList[] = {
Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0)
};
// TODO: prioritize matching alpha masks
Common::List<Graphics::PixelFormat> SdlGraphicsManager::getSupportedFormats() {
static Common::List<Graphics::PixelFormat> list;
static bool inited = false;
if (inited)
return list;
bool BGR = false;
int listLength = ARRAYSIZE(RGBList);
Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
if (_hwscreen) {
// Get our currently set hardware format
@ -413,30 +422,30 @@ Common::List<Graphics::PixelFormat> SdlGraphicsManager::getSupportedFormats() {
format.aLoss = 8;
// Push it first, as the prefered format.
list.push_back(format);
if (format.bShift > format.rShift)
BGR = true;
// Mark that we don't need to do this any more.
inited = true;
_supportedFormats.push_back(format);
}
for (int i = 0; i < listLength; i++) {
if (inited && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
// TODO: prioritize matching alpha masks
int i;
// Push some RGB formats
for (i = 0; i < ARRAYSIZE(RGBList); i++) {
if (_hwscreen && (RGBList[i].bytesPerPixel > format.bytesPerPixel))
continue;
if (BGR) {
if (BGRList[i] != format)
list.push_back(BGRList[i]);
list.push_back(RGBList[i]);
} else {
if (RGBList[i] != format)
list.push_back(RGBList[i]);
list.push_back(BGRList[i]);
_supportedFormats.push_back(RGBList[i]);
}
// Push some BGR formats
for (i = 0; i < ARRAYSIZE(BGRList); i++) {
if (_hwscreen && (BGRList[i].bytesPerPixel > format.bytesPerPixel))
continue;
if (BGRList[i] != format)
_supportedFormats.push_back(BGRList[i]);
}
list.push_back(Graphics::PixelFormat::createFormatCLUT8());
return list;
// Finally, we always supposed 8 bit palette graphics
_supportedFormats.push_back(Graphics::PixelFormat::createFormatCLUT8());
}
#endif
@ -718,6 +727,10 @@ bool SdlGraphicsManager::loadGFXMode() {
_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
_videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
);
#ifdef USE_RGB_COLOR
detectSupportedFormats();
#endif
if (_hwscreen == NULL) {
// DON'T use error(), as this tries to bring up the debug
// console, which WON'T WORK now that _hwscreen is hosed.
@ -1531,6 +1544,10 @@ void SdlGraphicsManager::setMousePos(int x, int y) {
void SdlGraphicsManager::warpMouse(int x, int y) {
int y1 = y;
// Don't change mouse position, when mouse is outside of our window (in case of windowed mode)
if (!(SDL_GetAppState( ) & SDL_APPMOUSEFOCUS))
return;
if (_videoMode.aspectRatioCorrection && !_overlayVisible)
y1 = real2Aspect(y);

View file

@ -87,7 +87,7 @@ public:
virtual int getGraphicsMode() const;
#ifdef USE_RGB_COLOR
virtual Graphics::PixelFormat getScreenFormat() const { return _screenFormat; }
virtual Common::List<Graphics::PixelFormat> getSupportedFormats();
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
#endif
virtual void initSize(uint w, uint h, const Graphics::PixelFormat *format = NULL);
virtual int getScreenChangeID() const { return _screenChangeCount; }
@ -160,6 +160,13 @@ protected:
#ifdef USE_RGB_COLOR
Graphics::PixelFormat _screenFormat;
Graphics::PixelFormat _cursorFormat;
Common::List<Graphics::PixelFormat> _supportedFormats;
/**
* Update the list of supported pixel formats.
* This method is invoked by loadGFXMode().
*/
void detectSupportedFormats();
#endif
/** Temporary screen (for scalers) */

View file

@ -31,6 +31,8 @@
#include "gui/ScrollBarWidget.h"
#include "gui/ThemeEval.h"
#include "common/translation.h"
namespace Common {
enum {
@ -44,12 +46,12 @@ RemapDialog::RemapDialog()
_keymapper = g_system->getEventManager()->getKeymapper();
assert(_keymapper);
_kmPopUpDesc = new GUI::StaticTextWidget(this, "KeyMapper.PopupDesc", "Keymap:");
_kmPopUpDesc = new GUI::StaticTextWidget(this, "KeyMapper.PopupDesc", _("Keymap:"));
_kmPopUp = new GUI::PopUpWidget(this, "KeyMapper.Popup");
_scrollBar = new GUI::ScrollBarWidget(this, 0, 0, 0, 0);
new GUI::ButtonWidget(this, "KeyMapper.Close", "Close", kCloseCmd);
new GUI::ButtonWidget(this, "KeyMapper.Close", _("Close"), 0, kCloseCmd);
}
RemapDialog::~RemapDialog() {
@ -61,7 +63,7 @@ void RemapDialog::open() {
const Stack<Keymapper::MapRecord> &activeKeymaps = _keymapper->getActiveStack();
if (!(activeKeymaps.size() > 0)) {
_kmPopUp->appendEntry(activeKeymaps.top().keymap->getName() + " (Active)");
_kmPopUp->appendEntry(activeKeymaps.top().keymap->getName() + _(" (Active)"));
divider = true;
}
@ -95,7 +97,7 @@ void RemapDialog::open() {
if (divider)
_kmPopUp->appendEntry("");
for (it = _globalKeymaps->begin(); it != _globalKeymaps->end(); ++it) {
_kmPopUp->appendEntry(it->_value->getName() + " (Global)", idx);
_kmPopUp->appendEntry(it->_value->getName() + _(" (Global)"), idx);
_keymapTable[idx++] = it->_value;
}
divider = true;
@ -105,7 +107,7 @@ void RemapDialog::open() {
if (divider)
_kmPopUp->appendEntry("");
for (it = _gameKeymaps->begin(); it != _gameKeymaps->end(); ++it) {
_kmPopUp->appendEntry(it->_value->getName() + " (Game)", idx);
_kmPopUp->appendEntry(it->_value->getName() + _(" (Game)"), idx);
_keymapTable[idx++] = it->_value;
}
}
@ -168,7 +170,7 @@ void RemapDialog::reflowLayout() {
widg.actionText =
new GUI::StaticTextWidget(this, 0, 0, 0, 0, "", Graphics::kTextAlignRight);
widg.keyButton =
new GUI::ButtonWidget(this, 0, 0, 0, 0, "", kRemapCmd + i);
new GUI::ButtonWidget(this, 0, 0, 0, 0, "", 0, kRemapCmd + i);
_keymapWidgets.push_back(widg);
} else {
widg = _keymapWidgets[i];

View file

@ -269,7 +269,7 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver) const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits))
@ -315,21 +315,12 @@ MusicDevices AlsaMusicPlugin::getDevices() const {
return devices;
}
Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver) const {
Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_ALSA();
return Common::kNoError;
}
MidiDriver *MidiDriver_ALSA_create() {
MidiDriver *mididriver;
AlsaMusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
}
//#if PLUGIN_ENABLED_DYNAMIC(ALSA)
//REGISTER_PLUGIN_DYNAMIC(ALSA, PLUGIN_TYPE_MUSIC, AlsaMusicPlugin);
//#else

View file

@ -177,7 +177,7 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver) const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
MusicDevices CamdMusicPlugin::getDevices() const {
@ -188,21 +188,12 @@ MusicDevices CamdMusicPlugin::getDevices() const {
return devices;
}
Common::Error CamdMusicPlugin::createInstance(MidiDriver **mididriver) const {
Common::Error CamdMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_CAMD();
return Common::kNoError;
}
MidiDriver *MidiDriver_CAMD_create() {
MidiDriver *mididriver;
CamdMusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
}
//#if PLUGIN_ENABLED_DYNAMIC(CAMD)
//REGISTER_PLUGIN_DYNAMIC(CAMD, PLUGIN_TYPE_MUSIC, CamdMusicPlugin);
//#else

View file

@ -218,7 +218,7 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver) const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
MusicDevices CoreAudioMusicPlugin::getDevices() const {
@ -229,21 +229,12 @@ MusicDevices CoreAudioMusicPlugin::getDevices() const {
return devices;
}
Common::Error CoreAudioMusicPlugin::createInstance(MidiDriver **mididriver) const {
Common::Error CoreAudioMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_CORE();
return Common::kNoError;
}
MidiDriver *MidiDriver_CORE_create() {
MidiDriver *mididriver;
CoreAudioMusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
}
//#if PLUGIN_ENABLED_DYNAMIC(COREAUDIO)
//REGISTER_PLUGIN_DYNAMIC(COREAUDIO, PLUGIN_TYPE_MUSIC, CoreAudioMusicPlugin);
//#else

View file

@ -190,7 +190,7 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver) const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
MusicDevices CoreMIDIMusicPlugin::getDevices() const {
@ -201,21 +201,12 @@ MusicDevices CoreMIDIMusicPlugin::getDevices() const {
return devices;
}
Common::Error CoreMIDIMusicPlugin::createInstance(MidiDriver **mididriver) const {
Common::Error CoreMIDIMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_CoreMIDI();
return Common::kNoError;
}
MidiDriver *MidiDriver_CoreMIDI_create() {
MidiDriver *mididriver;
CoreMIDIMusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
}
//#if PLUGIN_ENABLED_DYNAMIC(COREMIDI)
//REGISTER_PLUGIN_DYNAMIC(COREMIDI, PLUGIN_TYPE_MUSIC, CoreMIDIMusicPlugin);
//#else

View file

@ -199,7 +199,7 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver) const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
MusicDevices DMediaMusicPlugin::getDevices() const {
@ -224,21 +224,12 @@ MusicDevices DMediaMusicPlugin::getDevices() const {
return devices;
}
Common::Error DMediaMusicPlugin::createInstance(MidiDriver **mididriver) const {
Common::Error DMediaMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_DMEDIA();
return Common::kNoError;
}
MidiDriver *MidiDriver_DMEDIA_create() {
MidiDriver *mididriver;
DMediaMusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
}
//#if PLUGIN_ENABLED_DYNAMIC(DMEDIA)
//REGISTER_PLUGIN_DYNAMIC(DMEDIA, PLUGIN_TYPE_MUSIC, DMediaMusicPlugin);
//#else

View file

@ -28,7 +28,7 @@
* both the QuickTime support and (vkeybd http://www.alsa-project.org/~iwai/alsa.html)
*/
#if defined(UNIX) && !defined(__BEOS__) && !defined(__MAEMO__) && !defined(__MINT__)
#if defined(UNIX) && !defined(__BEOS__) && !defined(__MAEMO__) && !defined(__MINT__) && !defined(__ANDROID__)
#include "common/util.h"
#include "sound/musicplugin.h"
@ -184,7 +184,7 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver) const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
MusicDevices SeqMusicPlugin::getDevices() const {
@ -195,21 +195,12 @@ MusicDevices SeqMusicPlugin::getDevices() const {
return devices;
}
Common::Error SeqMusicPlugin::createInstance(MidiDriver **mididriver) const {
Common::Error SeqMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_SEQ();
return Common::kNoError;
}
MidiDriver *MidiDriver_SEQ_create() {
MidiDriver *mididriver;
SeqMusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
}
//#if PLUGIN_ENABLED_DYNAMIC(SEQ)
//REGISTER_PLUGIN_DYNAMIC(SEQ, PLUGIN_TYPE_MUSIC, SeqMusicPlugin);
//#else

View file

@ -127,8 +127,7 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver)
const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
MusicDevices StMidiMusicPlugin::getDevices() const {
@ -139,21 +138,12 @@ MusicDevices StMidiMusicPlugin::getDevices() const {
return devices;
}
Common::Error StMidiMusicPlugin::createInstance(MidiDriver **mididriver) const {
Common::Error StMidiMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_STMIDI();
return Common::kNoError;
}
MidiDriver *MidiDriver_STMIDI_create() {
MidiDriver *mididriver;
StMidiMusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
}
//#if PLUGIN_ENABLED_DYNAMIC(STMIDI)
//REGISTER_PLUGIN_DYNAMIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin);
//#else

View file

@ -530,7 +530,7 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver) const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
MusicDevices TimidityMusicPlugin::getDevices() const {
@ -539,21 +539,12 @@ MusicDevices TimidityMusicPlugin::getDevices() const {
return devices;
}
Common::Error TimidityMusicPlugin::createInstance(MidiDriver **mididriver) const {
Common::Error TimidityMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_TIMIDITY();
return Common::kNoError;
}
MidiDriver *MidiDriver_TIMIDITY_create() {
MidiDriver *mididriver;
TimidityMusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
}
//#if PLUGIN_ENABLED_DYNAMIC(TIMIDITY)
//REGISTER_PLUGIN_DYNAMIC(TIMIDITY, PLUGIN_TYPE_MUSIC, TimidityMusicPlugin);
//#else

View file

@ -24,12 +24,15 @@
#if defined(WIN32) && !defined(_WIN32_WCE)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// winnt.h defines ARRAYSIZE, but we want our own one...
#undef ARRAYSIZE
#include "sound/musicplugin.h"
#include "sound/mpu401.h"
#include "common/config-manager.h"
#include "common/translation.h"
#include <mmsystem.h>
@ -46,11 +49,12 @@ private:
HANDLE _streamEvent;
HMIDIOUT _mo;
bool _isOpen;
int _device;
void check_error(MMRESULT result);
public:
MidiDriver_WIN() : _isOpen(false) { }
MidiDriver_WIN(int deviceIndex) : _isOpen(false), _device(deviceIndex) { }
int open();
void close();
void send(uint32 b);
@ -62,7 +66,7 @@ int MidiDriver_WIN::open() {
return MERR_ALREADY_OPEN;
_streamEvent = CreateEvent(NULL, true, true, NULL);
MMRESULT res = midiOutOpen((HMIDIOUT *)&_mo, MIDI_MAPPER, (DWORD_PTR)_streamEvent, 0, CALLBACK_EVENT);
MMRESULT res = midiOutOpen((HMIDIOUT *)&_mo, _device, (DWORD_PTR)_streamEvent, 0, CALLBACK_EVENT);
if (res != MMSYSERR_NOERROR) {
check_error(res);
CloseHandle(_streamEvent);
@ -150,7 +154,7 @@ void MidiDriver_WIN::check_error(MMRESULT result) {
class WindowsMusicPlugin : public MusicPluginObject {
public:
const char *getName() const {
return "Windows MIDI";
return _s("Windows MIDI");
}
const char *getId() const {
@ -158,30 +162,41 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver) const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
MusicDevices WindowsMusicPlugin::getDevices() const {
MusicDevices devices;
// TODO: Return a different music type depending on the configuration
// TODO: List the available devices
devices.push_back(MusicDevice(this, "", MT_GM));
int numDevs = midiOutGetNumDevs();
MIDIOUTCAPS tmp;
for (int i = 0; i < numDevs; i++) {
if (midiOutGetDevCaps(i, &tmp, sizeof(MIDIOUTCAPS)) != MMSYSERR_NOERROR)
break;
// There is no way to detect the "MusicType" so I just set it to MT_GM
// The user will have to manually select his MT32 type device and his GM type device.
devices.push_back(MusicDevice(this, tmp.szPname, MT_GM));
}
return devices;
}
Common::Error WindowsMusicPlugin::createInstance(MidiDriver **mididriver) const {
*mididriver = new MidiDriver_WIN();
Common::Error WindowsMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle dev) const {
int devIndex = 0;
bool found = false;
return Common::kNoError;
if (dev) {
MusicDevices i = getDevices();
for (MusicDevices::iterator d = i.begin(); d != i.end(); d++) {
if (d->getCompleteId().equals(MidiDriver::getDeviceString(dev, MidiDriver::kDeviceId))) {
found = true;
break;
}
devIndex++;
}
}
MidiDriver *MidiDriver_WIN_create() {
MidiDriver *mididriver;
WindowsMusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
*mididriver = new MidiDriver_WIN(found ? devIndex : 0);
return Common::kNoError;
}
//#if PLUGIN_ENABLED_DYNAMIC(WINDOWS)

View file

@ -117,7 +117,7 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver) const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
MusicDevices YamahaPa1MusicPlugin::getDevices() const {
@ -128,21 +128,12 @@ MusicDevices YamahaPa1MusicPlugin::getDevices() const {
return devices;
}
Common::Error YamahaPa1MusicPlugin::createInstance(MidiDriver **mididriver) const {
Common::Error YamahaPa1MusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_YamahaPa1();
return Common::kNoError;
}
MidiDriver *MidiDriver_YamahaPa1_create() {
MidiDriver *mididriver;
YamahaPa1MusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
}
//#if PLUGIN_ENABLED_DYNAMIC(YPA1)
//REGISTER_PLUGIN_DYNAMIC(YPA1, PLUGIN_TYPE_MUSIC, YamahaPa1MusicPlugin);
//#else

View file

@ -135,7 +135,7 @@ public:
}
MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver) const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
};
MusicDevices ZodiacMusicPlugin::getDevices() const {
@ -146,21 +146,12 @@ MusicDevices ZodiacMusicPlugin::getDevices() const {
return devices;
}
Common::Error ZodiacMusicPlugin::createInstance(MidiDriver **mididriver) const {
Common::Error ZodiacMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_Zodiac();
return Common::kNoError;
}
MidiDriver *MidiDriver_Zodiac_create() {
MidiDriver *mididriver;
ZodiacMusicPlugin p;
p.createInstance(&mididriver);
return mididriver;
}
//#if PLUGIN_ENABLED_DYNAMIC(ZODIAC)
//REGISTER_PLUGIN_DYNAMIC(ZODIAC, PLUGIN_TYPE_MUSIC, ZodiacMusicPlugin);
//#else

View file

@ -92,13 +92,15 @@ int ModularBackend::getGraphicsMode() const {
}
#ifdef USE_RGB_COLOR
Graphics::PixelFormat ModularBackend::getScreenFormat() const {
return _graphicsManager->getScreenFormat();
}
Common::List<Graphics::PixelFormat> ModularBackend::getSupportedFormats() {
Common::List<Graphics::PixelFormat> ModularBackend::getSupportedFormats() const {
return _graphicsManager->getSupportedFormats();
}
#endif
void ModularBackend::initSize(uint w, uint h, const Graphics::PixelFormat *format ) {

View file

@ -76,7 +76,7 @@ public:
virtual int getGraphicsMode() const;
#ifdef USE_RGB_COLOR
virtual Graphics::PixelFormat getScreenFormat() const;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats();
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
#endif
virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format = NULL);
virtual int getScreenChangeID() const;

View file

@ -29,6 +29,7 @@ MODULE_OBJS := \
graphics/gp2xwizsdl/gp2xwizsdl-graphics.o \
graphics/linuxmotosdl/linuxmotosdl-graphics.o \
graphics/opengl/glerrorcheck.o \
graphics/opengl/gltexture.o \
graphics/opengl/opengl-graphics.o \
graphics/openglsdl/openglsdl-graphics.o \
graphics/sdl/sdl-graphics.o \

View file

@ -107,7 +107,7 @@ static void SkinsFormExit(Boolean bSave) {
listP = (ListType *)GetObjectPtr(SkinsSkinList);
selected = LstGetSelection(listP);
if (bSave && selected == -1) { // may never occured...
if (bSave && selected == -1) { // may never occurred...
FrmCustomAlert(FrmWarnAlert, "You didn't select a skin.", 0, 0);
return;
}
@ -164,7 +164,7 @@ static void SkinsFormBeam() {
listP = (ListType *)GetObjectPtr(SkinsSkinList);
selected = LstGetSelection(listP);
if (selected == -1) { // may never occured...
if (selected == -1) { // may never occurred...
FrmCustomAlert(FrmWarnAlert, "You didn't select a skin.", 0, 0);
return;
}
@ -187,7 +187,7 @@ static void SkinsFormDelete() {
listP = (ListType *)GetObjectPtr(SkinsSkinList);
selected = LstGetSelection(listP);
if (selected == -1) { // may never occured...
if (selected == -1) { // may never occurred...
FrmCustomAlert(FrmInfoAlert, "You didn't select a skin.", 0, 0);
return;
}

View file

@ -258,7 +258,7 @@ static void MusicFormInit(UInt16 index) {
ogameInfoP = (GameInfoType *)MemHandleLock(recordH);
if (!ogameInfoP) {
FrmCustomAlert(FrmErrorAlert, "An error occured.",0,0);
FrmCustomAlert(FrmErrorAlert, "An error occurred.",0,0);
return;
}

View file

@ -468,7 +468,7 @@ Boolean StartScummVM(Int16 engine) {
return false;
}
// reset mode if screen rotation occured (DIA only)
// reset mode if screen rotation occurred (DIA only)
if (!direct && OPTIONS_TST(kOptCollapsible)) {
UInt8 mode = PalmScreenSize(0,0, &(gVars->screenFullWidth), &(gVars->screenFullHeight));
OPTIONS_RST(kOptModeLandscape);

View file

@ -2,31 +2,28 @@ Building the ScummVM Android port
=================================
You will need these things to build:
1. Android EGL headers and library
2. Android SDK
3. An arm-android-eabi GCC toolchain
1. Android SDK
2. An arm-oe-linux-androideabi GCC toolchain(*)
In the example commands, we are going to build against the Android 1.5
native ABI (but using the Android 1.6 SDK tools). Other version
combinations might/should be possible with a bit of tweaking.
(*) Any other sane Android toolchain should be easy to use, but this
is the toolchain prefix that is used by default. You can trivially
find and modify the single location where it appears in ./configure if
you have some other prefix variation.
In detail:
1. Android EGL headers and library
1. Android SDK
You can build these from the full Android source, but it is far easier
to just download the 3 Android EGL headers from here:
http://android.git.kernel.org/?p=platform/frameworks/base.git;a=tree;f=opengl/include/EGL;hb=HEAD
(copy them to a directory called "EGL" somewhere)
Download the SDK from http://developer.android.com/ and install
somewhere. You will need both the API level 8 (aka Android 2.2) and
API level 3 (aka Android 1.5) platforms.
... and grab libEGL.so off an existing phone/emulator:
adb pull /system/lib/libEGL.so /tmp
2. Android SDK
Download and install somewhere.
3. arm-android-eabi GCC toolchain
2. arm-*-linux-androideabi GCC toolchain
You have several choices for toolchains:
@ -36,7 +33,7 @@ This is shipped with both the Android source release and Android NDK.
The problem is that "arm-eabi-gcc" can't actually link anything
successfully without extra command line flags. To use this with the
ScummVM configure/build environment you will need to create a family
of shell wrapper scripts that convert "arm-android-eabi-foo" to
of shell wrapper scripts that convert "arm-oe-linux-androideabi-foo" to
"arm-eabi-foo -mandroid".
For example, I use this script:
@ -44,17 +41,24 @@ For example, I use this script:
exec arm-eabi-${0##*-} -mandroid -DANDROID "$@"
... and create a family of symlinks/hardlinks pointing to it called
arm-android-eabi-gcc, arm-android-eabi-g++, etc. For tools that don't
take a "-mandroid" argument - like arm-eabi-strip - I bypass the shell
wrapper and just create an arm-android-eabi-strip symlink to the tool
directly.
arm-oe-android-linuxeabi-gcc, arm-oe-android-linuxeabi-g++, etc. For
tools that don't take a "-mandroid" argument - like arm-eabi-strip - I
bypass the shell wrapper and just create an arm-oe-android-linuxeabi-strip
symlink to the tool directly.
- Build your own arm-android-eabi toolchain from GCC source.
In practice you will probably need significant linker command line
massaging in order to get the crtbegin/end and libraries all linked in
the right way. It's not hard to do manually, but it is annoying to
script in a general purpose way.
This is lots of fun. I suggest my Android openembedded patches, see:
http://wiki.github.com/anguslees/openembedded-android/
(You just need to have lots of disk space and type a few commands)
If you get stuck, ask
- Build your own arm-*-linux-androideabi toolchain from GCC source.
This is lots of fun, but will become significantly easier once gcc-4.6
is released. In the interim, I suggest using my precompiled Android
openembedded-based toolchain:
wget http://commondatastorage.googleapis.com/anr/sdk/android-2.2-i686-linux-armv5te-linux-androideabi-toolchain-android.tar.bz2
sudo tar jxf android-2.2-i686-linux-armv5te-linux-androideabi-toolchain-android.tar.bz2 -C /
. /usr/local/android/arm/environment-setup
Alternatively, do a websearch - there are several other cross-compile
toolchains around.
@ -63,18 +67,25 @@ toolchains around.
Building ScummVM
================
Apply the theme engine patch:
patch -p1 < backends/platform/android/scummvm-android-themeengine.patch
(Optionally) compress scummmodern.zip:
(ScummVM usually ships it uncompressed, but Android can read it more
efficiently if it is compressed *before* adding it to the apk)
( cd gui/themes/scummmodern && zip -f ../scummmodern.zip )
Then build ScummVM:
export ANDROID_SDK=<root of Android SDK>
PATH=$ANDROID_SDK/platforms/android-1.6/tools:$ANDROID_SDK/tools:$PATH
# You also want to ensure your arm-android-eabi toolchain is in your $PATH
# You also want to ensure your arm-oe-linux-androideabi toolchain is in $PATH
export ANDROID_TOP=<root of built Android source>
EGL_INC="-I<location of EGL/ header directory>"
EGL_LIBS="-L<location of libEGL.so>"
CPPFLAGS="$EGL_INC" \
LDFLAGS="-g $EGL_LIBS" \
./configure --backend=android --host=android --enable-zlib #and any other flags
make scummvm.apk

View file

@ -31,10 +31,6 @@
#if defined(ANDROID_BACKEND)
#define ANDROID_VERSION_GE(major,minor) \
(ANDROID_MAJOR_VERSION > (major) || \
(ANDROID_MAJOR_VERSION == (major) && ANDROID_MINOR_VERSION >= (minor)))
#include <jni.h>
#include <string.h>
@ -45,7 +41,6 @@
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
#include <android/log.h>
#include "common/archive.h"
@ -78,6 +73,14 @@
#undef JNIEXPORT
#define JNIEXPORT __attribute__ ((visibility("default")))
// This replaces the bionic libc assert message with something that
// actually prints the assertion failure before aborting.
extern "C"
void __assert(const char *file, int line, const char *expr) {
__android_log_assert(expr, LOG_TAG, "%s:%d: Assertion failure: %s",
file, line, expr);
}
static JavaVM *cached_jvm;
static jfieldID FID_Event_type;
static jfieldID FID_Event_synthetic;
@ -162,20 +165,19 @@ private:
jmethodID MID_getPluginDirectories;
jmethodID MID_setupScummVMSurface;
jmethodID MID_destroyScummVMSurface;
jmethodID MID_swapBuffers;
int _screen_changeid;
EGLDisplay _egl_display;
EGLSurface _egl_surface;
EGLint _egl_surface_width;
EGLint _egl_surface_height;
int _egl_surface_width;
int _egl_surface_height;
bool _force_redraw;
// Game layer
GLESPaletteTexture* _game_texture;
int _shake_offset;
Common::Rect _focus_rect;
bool _full_screen_dirty;
Common::Array<Common::Rect> _dirty_rects;
// Overlay layer
GLES4444Texture* _overlay_texture;
@ -195,6 +197,7 @@ private:
pthread_t _timer_thread;
static void* timerThreadFunc(void* arg);
bool _enable_zoning;
bool _virtkeybd_on;
Common::SaveFileManager *_savefile;
@ -217,6 +220,11 @@ public:
static OSystem_Android* fromJavaObject(JNIEnv* env, jobject obj);
virtual void initBackend();
void addPluginDirectories(Common::FSList &dirs) const;
void enableZoning(bool enable) { _enable_zoning = enable; }
void setSurfaceSize(int width, int height) {
_egl_surface_width = width;
_egl_surface_height = height;
}
virtual bool hasFeature(Feature f);
virtual void setFeatureState(Feature f, bool enable);
@ -297,8 +305,6 @@ public:
OSystem_Android::OSystem_Android(jobject am)
: _back_ptr(0),
_egl_display(EGL_NO_DISPLAY),
_egl_surface(EGL_NO_SURFACE),
_screen_changeid(0),
_force_redraw(false),
_game_texture(NULL),
@ -307,6 +313,7 @@ OSystem_Android::OSystem_Android(jobject am)
_use_mouse_palette(false),
_show_mouse(false),
_show_overlay(false),
_enable_zoning(false),
_savefile(0),
_mixer(0),
_timer(0),
@ -362,6 +369,7 @@ bool OSystem_Android::initJavaHooks(JNIEnv* env, jobject self) {
FIND_METHOD(getPluginDirectories, "()[Ljava/lang/String;");
FIND_METHOD(setupScummVMSurface, "()V");
FIND_METHOD(destroyScummVMSurface, "()V");
FIND_METHOD(swapBuffers, "()Z");
#undef FIND_METHOD
@ -574,6 +582,7 @@ int OSystem_Android::getGraphicsMode() const {
}
void OSystem_Android::setupScummVMSurface() {
ENTER("setupScummVMSurface");
JNIEnv* env = JNU_GetEnv();
env->CallVoidMethod(_back_ptr, MID_setupScummVMSurface);
if (env->ExceptionCheck())
@ -581,37 +590,8 @@ void OSystem_Android::setupScummVMSurface() {
// EGL set up with a new surface. Initialise OpenGLES context.
_egl_display = eglGetCurrentDisplay();
_egl_surface = eglGetCurrentSurface(EGL_DRAW);
static bool log_version = true;
if (log_version) {
__android_log_print(ANDROID_LOG_INFO, LOG_TAG,
"Using EGL %s (%s); GL %s/%s (%s)",
eglQueryString(_egl_display, EGL_VERSION),
eglQueryString(_egl_display, EGL_VENDOR),
glGetString(GL_VERSION),
glGetString(GL_RENDERER),
glGetString(GL_VENDOR));
log_version = false; // only log this once
}
GLESTexture::initGLExtensions();
if (!eglQuerySurface(_egl_display, _egl_surface,
EGL_WIDTH, &_egl_surface_width) ||
!eglQuerySurface(_egl_display, _egl_surface,
EGL_HEIGHT, &_egl_surface_height)) {
JNU_ThrowByName(env, "java/lang/RuntimeException",
"Error fetching EGL surface width/height");
return;
}
__android_log_print(ANDROID_LOG_INFO, LOG_TAG,
"New surface is %dx%d",
_egl_surface_width, _egl_surface_height);
CHECK_GL_ERROR();
// Turn off anything that looks like 3D ;)
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
@ -645,20 +625,18 @@ void OSystem_Android::setupScummVMSurface() {
_mouse_texture->reinitGL();
glViewport(0, 0, _egl_surface_width, _egl_surface_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, _egl_surface_width, _egl_surface_height, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
clearFocusRectangle();
CHECK_GL_ERROR();
_force_redraw = true;
}
void OSystem_Android::destroyScummVMSurface() {
_egl_surface = EGL_NO_SURFACE;
JNIEnv* env = JNU_GetEnv();
env->CallVoidMethod(_back_ptr, MID_destroyScummVMSurface);
// Can't use OpenGLES functions after this
@ -739,8 +717,11 @@ void OSystem_Android::updateScreen() {
glPushMatrix();
if (_shake_offset != 0) {
// This is the only case where _game_texture doesn't
if (_shake_offset != 0 ||
(!_focus_rect.isEmpty() &&
!Common::Rect(_game_texture->width(),
_game_texture->height()).contains(_focus_rect))) {
// These are the only cases where _game_texture doesn't
// cover the entire screen.
glClearColorx(0, 0, 0, 1 << 16);
glClear(GL_COLOR_BUFFER_BIT);
@ -749,8 +730,22 @@ void OSystem_Android::updateScreen() {
glTranslatex(0, -_shake_offset << 16, 0);
}
if (_focus_rect.isEmpty()) {
_game_texture->drawTexture(0, 0,
_egl_surface_width, _egl_surface_height);
} else {
glPushMatrix();
glScalex(xdiv(_egl_surface_width, _focus_rect.width()),
xdiv(_egl_surface_height, _focus_rect.height()),
1 << 16);
glTranslatex(-_focus_rect.left << 16, -_focus_rect.top << 16, 0);
glScalex(xdiv(_game_texture->width(), _egl_surface_width),
xdiv(_game_texture->height(), _egl_surface_height),
1 << 16);
_game_texture->drawTexture(0, 0,
_egl_surface_width, _egl_surface_height);
glPopMatrix();
}
CHECK_GL_ERROR();
@ -801,16 +796,13 @@ void OSystem_Android::updateScreen() {
CHECK_GL_ERROR();
if (!eglSwapBuffers(_egl_display, _egl_surface)) {
EGLint error = eglGetError();
warning("eglSwapBuffers exited with error 0x%x", error);
// Some errors mean we need to reinit GL
if (error == EGL_CONTEXT_LOST) {
JNIEnv* env = JNU_GetEnv();
if (!env->CallBooleanMethod(_back_ptr, MID_swapBuffers)) {
// Context lost -> need to reinit GL
destroyScummVMSurface();
setupScummVMSurface();
}
}
}
Graphics::Surface *OSystem_Android::lockScreen() {
ENTER("lockScreen()");
@ -841,26 +833,18 @@ void OSystem_Android::fillScreen(uint32 col) {
void OSystem_Android::setFocusRectangle(const Common::Rect& rect) {
ENTER("setFocusRectangle(%d,%d,%d,%d)",
rect.left, rect.top, rect.right, rect.bottom);
#if 0
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(rect.left, rect.right, rect.top, rect.bottom, 0, 1);
glMatrixMode(GL_MODELVIEW);
if (_enable_zoning) {
_focus_rect = rect;
_force_redraw = true;
#endif
}
}
void OSystem_Android::clearFocusRectangle() {
ENTER("clearFocusRectangle()");
#if 0
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, _egl_surface_width, _egl_surface_height, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
if (_enable_zoning) {
_focus_rect = Common::Rect();
_force_redraw = true;
#endif
}
}
void OSystem_Android::showOverlay() {
@ -1338,6 +1322,17 @@ void AndroidPluginProvider::addCustomDirectories(Common::FSList &dirs) const {
}
#endif
static void ScummVM_enableZoning(JNIEnv* env, jobject self, jboolean enable) {
OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
cpp_obj->enableZoning(enable);
}
static void ScummVM_setSurfaceSize(JNIEnv* env, jobject self,
jint width, jint height) {
OSystem_Android* cpp_obj = OSystem_Android::fromJavaObject(env, self);
cpp_obj->setSurfaceSize(width, height);
}
const static JNINativeMethod gMethods[] = {
{ "create", "(Landroid/content/res/AssetManager;)V",
(void*)ScummVM_create },
@ -1352,6 +1347,10 @@ const static JNINativeMethod gMethods[] = {
(void*)ScummVM_setConfManInt },
{ "setConfMan", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*)ScummVM_setConfManString },
{ "enableZoning", "(Z)V",
(void*)ScummVM_enableZoning },
{ "setSurfaceSize", "(II)V",
(void*)ScummVM_setSurfaceSize },
};
JNIEXPORT jint JNICALL

View file

@ -4,7 +4,6 @@ AAPT = aapt
DX = dx
APKBUILDER = apkbuilder
ADB = adb -e
ANDROID_JAR = $(ANDROID_SDK)/platforms/android-1.6/android.jar
JAVAC ?= javac
JAVACFLAGS = -source 1.5 -target 1.5
@ -12,6 +11,14 @@ JAVACFLAGS = -source 1.5 -target 1.5
#LDFLAGS += -Wl,--gc-sections
#CXXFLAGS += -ffunction-sections -fdata-sections -fvisibility=hidden -fvisibility-inlines-hidden
resources.ap_: $(srcdir)/dists/android/AndroidManifest.xml $(RESOURCES) $(ASSETS) $(ANDROID_JAR8) $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA)
$(INSTALL) -d build.tmp/assets/
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) build.tmp/assets/
$(AAPT) package -f -M $< -S $(srcdir)/dists/android/res -A build.tmp/assets -I $(ANDROID_JAR8) -F $@
build.tmp/%/resources.ap_: build.tmp/%/AndroidManifest.xml build.stage/%/res/values/strings.xml build.stage/%/res/drawable/scummvm.png $(ANDROID_JAR8)
$(AAPT) package -f -M $< -S build.stage/$*/res -I $(ANDROID_JAR8) -F $@
scummvm.apk: build.tmp/libscummvm.so resources.ap_ classes.dex
# Package installer won't delete old libscummvm.so on upgrade so
# replace it with a zero size file

View file

@ -39,14 +39,22 @@ PLUGIN_RESOURCES = \
#ANDROID_VERSIONCODE = 6 Specified in dists/android/AndroidManifest.xml.in
ANDROID_PLUGIN_VERSIONCODE = 6
# This is a bit silly. I want to compile against the 1.6 android.jar,
# to make the compiler check that I don't use something that requires
# a newer Android. However, in order to use android:installLocation,
# we need to give aapt a version >=8 android.jar - even though the
# result will work ok on 1.5+.
ANDROID_JAR = $(ANDROID_SDK)/platforms/android-1.5/android.jar
ANDROID_JAR8 = $(ANDROID_SDK)/platforms/android-8/android.jar
# This library contains scummvm proper
build.tmp/libscummvm.so: $(OBJS)
@$(MKDIR) -p $(@D)
$(CXX) $(PLUGIN_LDFLAGS) -shared $(LDFLAGS) -Wl,-soname,$(@F) -Wl,--no-undefined -o $@ $(PRE_OBJS_FLAGS) $(OBJS) $(POST_OBJS_FLAGS) $(LIBS)
$(QUIET_LINK)$(CXX) -shared $(LDFLAGS) -Wl,-Bsymbolic -Wl,-soname,$(@F) -Wl,--no-undefined -o $@ $(PRE_OBJS_FLAGS) $(OBJS) $(POST_OBJS_FLAGS) $(LIBS)
backends/platform/android/org/inodes/gus/scummvm/R.java backends/platform/android/org/inodes/gus/scummvm/Manifest.java: $(srcdir)/dists/android/AndroidManifest.xml $(filter %.xml,$(RESOURCES)) $(ANDROID_JAR)
$(AAPT) package -m -J backends/platform/android -M $< -S $(srcdir)/dists/android/res -I $(ANDROID_JAR)
backends/platform/android/org/inodes/gus/scummvm/R.java backends/platform/android/org/inodes/gus/scummvm/Manifest.java: $(srcdir)/dists/android/AndroidManifest.xml $(filter %.xml,$(RESOURCES)) $(ANDROID_JAR8)
$(AAPT) package -m -J backends/platform/android -M $< -S $(srcdir)/dists/android/res -I $(ANDROID_JAR8)
build.tmp/classes/%.class: $(srcdir)/backends/platform/android/%.java $(srcdir)/backends/platform/android/org/inodes/gus/scummvm/R.java
@$(MKDIR) -p $(@D)
@ -63,14 +71,6 @@ build.tmp/plugins/classes.dex: $(JAVA_PLUGIN_SRC:backends/platform/android/%.jav
@$(MKDIR) -p $(@D)
$(DX) --dex --output=$@ build.tmp/classes.plugin
resources.ap_: $(srcdir)/dists/android/AndroidManifest.xml $(RESOURCES) $(ASSETS) $(ANDROID_JAR) $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA)
$(INSTALL) -d build.tmp/assets/
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) build.tmp/assets/
$(AAPT) package -f -M $< -S $(srcdir)/dists/android/res -A build.tmp/assets -I $(ANDROID_JAR) -F $@
build.tmp/%/resources.ap_: build.tmp/%/AndroidManifest.xml build.stage/%/res/values/strings.xml build.stage/%/res/drawable/scummvm.png $(ANDROID_JAR)
$(AAPT) package -f -M $< -S build.stage/$*/res -I $(ANDROID_JAR) -F $@
build.tmp/%/AndroidManifest.xml build.stage/%/res/values/strings.xml: dists/android/mkmanifest.pl configure dists/android/AndroidManifest.xml
dists/android/mkmanifest.pl --id=$* --configure=configure \
--version-name=$(VERSION) \

View file

@ -12,7 +12,10 @@ import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import javax.microedition.khronos.opengles.GL;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
@ -129,6 +132,7 @@ public class ScummVM implements SurfaceHolder.Callback {
}
// Called by ScummVM thread
static private boolean _log_version = true;
protected void setupScummVMSurface() {
try {
surfaceLock.acquire();
@ -140,6 +144,26 @@ public class ScummVM implements SurfaceHolder.Callback {
eglSurface = egl.eglCreateWindowSurface(eglDisplay, eglConfig,
nativeSurface, null);
egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
GL10 gl = (GL10)eglContext.getGL();
if (_log_version) {
Log.i(LOG_TAG, String.format("Using EGL %s (%s); GL %s/%s (%s)",
egl.eglQueryString(eglDisplay, EGL10.EGL_VERSION),
egl.eglQueryString(eglDisplay, EGL10.EGL_VENDOR),
gl.glGetString(GL10.GL_VERSION),
gl.glGetString(GL10.GL_RENDERER),
gl.glGetString(GL10.GL_VENDOR)));
_log_version = false; // only log this once
}
int[] value = new int[1];
egl.eglQuerySurface(eglDisplay, eglSurface, EGL10.EGL_WIDTH, value);
int width = value[0];
egl.eglQuerySurface(eglDisplay, eglSurface, EGL10.EGL_HEIGHT, value);
int height = value[0];
Log.i(LOG_TAG, String.format("New surface is %dx%d", width, height));
setSurfaceSize(width, height);
}
// Called by ScummVM thread
@ -158,10 +182,22 @@ public class ScummVM implements SurfaceHolder.Callback {
holder.addCallback(this);
}
final public boolean swapBuffers() {
if (!egl.eglSwapBuffers(eglDisplay, eglSurface)) {
int error = egl.eglGetError();
Log.w(LOG_TAG, String.format("eglSwapBuffers exited with error 0x%x", error));
if (error == EGL11.EGL_CONTEXT_LOST)
return false;
}
return true;
}
// Set scummvm config options
final public native static void loadConfigFile(String path);
final public native static void setConfMan(String key, int value);
final public native static void setConfMan(String key, String value);
final public native void enableZoning(boolean enable);
final public native void setSurfaceSize(int width, int height);
// Feed an event to ScummVM. Safe to call from other threads.
final public native void pushEvent(Event e);

View file

@ -1,7 +1,7 @@
package org.inodes.gus.scummvm;
import android.app.AlertDialog;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.media.AudioManager;
@ -9,13 +9,14 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
import java.io.IOException;
@ -31,8 +32,27 @@ public class ScummVMActivity extends Activity {
private class MyScummVM extends ScummVM {
private boolean scummvmRunning = false;
private boolean usingSmallScreen() {
// Multiple screen sizes came in with Android 1.6. Have
// to use reflection in order to continue supporting 1.5
// devices :(
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
try {
// This 'density' term is very confusing.
int DENSITY_LOW = metrics.getClass().getField("DENSITY_LOW").getInt(null);
int densityDpi = metrics.getClass().getField("densityDpi").getInt(metrics);
return densityDpi <= DENSITY_LOW;
} catch (Exception e) {
return false;
}
}
public MyScummVM() {
super(ScummVMActivity.this);
// Enable ScummVM zoning on 'small' screens.
enableZoning(usingSmallScreen());
}
@Override

View file

@ -34,6 +34,7 @@ import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
public class Unpacker extends Activity {
private final static boolean PLUGINS_ENABLED = true;
private final static String META_NEXT_ACTIVITY =
"org.inodes.gus.unpacker.nextActivity";
private ProgressBar mProgress;
@ -79,7 +80,6 @@ public class Unpacker extends Activity {
if (cn != null) {
final Intent origIntent = getIntent();
Intent intent = new Intent();
intent.setPackage(origIntent.getPackage());
intent.setComponent(cn);
if (origIntent.getExtras() != null)
intent.putExtras(origIntent.getExtras());
@ -294,7 +294,7 @@ public class Unpacker extends Activity {
Intent intent = new Intent(ScummVMApplication.ACTION_PLUGIN_QUERY);
List<ResolveInfo> plugins = getPackageManager()
.queryBroadcastReceivers(intent, 0);
if (plugins.isEmpty()) {
if (PLUGINS_ENABLED && plugins.isEmpty()) {
// No plugins installed
AlertDialog.Builder alert = new AlertDialog.Builder(this)
.setTitle(R.string.no_plugins_title)

View file

@ -0,0 +1,334 @@
/* 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/null/null.cpp $
* $Id: null.cpp 34912 2008-11-06 15:02:50Z fingolfin $
*
*/
#include "base/main.h"
#include "graphics/surface.h"
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <android/log.h>
#include "common/rect.h"
#include "common/array.h"
#include "common/util.h"
#include "common/tokenizer.h"
#include "backends/platform/android/video.h"
#undef LOG_TAG
#define LOG_TAG "ScummVM-video"
#if 0
#define ENTER(args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, args)
#else
#define ENTER(args...) /**/
#endif
#if 0
#define CHECK_GL_ERROR() checkGlError(__FILE__, __LINE__)
static const char* getGlErrStr(GLenum error) {
switch (error) {
case GL_NO_ERROR: return "GL_NO_ERROR";
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
case GL_STACK_OVERFLOW: return "GL_STACK_OVERFLOW";
case GL_STACK_UNDERFLOW: return "GL_STACK_UNDERFLOW";
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
}
static char buf[40];
snprintf(buf, sizeof(buf), "(Unknown GL error code 0x%x)", error);
return buf;
}
static void checkGlError(const char* file, int line) {
GLenum error = glGetError();
if (error != GL_NO_ERROR)
warning("%s:%d: GL error: %s", file, line, getGlErrStr(error));
}
#else
#define CHECK_GL_ERROR() do {} while (false)
#endif
// Supported GL extensions
static bool npot_supported = false;
#ifdef GL_OES_draw_texture
static bool draw_tex_supported = false;
#endif
static inline GLfixed xdiv(int numerator, int denominator) {
assert(numerator < (1<<16));
return (numerator << 16) / denominator;
}
template <class T>
static T nextHigher2(T k) {
if (k == 0)
return 1;
--k;
for (uint i = 1; i < sizeof(T)*CHAR_BIT; i <<= 1)
k = k | k >> i;
return k + 1;
}
void GLESTexture::initGLExtensions() {
const char* ext_string =
reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
__android_log_print(ANDROID_LOG_INFO, LOG_TAG,
"Extensions: %s", ext_string);
Common::StringTokenizer tokenizer(ext_string, " ");
while (!tokenizer.empty()) {
Common::String token = tokenizer.nextToken();
if (token == "GL_ARB_texture_non_power_of_two")
npot_supported = true;
#ifdef GL_OES_draw_texture
if (token == "GL_OES_draw_texture")
draw_tex_supported = true;
#endif
}
}
GLESTexture::GLESTexture() :
_texture_width(0),
_texture_height(0),
_all_dirty(true)
{
glGenTextures(1, &_texture_name);
// This all gets reset later in allocBuffer:
_surface.w = 0;
_surface.h = 0;
_surface.pitch = _texture_width;
_surface.pixels = NULL;
_surface.bytesPerPixel = 0;
}
GLESTexture::~GLESTexture() {
debug("Destroying texture %u", _texture_name);
glDeleteTextures(1, &_texture_name);
}
void GLESTexture::reinitGL() {
glGenTextures(1, &_texture_name);
setDirty();
}
void GLESTexture::allocBuffer(GLuint w, GLuint h) {
CHECK_GL_ERROR();
int bpp = bytesPerPixel();
_surface.w = w;
_surface.h = h;
_surface.bytesPerPixel = bpp;
if (w <= _texture_width && h <= _texture_height)
// Already allocated a sufficiently large buffer
return;
if (npot_supported) {
_texture_width = _surface.w;
_texture_height = _surface.h;
} else {
_texture_width = nextHigher2(_surface.w);
_texture_height = nextHigher2(_surface.h);
}
_surface.pitch = _texture_width * bpp;
// Allocate room for the texture now, but pixel data gets uploaded
// later (perhaps with multiple TexSubImage2D operations).
CHECK_GL_ERROR();
glBindTexture(GL_TEXTURE_2D, _texture_name);
CHECK_GL_ERROR();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
CHECK_GL_ERROR();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
CHECK_GL_ERROR();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
CHECK_GL_ERROR();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
CHECK_GL_ERROR();
glTexImage2D(GL_TEXTURE_2D, 0, glFormat(),
_texture_width, _texture_height,
0, glFormat(), glType(), NULL);
CHECK_GL_ERROR();
}
void GLESTexture::updateBuffer(GLuint x, GLuint y, GLuint w, GLuint h,
const void* buf, int pitch) {
ENTER("updateBuffer(%u, %u, %u, %u, %p, %d)", x, y, w, h, buf, pitch);
glBindTexture(GL_TEXTURE_2D, _texture_name);
setDirtyRect(Common::Rect(x, y, x+w, y+h));
if (static_cast<int>(w) * bytesPerPixel() == pitch) {
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h,
glFormat(), glType(), buf);
} else {
// GLES removed the ability to specify pitch, so we
// have to do this row by row.
const byte* src = static_cast<const byte*>(buf);
do {
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y,
w, 1, glFormat(), glType(), src);
++y;
src += pitch;
} while (--h);
}
}
void GLESTexture::fillBuffer(byte x) {
byte tmpbuf[_surface.h * _surface.w * bytesPerPixel()];
memset(tmpbuf, 0, _surface.h * _surface.w * bytesPerPixel());
glBindTexture(GL_TEXTURE_2D, _texture_name);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _surface.w, _surface.h,
glFormat(), glType(), tmpbuf);
setDirty();
}
void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
glBindTexture(GL_TEXTURE_2D, _texture_name);
#ifdef GL_OES_draw_texture
// Great extension, but only works under specific conditions.
// Still a work-in-progress - disabled for now.
if (false && draw_tex_supported && paletteSize() == 0) {
//glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
const GLint crop[4] = {0, _surface.h, _surface.w, -_surface.h};
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
glDrawTexiOES(x, y, 0, w, h);
} else
#endif
{
const GLfixed tex_width = xdiv(_surface.w, _texture_width);
const GLfixed tex_height = xdiv(_surface.h, _texture_height);
const GLfixed texcoords[] = {
0, 0,
tex_width, 0,
0, tex_height,
tex_width, tex_height,
};
glTexCoordPointer(2, GL_FIXED, 0, texcoords);
const GLshort vertices[] = {
x, y,
x+w, y,
x, y+h,
x+w, y+h,
};
glVertexPointer(2, GL_SHORT, 0, vertices);
assert(ARRAYSIZE(vertices) == ARRAYSIZE(texcoords));
glDrawArrays(GL_TRIANGLE_STRIP, 0, ARRAYSIZE(vertices)/2);
}
_all_dirty = false;
_dirty_rect = Common::Rect();
}
GLESPaletteTexture::GLESPaletteTexture() :
GLESTexture(),
_texture(NULL)
{
}
GLESPaletteTexture::~GLESPaletteTexture() {
delete[] _texture;
}
void GLESPaletteTexture::allocBuffer(GLuint w, GLuint h) {
CHECK_GL_ERROR();
int bpp = bytesPerPixel();
_surface.w = w;
_surface.h = h;
_surface.bytesPerPixel = bpp;
if (w <= _texture_width && h <= _texture_height)
// Already allocated a sufficiently large buffer
return;
if (npot_supported) {
_texture_width = _surface.w;
_texture_height = _surface.h;
} else {
_texture_width = nextHigher2(_surface.w);
_texture_height = nextHigher2(_surface.h);
}
_surface.pitch = _texture_width * bpp;
// Texture gets uploaded later (from drawTexture())
byte* new_buffer = new byte[paletteSize() +
_texture_width * _texture_height * bytesPerPixel()];
if (_texture) {
memcpy(new_buffer, _texture, paletteSize()); // preserve palette
delete[] _texture;
}
_texture = new_buffer;
_surface.pixels = _texture + paletteSize();
}
void GLESPaletteTexture::fillBuffer(byte x) {
assert(_surface.pixels);
memset(_surface.pixels, x, _surface.pitch * _surface.h);
setDirty();
}
void GLESPaletteTexture::updateBuffer(GLuint x, GLuint y,
GLuint w, GLuint h,
const void* buf, int pitch) {
_all_dirty = true;
const byte* src = static_cast<const byte*>(buf);
byte* dst = static_cast<byte*>(_surface.getBasePtr(x, y));
do {
memcpy(dst, src, w * bytesPerPixel());
dst += _surface.pitch;
src += pitch;
} while (--h);
}
void GLESPaletteTexture::uploadTexture() const {
const size_t texture_size =
paletteSize() + _texture_width * _texture_height * bytesPerPixel();
glCompressedTexImage2D(GL_TEXTURE_2D, 0, glType(),
_texture_width, _texture_height,
0, texture_size, _texture);
CHECK_GL_ERROR();
}
void GLESPaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
if (_all_dirty) {
glBindTexture(GL_TEXTURE_2D, _texture_name);
CHECK_GL_ERROR();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
CHECK_GL_ERROR();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
CHECK_GL_ERROR();
uploadTexture();
_all_dirty = false;
}
GLESTexture::drawTexture(x, y, w, h);
}

View file

@ -0,0 +1,140 @@
/* 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/null/null.cpp $
* $Id: null.cpp 34912 2008-11-06 15:02:50Z fingolfin $
*
*/
#if defined(ANDROID)
#include <GLES/gl.h>
#include "graphics/surface.h"
#include "common/rect.h"
#include "common/array.h"
class GLESTexture {
public:
static void initGLExtensions();
GLESTexture();
virtual ~GLESTexture();
virtual void reinitGL();
virtual void allocBuffer(GLuint width, GLuint height);
const Graphics::Surface* surface_const() const { return &_surface; }
GLuint width() const { return _surface.w; }
GLuint height() const { return _surface.h; }
GLuint texture_name() const { return _texture_name; }
bool dirty() const { return _all_dirty || !_dirty_rect.isEmpty(); }
virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
const void* buf, int pitch);
virtual void fillBuffer(byte x);
virtual void drawTexture() {
drawTexture(0, 0, _surface.w, _surface.h);
}
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
protected:
virtual byte bytesPerPixel() const = 0;
virtual GLenum glFormat() const = 0;
virtual GLenum glType() const = 0;
virtual size_t paletteSize() const { return 0; };
void setDirty() {
_all_dirty = true;
_dirty_rect = Common::Rect();
}
void setDirtyRect(const Common::Rect& r) {
if (!_all_dirty) {
if (_dirty_rect.isEmpty())
_dirty_rect = r;
else
_dirty_rect.extend(r);
}
}
GLuint _texture_name;
Graphics::Surface _surface;
GLuint _texture_width;
GLuint _texture_height;
bool _all_dirty;
Common::Rect _dirty_rect; // Covers dirty area
};
// RGBA4444 texture
class GLES4444Texture : public GLESTexture {
protected:
virtual byte bytesPerPixel() const { return 2; }
virtual GLenum glFormat() const { return GL_RGBA; }
virtual GLenum glType() const { return GL_UNSIGNED_SHORT_4_4_4_4; }
};
// RGB565 texture
class GLES565Texture : public GLESTexture {
protected:
virtual byte bytesPerPixel() const { return 2; }
virtual GLenum glFormat() const { return GL_RGB; }
virtual GLenum glType() const { return GL_UNSIGNED_SHORT_5_6_5; }
};
// RGB888 256-entry paletted texture
class GLESPaletteTexture : public GLESTexture {
public:
GLESPaletteTexture();
virtual ~GLESPaletteTexture();
virtual void allocBuffer(GLuint width, GLuint height);
virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
const void* buf, int pitch);
Graphics::Surface* surface() {
setDirty();
return &_surface;
}
void* pixels() {
setDirty();
return _surface.pixels;
}
const byte* palette_const() const { return _texture; };
byte* palette() {
setDirty();
return _texture;
};
virtual void drawTexture() {
drawTexture(0, 0, _surface.w, _surface.h);
}
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
virtual void fillBuffer(byte x);
protected:
virtual byte bytesPerPixel() const { return 1; }
virtual GLenum glFormat() const { return GL_RGB; }
virtual GLenum glType() const { return GL_PALETTE8_RGB8_OES; }
virtual size_t paletteSize() const { return 256 * 3; };
virtual void uploadTexture() const;
byte* _texture;
};
// RGBA8888 256-entry paletted texture
class GLESPaletteATexture : public GLESPaletteTexture {
protected:
virtual GLenum glFormat() const { return GL_RGBA; }
virtual GLenum glType() const { return GL_PALETTE8_RGBA8_OES; }
virtual size_t paletteSize() const { return 256 * 4; };
};
#endif

View file

@ -86,7 +86,7 @@ class OSystem_Dreamcast : private DCHardware, public BaseBackend, public Filesys
Graphics::PixelFormat getScreenFormat() const;
// Returns a list of all pixel formats supported by the backend.
Common::List<Graphics::PixelFormat> getSupportedFormats();
Common::List<Graphics::PixelFormat> getSupportedFormats() const;
// Set the size of the video bitmap.
// Typically, 320x200

View file

@ -198,7 +198,7 @@ Graphics::PixelFormat OSystem_Dreamcast::getScreenFormat() const
return screenFormats[_screenFormat];
}
Common::List<Graphics::PixelFormat> OSystem_Dreamcast::getSupportedFormats()
Common::List<Graphics::PixelFormat> OSystem_Dreamcast::getSupportedFormats() const
{
Common::List<Graphics::PixelFormat> list;
unsigned i;

View file

@ -8,17 +8,19 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
* $Header: /cvsroot/scummvm/scummvm/backends/fs/fs.cpp,v 1.3.2.1 2004/12/18 02:33:52 fingolfin Exp $
*/
//////////////////////////////////////////////////////////////////////

View file

@ -113,9 +113,6 @@ ifdef DS_BUILD_A
DEFINES = -DDS_SCUMM_BUILD -DDS_BUILD_A -DUSE_ARM_GFX_ASM -DUSE_ARM_COSTUME_ASM
LOGO = logoa.bmp
ENABLE_SCUMM = STATIC_PLUGIN
DEFINES += -DENABLE_SCUMM=STATIC_PLUGIN
MODULES += engines/scumm
USE_ARM_GFX_ASM = 1
BUILD=scummvm-A
endif
@ -202,7 +199,6 @@ endif
#endif
ARM7BIN := -7 $(CURDIR)/../../arm7/arm7.bin
ICON := -b ../../../logo.bmp "ScummVM;By Neil Millstone;"
CC = arm-eabi-gcc
CXX = arm-eabi-g++
@ -248,9 +244,6 @@ endif
DEFINES += -DREDUCE_MEMORY_USAGE
# Removed, as these are done in portdefs.h
# -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE
LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,-Map,map.txt -Wl,--gc-sections
ifdef WRAP_MALLOC
@ -260,7 +253,7 @@ endif
INCLUDES= -I$(portdir)/$(BUILD) -I$(srcdir) -I$(srcdir)/engines \
-I$(portdir)/data -I$(portdir)/../commoninclude \
-I$(portdir)/source -I$(portdir)/source/mad -I$(portdir)/source/libcartreset \
-I$(portdir)/source -I$(portdir)/source/mad \
-I$(libndsdir)/include -include $(srcdir)/common/scummsys.h
@ -272,12 +265,7 @@ ifdef USE_DEBUGGER
LIBS += -ldsdebugger -ldswifi9
endif
#-Lscumm -lscumm -Lbase -lbase -Lcommon -lcommon -Lgraphics -lgraphics -Lgui -lgui -Lsound -lsound
EXECUTABLE = scummvm.elf
PLUGIN_PREFIX =
PLUGIN_SUFFIX = .plg
PLUGIN_EXTRA_DEPS = plugin.x plugin.syms scummvm.elf
PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,-Tplugin.x,--just-symbols,scummvm.elf,--retain-symbols-file,plugin.syms -L$(ronindir)/lib
MKDIR = mkdir -p
RM = rm -f
RM_REC = rm -rf
@ -287,17 +275,19 @@ OBJCOPY = arm-eabi-objcopy
AS = arm-eabi-as
HAVE_GCC3 = true
ifdef DYNAMIC_MODULES
DEFINES += -DDYNAMIC_MODULES
PRE_OBJS_FLAGS = -Wl,--whole-archive
POST_OBJS_FLAGS = -Wl,--no-whole-archive
endif
PORT_OBJS := $(portdir)/source/blitters_arm.o $(portdir)/source/cdaudio.o $(portdir)/source/dsmain.o \
$(portdir)/../../../fs/ds/ds-fs.o $(portdir)/source/gbampsave.o $(portdir)/source/scummhelp.o\
$(portdir)/source/osystem_ds.o $(portdir)/source/portdefs.o $(portdir)/source/ramsave.o\
$(portdir)/source/touchkeyboard.o $(portdir)/source/zipreader.o\
$(portdir)/source/dsoptions.o $(portdir)/source/keys.o $(portdir)/source/wordcompletion.o\
PORT_OBJS := \
$(portdir)/source/blitters_arm.o \
$(portdir)/source/cdaudio.o \
$(portdir)/source/dsmain.o \
$(portdir)/../../../fs/ds/ds-fs.o \
$(portdir)/source/gbampsave.o \
$(portdir)/source/scummhelp.o \
$(portdir)/source/osystem_ds.o \
$(portdir)/source/touchkeyboard.o \
$(portdir)/source/zipreader.o \
$(portdir)/source/dsoptions.o \
$(portdir)/source/keys.o \
$(portdir)/source/wordcompletion.o \
$(portdir)/source/interrupt.o
ifdef USE_PROFILER
@ -305,16 +295,23 @@ ifdef USE_PROFILER
endif
DATA_OBJS := $(portdir)/data/icons.o $(portdir)/data/keyboard.o $(portdir)/data/keyboard_pal.o $(portdir)/data/default_font.o $(portdir)/data/8x8font_tga.o
DATA_OBJS :=
$(portdir)/data/icons.o \
$(portdir)/data/keyboard.o \
$(portdir)/data/keyboard_pal.o \
$(portdir)/data/default_font.o \
$(portdir)/data/8x8font_tga.o
COMPRESSOR_OBJS :=
#$(portdir)/source/compressor/lz.o
FAT_OBJS := $(portdir)/source/fat/disc_io.o $(portdir)/source/fat/gba_nds_fat.o\
$(portdir)/source/fat/io_fcsr.o $(portdir)/source/fat/io_m3cf.o\
$(portdir)/source/fat/io_mpcf.o $(portdir)/source/fat/io_sccf.o\
FAT_OBJS :=
$(portdir)/source/fat/disc_io.o \
$(portdir)/source/fat/gba_nds_fat.o \
$(portdir)/source/fat/io_fcsr.o \
$(portdir)/source/fat/io_m3cf.o \
$(portdir)/source/fat/io_mpcf.o \
$(portdir)/source/fat/io_sccf.o \
$(portdir)/source/fat/io_m3sd.o \
$(portdir)/source/fat/io_nmmc.o $(portdir)/source/fat/io_scsd.o \
$(portdir)/source/fat/io_nmmc.o \
$(portdir)/source/fat/io_scsd.o \
$(portdir)/source/fat/io_scsd_asm.o \
$(portdir)/source/fat/io_njsd.o \
$(portdir)/source/fat/io_mmcf.o \
@ -324,15 +321,8 @@ FAT_OBJS := $(portdir)/source/fat/disc_io.o $(portdir)/source/fat/gba_nds_fat.o
$(portdir)/source/fat/m3sd.o
# $(portdir)/source/fat/io_cf_common.o $(portdir)/source/fat/io_m3_common.o\
# $(portdir)/source/fat/io_sd_common.o $(portdir)/source/fat/io_scsd_s.o \
# $(portdir)/source/fat/io_sc_common.o $(portdir)/source/fat/io_sd_common.o
LIBCARTRESET_OBJS :=
#$(portdir)/source/libcartreset/cartreset.o
# Files in this list will be optimisied for speed, otherwise they will be optimised for space
OPTLIST := actor.cpp ds_main.cpp osystem_ds.cpp blitters.cpp mame.cpp rate.cpp isomap.cpp image.cpp gfx.cpp sprite.cpp actor_path.cpp actor_walk.cpp script.cpp
OPTLIST := actor.cpp dsmain.cpp osystem_ds.cpp blitters.cpp mame.cpp rate.cpp isomap.cpp image.cpp gfx.cpp sprite.cpp actor_path.cpp actor_walk.cpp script.cpp
#OPTLIST :=
# Compiler options for files which should be optimised for speed
@ -340,20 +330,14 @@ ifdef DS_BUILD_E
# Another attempt to save some RAM in ITE
OPT_SPEED := -O3 -mthumb
else
#OPT_SPEED := -O3
OPT_SPEED := -Os -mthumb
OPT_SPEED := -O3
endif
# Compiler options for files which should be optimised for space
OPT_SIZE := -Os -mthumb
#-mthumb -fno-gcse -fno-schedule-insns2
OBJS := $(DATA_OBJS) $(LIBCARTRESET_OBJS) $(PORT_OBJS) $(COMPRESSOR_OBJS) $(FAT_OBJS)
OBJS := $(DATA_OBJS) $(PORT_OBJS) $(FAT_OBJS)
@ -361,7 +345,7 @@ MODULE_DIRS += .
ndsall:
@[ -d $(BUILD) ] || mkdir -p $(BUILD)
make -C ./$(BUILD) -f ../makefile scummvm.nds
make -C ./$(BUILD) -f ../makefile scummvm.nds scummvm.ds.gba
include $(srcdir)/Makefile.common
@ -372,25 +356,12 @@ clean:
$(RM) $(OBJS) $(EXECUTABLE)
rm -fr $(BUILD)
plugin_dist :
find . -name '*.plg' | while read p; do \
sh-elf-strip -g -o "`basename \"$$p\" | tr '[:lower:]' '[:upper:]'`" "$$p"; \
done
dist : SCUMMVM.BIN plugins plugin_dist
#---------------------------------------------------------------------------------
# canned command sequence for binary data
#---------------------------------------------------------------------------------
#define bin2o
# bin2s $< | $(AS) -mthumb -mthumb-interwork -o $(@)
# echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_raw_end[];" > `(echo $(<F) | tr . _)`.h
# echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_raw[];" >> `(echo $(<F) | tr . _)`.h
# echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_raw_size";" >> `(echo $(<F) | tr . _)`.h
#endef
define bin2o
bin2s $< | $(AS) -mthumb -mthumb-interwork -o $(@)
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(<F) | tr . _)`.h
@ -399,46 +370,16 @@ define bin2o
endef
#define bin2o
# @echo $(*)
# cp $(<) $(*).tmp
# $(OBJCOPY) -I binary -O elf32-littlearm -B arm \
# --rename-section .data=.rodata \
# --redefine-sym _binary_$(subst .,_,$(subst /,_,$(*)))_tmp_start=$(notdir $*)\
# --redefine-sym _binary_$(subst .,_,$(subst /,_,$(*)))_tmp_end=$(notdir $*)_end\
# $(*).tmp $(@)
# echo "extern const u8" $(notdir $*)"[] __attribute__ ((aligned (4)));" > $(*).h
# echo "extern const u32" $(notdir $(*))_size[]";" >> $(*).h
#
# echo $(*).h
# rm $(*).tmp
#endef
##############
# Replacement rule for the one in makefile.common
##############
%.o: %.cpp
# echo !!!!!!!!!!!! $(notdir $<)
# ifeq ( $(notdir $<), $(findstring $(notdir $<), $(OPTLIST)) )
# OPTFLAG=-O3
# else
# OPTFLAG=-Os
# endif
# export OPTFLAG = ;
# echo !!!!!!!! $(OPTFLAG)
$(MKDIR) $(*D)/$(DEPDIR)
$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(if $(findstring $(notdir $<), $(OPTLIST)), $(OPT_SPEED), $(OPT_SIZE)) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
#---------------------------------------------------------------------------------
#---------------------------------------------------------------------------------
%.o : %.pcx
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
%.o : %.bin
#---------------------------------------------------------------------------------
@ -457,31 +398,17 @@ endef
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
%.o : %.map
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
%.o : %.mdl
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
#---------------------------------------------------------------------------------
%.nds: %.bin
@echo ndstool -c $@ -9 scummvm.bin $(ARM7BIN) -b ../../$(LOGO) "$(shell basename $@);ScummVM $(VERSION);DS Port"
ndstool -c $@ -9 scummvm.bin $(ARM7BIN) -b ../../$(LOGO) "$(shell basename $@);ScummVM $(VERSION);DS Port"
dsbuild $@ -l ../ndsloader.bin
ndstool -c $@ -9 $< $(ARM7BIN) -b ../../$(LOGO) "$(@F);ScummVM $(VERSION);DS Port"
padbin 16 $(basename $@).ds.gba
%.ds.gba: %.nds
dsbuild $< -o $@ -l $(portdir)/ndsloader.bin
padbin 16 $@
#---------------------------------------------------------------------------------
# FIXME: The following rule hardcodes the input & output filename -- shouldn't it use $< and $@ instead?
%.bin: %.elf
$(OBJCOPY) -S scummvm.elf scummvm-stripped.elf
$(OBJCOPY) -O binary scummvm-stripped.elf scummvm.bin
$(OBJCOPY) -S -O binary $< $@
#%.o: %.s
# $(MKDIR) $(*D)/$(DEPDIR)

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -30,10 +33,10 @@ namespace DS {
void asmDrawStripToScreen(int height, int width, byte const *text, byte const *src, byte *dst,
int vsPitch, int vmScreenWidth, int textSurfacePitch) {
if (height <= 0) height = 1;
if (width < 4) return;
if (height <= 0)
height = 1;
if (width < 4)
return;
width &= ~4;
// src = (const byte *) (((int) (src)) & (~4));
@ -141,22 +144,19 @@ void asmCopy8Col(byte* dst, int dstPitch, const byte* src, int height) {
static bool isDivBy5Ready = false;
static u32 DIV_BY_5[160];
void ComputeDivBy5TableIFN()
{
void ComputeDivBy5TableIFN() {
if (isDivBy5Ready)
return;
isDivBy5Ready = true;
for (int i=0; i<160; ++i)
{
for (int i = 0; i < 160; ++i) {
DIV_BY_5[i] = (2*i+5)/10;
}
}
#ifdef PERFECT_5_TO_4_RESCALING
static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3, u16 s4,
u16* dest)
{
u16 *dest) {
u32 bs0 = s0 & 0x1F;
u32 bs1 = s1 & 0x1F;
u32 bs2 = s2 & 0x1F;
@ -230,8 +230,7 @@ static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3
}
#else
static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3, u16 s4,
u16* dest)
{
u16 *dest) {
static const u32 MASK = 0x03E07C1F;
u32 argbargbs0 = u32(s0) | (u32(s0) << 16);
@ -279,8 +278,7 @@ static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3
#endif
static inline void RescaleBlock_5x8888_To_4x1555( u32 s0, u32 s1, u32 s2, u32 s3, u32 s4,
u16* dest)
{
u16 *dest) {
u32 d0 = 4*s0 + s1;
u32 d1 = 2*s1 + s1 + 2*s2;
@ -317,12 +315,10 @@ static inline void RescaleBlock_5x8888_To_4x1555( u32 s0, u32 s1, u32 s2, u32 s3
// Can't work in place
#ifdef PERFECT_5_TO_4_RESCALING
static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16* dest, const u8* src, const u32* palette)
{
static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16 *dest, const u8 *src, const u32 *palette) {
ComputeDivBy5TableIFN();
for (size_t i=0; i<64; ++i)
{
for (size_t i = 0; i < 64; ++i) {
u32 s0 = palette[src[5*i+0]];
u32 s1 = palette[src[5*i+1]];
u32 s2 = palette[src[5*i+2]];
@ -333,10 +329,8 @@ static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16* dest, const
}
}
#else
static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16* dest, const u8* src, const u16* palette)
{
for (size_t i=0; i<64; ++i)
{
static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16 *dest, const u8 *src, const u16 *palette) {
for (size_t i = 0; i < 64; ++i) {
u16 s0 = palette[src[5*i+0]];
u16 s1 = palette[src[5*i+1]];
u16 s2 = palette[src[5*i+2]];
@ -350,12 +344,10 @@ static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16* dest, const
// Can work in place, because it's a contraction
static inline void Rescale_320x1555Scanline_To_256x1555Scanline(u16* dest, const u16* src)
{
static inline void Rescale_320x1555Scanline_To_256x1555Scanline(u16 *dest, const u16 *src) {
ComputeDivBy5TableIFN();
for (size_t i=0; i<64; ++i)
{
for (size_t i = 0; i < 64; ++i) {
u16 s0 = src[5*i+0];
u16 s1 = src[5*i+1];
u16 s2 = src[5*i+2];
@ -367,13 +359,11 @@ static inline void Rescale_320x1555Scanline_To_256x1555Scanline(u16* dest, const
}
#ifdef PERFECT_5_TO_4_RESCALING
void Rescale_320x256xPAL8_To_256x256x1555(u16* dest, const u8* src, int destStride, int srcStride, const u16* palette)
{
void Rescale_320x256xPAL8_To_256x256x1555(u16 *dest, const u8 *src, int destStride, int srcStride, const u16 *palette) {
u32 fastRam[768];
// Palette lookup -> 0_888
for (size_t i=0; i<256; ++i)
{
for (size_t i = 0; i < 256; ++i) {
u32 col = palette[i];
u32 result = col & 0x0000001F;
result |= (col << 3) & 0x00001F00;
@ -382,31 +372,26 @@ void Rescale_320x256xPAL8_To_256x256x1555(u16* dest, const u8* src, int destStri
fastRam[i] = result;
}
for (size_t i=0; i<200; ++i)
{
for (size_t i = 0; i < 200; ++i) {
Rescale_320xPAL8Scanline_To_256x1555Scanline(dest + i*destStride, src + i *srcStride, fastRam);
}
}
#else
void Rescale_320x256xPAL8_To_256x256x1555(u16* dest, const u8* src, int destStride, int srcStride, const u16* palette)
{
void Rescale_320x256xPAL8_To_256x256x1555(u16 *dest, const u8 *src, int destStride, int srcStride, const u16 *palette) {
u16 fastRam[256];
for (size_t i = 0; i < 128; ++i)
((u32*)fastRam)[i] = ((const u32*)palette)[i];
for (size_t i=0; i<200; ++i)
{
for (size_t i = 0; i < 200; ++i) {
Rescale_320xPAL8Scanline_To_256x1555Scanline(dest + i*destStride, src + i *srcStride, fastRam);
}
}
#endif
void Rescale_320x256x1555_To_256x256x1555(u16* dest, const u16* src, int destStride, int srcStride)
{
for (size_t i=0; i<200; ++i)
{
void Rescale_320x256x1555_To_256x256x1555(u16 *dest, const u16 *src, int destStride, int srcStride) {
for (size_t i = 0; i < 200; ++i) {
Rescale_320x1555Scanline_To_256x1555Scanline(dest + i*destStride, src + i *srcStride);
}
}
}
} // End of namespace DS

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -35,7 +38,7 @@ void asmCopy8Col(byte* dst, int dstPitch, const byte* src, int height);
void Rescale_320x256xPAL8_To_256x256x1555(u16 *dest, const u8 *src, int destStride, int srcStride, const u16 *palette);
void Rescale_320x256x1555_To_256x256x1555(u16 *dest, const u16 *src, int destStride, int srcStride);
}
} // End of namespace DS
#else

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -71,25 +74,25 @@ struct decoderFormat {
unsigned char sample[1024];
} __attribute__ ((packed));
bool active = false;
WaveHeader waveHeader;
Header blockHeader;
FILE* file;
int fillPos;
bool isPlayingFlag = false;
static bool s_active = false;
static WaveHeader waveHeader;
static Header blockHeader;
static FILE *s_file;
static int fillPos;
static bool isPlayingFlag = false;
s16* audioBuffer;
u32 sampleNum;
s16* decompressionBuffer;
int numLoops;
int blockCount;
int dataChunkStart;
int blocksLeft;
bool trackStartsAt2 = false;
static s16 *audioBuffer;
static u32 sampleNum;
static s16 *decompressionBuffer;
static int s_numLoops;
static int blockCount;
static int dataChunkStart;
static int blocksLeft;
static bool trackStartsAt2 = false;
// These are from Microsoft's document on DVI ADPCM
const int stepTab[ 89 ] = {
static const int stepTab[ 89 ] = {
7, 8, 9, 10, 11, 12, 13, 14,
16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66,
@ -103,7 +106,7 @@ const int stepTab[ 89 ] = {
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
32767 };
const int indexTab[ 16 ] = { -1, -1, -1, -1, 2, 4, 6, 8,
static const int indexTab[ 16 ] = { -1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8 };
void playNextBlock();
@ -115,11 +118,11 @@ void allocBuffers() {
}
void setActive(bool active) {
DS::CD::active = active;
s_active = active;
}
bool getActive() {
return active;
return s_active;
}
void playTrack(int track, int numLoops, int startFrame, int duration) {
@ -145,21 +148,21 @@ void playTrack(int track, int numLoops, int startFrame, int duration) {
sprintf(str, "track%d.wav", track);
fname = path + str;
file = DS::std_fopen(fname.c_str(), "rb");
s_file = DS::std_fopen(fname.c_str(), "rb");
if (!file) {
if (!s_file) {
sprintf(str, "track%02d.wav", track);
fname = path + str;
file = DS::std_fopen(fname.c_str(), "rb");
s_file = DS::std_fopen(fname.c_str(), "rb");
}
if (!file) {
if (!s_file) {
consolePrintf("Failed to open %s!\n", path.c_str());
return;
}
DS::std_fread((const void *) &waveHeader, sizeof(waveHeader), 1, file);
DS::std_fread(&waveHeader, sizeof(waveHeader), 1, s_file);
consolePrintf("File: %s\n", fname.c_str());
@ -171,7 +174,7 @@ void playTrack(int track, int numLoops, int startFrame, int duration) {
if ((waveHeader.fmtFormatTag != 17) && (waveHeader.fmtFormatTag != 20)) {
consolePrintf("Wave file is in the wrong format! You must use IMA-ADPCM 4-bit mono.\n");
DS::std_fclose(file);
DS::std_fclose(s_file);
return;
}
@ -183,14 +186,14 @@ void playTrack(int track, int numLoops, int startFrame, int duration) {
// Skip chunks until we reach the data chunk
chunkHeader chunk;
DS::std_fread((const void *) &chunk, sizeof(chunkHeader), 1, file);
DS::std_fread(&chunk, sizeof(chunkHeader), 1, s_file);
while (!((chunk.name[0] == 'd') && (chunk.name[1] == 'a') && (chunk.name[2] == 't') && (chunk.name[3] == 'a'))) {
DS::std_fseek(file, chunk.size, SEEK_CUR);
DS::std_fread((const void *) &chunk, sizeof(chunkHeader), 1, file);
DS::std_fseek(s_file, chunk.size, SEEK_CUR);
DS::std_fread(&chunk, sizeof(chunkHeader), 1, s_file);
}
dataChunkStart = DS::std_ftell(file);
dataChunkStart = DS::std_ftell(s_file);
static bool started = false;
@ -234,14 +237,14 @@ void playTrack(int track, int numLoops, int startFrame, int duration) {
// No need to seek if we're starting from the beginning
if (block != 0) {
DS::std_fseek(file, dataChunkStart + block * waveHeader.fmtBlockAlign, SEEK_SET);
DS::std_fseek(s_file, dataChunkStart + block * waveHeader.fmtBlockAlign, SEEK_SET);
// consolePrintf("Startframe: %d msec: %d (%d,%d)\n", startFrame, tenthssec, samples, block);
}
//decompressBlock();
playNextBlock();
DS::CD::numLoops = numLoops;
s_numLoops = numLoops;
}
void update() {
@ -263,20 +266,20 @@ void decompressBlock() {
do {
DS::std_fread((const void *) &blockHeader, sizeof(blockHeader), 1, file);
DS::std_fread(&blockHeader, sizeof(blockHeader), 1, s_file);
DS::std_fread(&block[0], waveHeader.fmtBlockAlign - sizeof(blockHeader), 1, file);
DS::std_fread(&block[0], waveHeader.fmtBlockAlign - sizeof(blockHeader), 1, s_file);
if (DS::std_feof(file) ) {
if (DS::std_feof(s_file)) {
// Reached end of file, so loop
if ((numLoops == -1) || (numLoops > 1)) {
if ((s_numLoops == -1) || (s_numLoops > 1)) {
// Seek file to first packet
if (numLoops != -1) {
numLoops--;
if (s_numLoops != -1) {
s_numLoops--;
}
DS::std_fseek(file, dataChunkStart, SEEK_SET);
DS::std_fseek(s_file, dataChunkStart, SEEK_SET);
loop = true;
} else {
// Fill decompression buffer with zeros to prevent glitching
@ -325,46 +328,31 @@ void decompressBlock() {
int offset = 0;
switch (7 - (r & 0x0007)) {
case 0: {
case 0:
offset = (word & 0xF0000000) >> 28;
break;
}
case 1: {
case 1:
offset = (word & 0x0F000000) >> 24;
break;
}
case 2: {
case 2:
offset = (word & 0x00F00000) >> 20;
break;
}
case 3: {
case 3:
offset = (word & 0x000F0000) >> 16;
break;
}
case 4: {
case 4:
offset = (word & 0x0000F000) >> 12;
break;
}
case 5: {
case 5:
offset = (word & 0x00000F00) >> 8;
break;
}
case 6: {
case 6:
offset = (word & 0x000000F0) >> 4;
break;
}
case 7: {
case 7:
offset = (word & 0x0000000F);
break;
}
}
int diff = 0;
@ -406,7 +394,8 @@ void decompressBlock() {
}
void playNextBlock() {
if (!isPlayingFlag) return;
if (!isPlayingFlag)
return;
int lastBlockId = -1;
while (IPC->adpcm.semaphore); // Wait for buffer to become free if needed
@ -442,9 +431,6 @@ void playNextBlock() {
// DC_FlushAll();
}
}
@ -460,9 +446,10 @@ void playNextBlock() {
}
void stopTrack() {
if (!isPlayingFlag) return;
if (!isPlayingFlag)
return;
DS::std_fclose(file);
DS::std_fclose(s_file);
isPlayingFlag = false;
@ -495,8 +482,8 @@ bool trackExists(int num) {
}
consolePrintf("Looking for %s...", path.c_str());
FILE* file;
if ((file = DS::std_fopen(path.c_str(), "r"))) {
FILE *file = DS::std_fopen(path.c_str(), "r");
if (file) {
consolePrintf("Success!\n");
setActive(true);
DS::std_fclose(file);
@ -548,4 +535,4 @@ bool isPlaying() {
}
}
}
} // End of namespace DS

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -35,6 +38,6 @@ bool isPlaying();
void update();
}
}
} // End of namespace DS
#endif

View file

@ -1,539 +0,0 @@
/*************************************************************************
* Name: lz.c
* Author: Marcus Geelnard
* Description: LZ77 coder/decoder implementation.
* Reentrant: Yes
* $Id$
*
* The LZ77 compression scheme is a substitutional compression scheme
* proposed by Abraham Lempel and Jakob Ziv in 1977. It is very simple in
* its design, and uses no fancy bit level compression.
*
* This is my first attempt at an implementation of a LZ77 code/decoder.
*
* The principle of the LZ77 compression algorithm is to store repeated
* occurrences of strings as references to previous occurrences of the same
* string. The point is that the reference consumes less space than the
* string itself, provided that the string is long enough (in this
* implementation, the string has to be at least 4 bytes long, since the
* minimum coded reference is 3 bytes long). Also note that the term
* "string" refers to any kind of byte sequence (it does not have to be
* an ASCII string, for instance).
*
* The coder uses a brute force approach to finding string matches in the
* history buffer (or "sliding window", if you wish), which is very, very
* slow. I recon the complexity is somewhere between O(n^2) and O(n^3),
* depending on the input data.
*
* There is also a faster implementation that uses a large working buffer
* in which a "jump table" is stored, which is used to quickly find
* possible string matches (see the source code for LZ_CompressFast() for
* more information). The faster method is an order of magnitude faster,
* and also does a full string search in the entire input buffer (it does
* not use a sliding window).
*
* The upside is that decompression is very fast, and the compression ratio
* is often very good.
*
* The reference to a string is coded as a (length,offset) pair, where the
* length indicates the length of the string, and the offset gives the
* offset from the current data position. To distinguish between string
* references and literal strings (uncompressed bytes), a string reference
* is preceded by a marker byte, which is chosen as the least common byte
* symbol in the input data stream (this marker byte is stored in the
* output stream as the first byte).
*
* Occurrences of the marker byte in the stream are encoded as the marker
* byte followed by a zero byte, which means that occurrences of the marker
* byte have to be coded with two bytes.
*
* The lengths and offsets are coded in a variable length fashion, allowing
* values of any magnitude (up to 4294967295 in this implementation).
*
* With this compression scheme, the worst case compression result is
* (257/256)*insize + 1.
*
*-------------------------------------------------------------------------
* Copyright (c) 2003-2004 Marcus Geelnard
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Marcus Geelnard
* marcus.geelnard at home.se
*************************************************************************/
/*************************************************************************
* Constants used for LZ77 coding
*************************************************************************/
/* Maximum offset (can be any size < 2^32). Lower values gives faster
compression, while higher values gives better compression.
NOTE: LZ_CompressFast does not use this constant. */
#define LZ_MAX_OFFSET 512
/*************************************************************************
* INTERNAL FUNCTIONS *
*************************************************************************/
/*************************************************************************
* _LZ_StringCompare() - Return maximum length string match.
*************************************************************************/
inline static unsigned int _LZ_StringCompare( unsigned char * str1,
unsigned char * str2, unsigned int minlen, unsigned int maxlen )
{
unsigned int len;
for ( len = minlen; (len < maxlen) && (str1[len] == str2[len]); ++ len );
return len;
}
/*************************************************************************
* _LZ_WriteVarSize() - Write unsigned integer with variable number of
* bytes depending on value.
*************************************************************************/
inline static int _LZ_WriteVarSize( unsigned int x, unsigned char * buf )
{
unsigned int y;
int num_bytes, i, b;
/* Determine number of bytes needed to store the number x */
y = x >> 3;
for ( num_bytes = 5; num_bytes >= 2; -- num_bytes )
{
if ( y & 0xfe000000 ) break;
y <<= 7;
}
/* Write all bytes, seven bits in each, with 8:th bit set for all */
/* but the last byte. */
for ( i = num_bytes-1; i >= 0; -- i )
{
b = (x >> (i*7)) & 0x0000007f;
if ( i > 0 )
{
b |= 0x00000080;
}
*buf ++ = (unsigned char) b;
}
/* Return number of bytes written */
return num_bytes;
}
/*************************************************************************
* _LZ_ReadVarSize() - Read unsigned integer with variable number of
* bytes depending on value.
*************************************************************************/
inline static int _LZ_ReadVarSize( unsigned int * x, unsigned char * buf )
{
unsigned int y, b, num_bytes;
/* Read complete value (stop when byte contains zero in 8:th bit) */
y = 0;
num_bytes = 0;
do
{
b = (unsigned int) (*buf ++);
y = (y << 7) | (b & 0x0000007f);
++ num_bytes;
}
while ( b & 0x00000080 );
/* Store value in x */
*x = y;
/* Return number of bytes read */
return num_bytes;
}
/*************************************************************************
* PUBLIC FUNCTIONS *
*************************************************************************/
/*************************************************************************
* LZ_Compress() - Compress a block of data using an LZ77 coder.
* in - Input (uncompressed) buffer.
* out - Output (compressed) buffer. This buffer must be 0.4% larger
* than the input buffer, plus one byte.
* insize - Number of input bytes.
* The function returns the size of the compressed data.
*************************************************************************/
int LZ_Compress( unsigned char *in, unsigned char *out,
unsigned int insize )
{
unsigned char marker, symbol;
unsigned int inpos, outpos, bytesleft, i;
unsigned int maxoffset, offset, bestoffset;
unsigned int maxlength, length, bestlength;
unsigned int histogram[ 256 ];
unsigned char *ptr1, *ptr2;
/* Do we have anything to compress? */
if ( insize < 1 )
{
return 0;
}
/* Create histogram */
for ( i = 0; i < 256; ++ i )
{
histogram[ i ] = 0;
}
for ( i = 0; i < insize; ++ i )
{
++ histogram[ in[ i ] ];
}
/* Find the least common byte, and use it as the code marker */
marker = 0;
for ( i = 1; i < 256; ++ i )
{
if ( histogram[ i ] < histogram[ marker ] )
{
marker = i;
}
}
/* Remember the repetition marker for the decoder */
out[ 0 ] = marker;
/* Start of compression */
inpos = 0;
outpos = 1;
/* Main compression loop */
bytesleft = insize;
do
{
/* Determine most distant position */
if ( inpos > LZ_MAX_OFFSET ) maxoffset = LZ_MAX_OFFSET;
else maxoffset = inpos;
/* Get pointer to current position */
ptr1 = &in[ inpos ];
/* Search history window for maximum length string match */
bestlength = 3;
bestoffset = 0;
for ( offset = 3; offset <= maxoffset; ++ offset )
{
/* Get pointer to candidate string */
ptr2 = &ptr1[ -offset ];
/* Quickly determine if this is a candidate (for speed) */
if ( (ptr1[ 0 ] == ptr2[ 0 ]) &&
(ptr1[ bestlength ] == ptr2[ bestlength ]) )
{
/* Determine maximum length for this offset */
maxlength = (bytesleft < offset ? bytesleft : offset);
/* Count maximum length match at this offset */
length = _LZ_StringCompare( ptr1, ptr2, 0, maxlength );
/* Better match than any previous match? */
if ( length > bestlength )
{
bestlength = length;
bestoffset = offset;
}
}
}
/* Was there a good enough match? */
if ( (bestlength >= 8) ||
((bestlength == 4) && (bestoffset <= 0x0000007f)) ||
((bestlength == 5) && (bestoffset <= 0x00003fff)) ||
((bestlength == 6) && (bestoffset <= 0x001fffff)) ||
((bestlength == 7) && (bestoffset <= 0x0fffffff)) )
{
out[ outpos ++ ] = (unsigned char) marker;
outpos += _LZ_WriteVarSize( bestlength, &out[ outpos ] );
outpos += _LZ_WriteVarSize( bestoffset, &out[ outpos ] );
inpos += bestlength;
bytesleft -= bestlength;
}
else
{
/* Output single byte (or two bytes if marker byte) */
symbol = in[ inpos ++ ];
out[ outpos ++ ] = symbol;
if ( symbol == marker )
{
out[ outpos ++ ] = 0;
}
-- bytesleft;
}
}
while ( bytesleft > 3 );
/* Dump remaining bytes, if any */
while ( inpos < insize )
{
if ( in[ inpos ] == marker )
{
out[ outpos ++ ] = marker;
out[ outpos ++ ] = 0;
}
else
{
out[ outpos ++ ] = in[ inpos ];
}
++ inpos;
}
return outpos;
}
/*************************************************************************
* LZ_CompressFast() - Compress a block of data using an LZ77 coder.
* in - Input (uncompressed) buffer.
* out - Output (compressed) buffer. This buffer must be 0.4% larger
* than the input buffer, plus one byte.
* insize - Number of input bytes.
* work - Pointer to a temporary buffer (internal working buffer), which
* must be able to hold (insize+65536) unsigned integers.
* The function returns the size of the compressed data.
*************************************************************************/
int LZ_CompressFast( unsigned char *in, unsigned char *out,
unsigned int insize, unsigned int *work )
{
unsigned char marker, symbol;
unsigned int inpos, outpos, bytesleft, i, index, symbols;
unsigned int offset, bestoffset;
unsigned int maxlength, length, bestlength;
unsigned int histogram[ 256 ], *lastindex, *jumptable;
unsigned char *ptr1, *ptr2;
/* Do we have anything to compress? */
if ( insize < 1 )
{
return 0;
}
/* Assign arrays to the working area */
lastindex = work;
jumptable = &work[ 65536 ];
/* Build a "jump table". Here is how the jump table works:
jumptable[i] points to the nearest previous occurrence of the same
symbol pair as in[i]:in[i+1], so in[i] == in[jumptable[i]] and
in[i+1] == in[jumptable[i]+1]. Following the jump table gives a
dramatic boost for the string search'n'match loop compared to doing
a brute force search. */
for ( i = 0; i < 65536; ++ i )
{
lastindex[ i ] = 0xffffffff;
}
for ( i = 0; i < insize-1; ++ i )
{
symbols = (((unsigned int)in[i]) << 8) | ((unsigned int)in[i+1]);
index = lastindex[ symbols ];
lastindex[ symbols ] = i;
jumptable[ i ] = index;
}
jumptable[ insize-1 ] = 0xffffffff;
/* Create histogram */
for ( i = 0; i < 256; ++ i )
{
histogram[ i ] = 0;
}
for ( i = 0; i < insize; ++ i )
{
++ histogram[ in[ i ] ];
}
/* Find the least common byte, and use it as the code marker */
marker = 0;
for ( i = 1; i < 256; ++ i )
{
if ( histogram[ i ] < histogram[ marker ] )
{
marker = i;
}
}
/* Remember the repetition marker for the decoder */
out[ 0 ] = marker;
/* Start of compression */
inpos = 0;
outpos = 1;
/* Main compression loop */
bytesleft = insize;
do
{
/* Get pointer to current position */
ptr1 = &in[ inpos ];
/* Search history window for maximum length string match */
bestlength = 3;
bestoffset = 0;
index = jumptable[ inpos ];
while ( index != 0xffffffff )
{
/* Get pointer to candidate string */
ptr2 = &in[ index ];
/* Quickly determine if this is a candidate (for speed) */
if ( ptr2[ bestlength ] == ptr1[ bestlength ] )
{
/* Determine maximum length for this offset */
offset = inpos - index;
maxlength = (bytesleft < offset ? bytesleft : offset);
/* Count maximum length match at this offset */
length = _LZ_StringCompare( ptr1, ptr2, 2, maxlength );
/* Better match than any previous match? */
if ( length > bestlength )
{
bestlength = length;
bestoffset = offset;
}
}
/* Get next possible index from jump table */
index = jumptable[ index ];
}
/* Was there a good enough match? */
if ( (bestlength >= 8) ||
((bestlength == 4) && (bestoffset <= 0x0000007f)) ||
((bestlength == 5) && (bestoffset <= 0x00003fff)) ||
((bestlength == 6) && (bestoffset <= 0x001fffff)) ||
((bestlength == 7) && (bestoffset <= 0x0fffffff)) )
{
out[ outpos ++ ] = (unsigned char) marker;
outpos += _LZ_WriteVarSize( bestlength, &out[ outpos ] );
outpos += _LZ_WriteVarSize( bestoffset, &out[ outpos ] );
inpos += bestlength;
bytesleft -= bestlength;
}
else
{
/* Output single byte (or two bytes if marker byte) */
symbol = in[ inpos ++ ];
out[ outpos ++ ] = symbol;
if ( symbol == marker )
{
out[ outpos ++ ] = 0;
}
-- bytesleft;
}
}
while ( bytesleft > 3 );
/* Dump remaining bytes, if any */
while ( inpos < insize )
{
if ( in[ inpos ] == marker )
{
out[ outpos ++ ] = marker;
out[ outpos ++ ] = 0;
}
else
{
out[ outpos ++ ] = in[ inpos ];
}
++ inpos;
}
return outpos;
}
/*************************************************************************
* LZ_Uncompress() - Uncompress a block of data using an LZ77 decoder.
* in - Input (compressed) buffer.
* out - Output (uncompressed) buffer. This buffer must be large
* enough to hold the uncompressed data.
* insize - Number of input bytes.
*************************************************************************/
void LZ_Uncompress( unsigned char *in, unsigned char *out,
unsigned int insize )
{
unsigned char marker, symbol;
unsigned int i, inpos, outpos, length, offset;
/* Do we have anything to compress? */
if ( insize < 1 )
{
return;
}
/* Get marker symbol from input stream */
marker = in[ 0 ];
inpos = 1;
/* Main decompression loop */
outpos = 0;
do
{
symbol = in[ inpos ++ ];
if ( symbol == marker )
{
/* We had a marker byte */
if ( in[ inpos ] == 0 )
{
/* It was a single occurrence of the marker byte */
out[ outpos ++ ] = marker;
++ inpos;
}
else
{
/* Extract true length and offset */
inpos += _LZ_ReadVarSize( &length, &in[ inpos ] );
inpos += _LZ_ReadVarSize( &offset, &in[ inpos ] );
/* Copy corresponding data from history window */
for ( i = 0; i < length; ++ i )
{
out[ outpos ] = out[ outpos - offset ];
++ outpos;
}
}
}
else
{
/* No marker, plain copy */
out[ outpos ++ ] = symbol;
}
}
while ( inpos < insize );
}

View file

@ -1,50 +0,0 @@
/*************************************************************************
* Name: lz.h
* Author: Marcus Geelnard
* Description: LZ77 coder/decoder interface.
* Reentrant: Yes
* $Id$
*-------------------------------------------------------------------------
* Copyright (c) 2003-2004 Marcus Geelnard
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Marcus Geelnard
* marcus.geelnard at home.se
*************************************************************************/
#ifndef _lz_h_
#define _lz_h_
/*************************************************************************
* Function prototypes
*************************************************************************/
int LZ_Compress( unsigned char *in, unsigned char *out,
unsigned int insize );
int LZ_CompressFast( unsigned char *in, unsigned char *out,
unsigned int insize, unsigned int *work );
void LZ_Uncompress( unsigned char *in, unsigned char *out,
unsigned int insize );
#endif /* _lz_h_ */

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -70,8 +73,6 @@
//#define USE_LIBCARTRESET
#include <nds.h>
#include <nds/registers_alt.h>
#include <nds/arm9/exceptions.h>
@ -80,8 +81,10 @@
//#include <ARM9/console.h> //basic print funcionality
#include <stdlib.h>
#include <string.h>
#include "NDS/scummvm_ipc.h"
#include "dsmain.h"
#include "string.h"
#include "osystem_ds.h"
#include "icons_raw.h"
#include "fat/gba_nds_fat.h"
@ -95,16 +98,16 @@
#ifdef USE_DEBUGGER
#include "user_debugger.h"
#endif
#include "ramsave.h"
#include "blitters.h"
#include "cartreset_nolibfat.h"
#include "keys.h"
#ifdef USE_PROFILER
#include "profiler/cyg-profile.h"
#endif
#include "engine.h"
#include "backends/fs/ds/ds-fs.h"
#include "base/version.h"
#include "engine.h"
#include "common/util.h"
extern "C" void OurIntrMain(void);
extern "C" u32 getExceptionAddress(u32 opcodeAddress, u32 thumbState);
@ -118,20 +121,18 @@ static const char *registerNames[] =
extern "C" void *__real_malloc(size_t size);
int total = 0;
static int s_total_malloc = 0;
void* operator new (size_t size)
{
void *operator new (size_t size) {
register unsigned int reg asm("lr");
volatile unsigned int poo = reg;
void *res = __real_malloc(size);
total += size;
s_total_malloc += size;
if (!res)
{
if (!res) {
// *((u8 *) NULL) = 0;
consolePrintf("Failed alloc (new) %d (%d)\n", size, total);
consolePrintf("Failed alloc (new) %d (%d)\n", size, s_total_malloc);
return NULL;
}
@ -151,8 +152,7 @@ extern "C" void* __wrap_malloc(size_t size) {
volatile unsigned int poo = reg;
if (size == 0)
{
if (size == 0) {
static int zeroSize = 0;
consolePrintf("0 size malloc (%d)", zeroSize++);
}
@ -162,12 +162,12 @@ extern "C" void* __wrap_malloc(size_t size) {
if (size > 50 * 1024) {
consolePrintf("Allocated %d (%x)\n", size, poo);
}
total += size;
s_total_malloc += size;
return res;
} else {
// *((u8 *) NULL) = 0;
consolePrintf("Failed alloc %d (%d)\n", size, total);
consolePrintf("Failed alloc %d (%d)\n", size, s_total_malloc);
return NULL;
}
}
@ -193,112 +193,109 @@ enum MouseMode {
#define SCUMM_GAME_HEIGHT 142
#define SCUMM_GAME_WIDTH 227
int textureID;
u16* texture;
int frameCount;
int currentTimeMillis;
static int frameCount;
static int currentTimeMillis;
// Timer Callback
int callbackInterval;
int callbackTimer;
OSystem_DS::TimerProc callback;
static int callbackInterval;
static int callbackTimer;
static OSystem_DS::TimerProc callback;
// Scaled
bool scaledMode;
int scX;
int scY;
static bool scaledMode;
static int scX;
static int scY;
int subScX;
int subScY;
int subScTargetX;
int subScTargetY;
int subScreenWidth = SCUMM_GAME_WIDTH;
int subScreenHeight = SCUMM_GAME_HEIGHT;
int subScreenScale = 256;
static int subScX;
static int subScY;
static int subScTargetX;
static int subScTargetY;
static int subScreenWidth = SCUMM_GAME_WIDTH;
static int subScreenHeight = SCUMM_GAME_HEIGHT;
static int subScreenScale = 256;
// Sound
int bufferSize;
s16* soundBuffer;
int bufferFrame;
int bufferRate;
int bufferSamples;
bool soundHiPart;
int soundFrequency;
static int bufferSize;
static s16 *soundBuffer;
static int bufferFrame;
static int bufferRate;
static int bufferSamples;
static bool soundHiPart;
static int soundFrequency;
// Events
int lastEventFrame;
bool indyFightState;
bool indyFightRight;
static int lastEventFrame;
static bool indyFightState;
static bool indyFightRight;
OSystem_DS::SoundProc soundCallback;
void* soundParam;
int lastCallbackFrame;
bool bufferFirstHalf;
bool bufferSecondHalf;
static OSystem_DS::SoundProc soundCallback;
static int lastCallbackFrame;
static bool bufferFirstHalf;
static bool bufferSecondHalf;
// Saved buffers
bool highBuffer;
bool displayModeIs8Bit = false;
static bool highBuffer;
static bool displayModeIs8Bit = false;
// Game id
u8 gameID;
static u8 gameID;
bool snapToBorder = false;
bool consoleEnable = false;
bool gameScreenSwap = false;
static bool snapToBorder = false;
static bool consoleEnable = false;
static bool gameScreenSwap = false;
bool isCpuScalerEnabled();
//#define HEAVY_LOGGING
MouseMode mouseMode = MOUSE_LEFT;
static MouseMode mouseMode = MOUSE_LEFT;
int storedMouseX = 0;
int storedMouseY = 0;
static int storedMouseX = 0;
static int storedMouseY = 0;
// Sprites
SpriteEntry sprites[128];
SpriteEntry spritesMain[128];
int tweak;
static SpriteEntry sprites[128];
static SpriteEntry spritesMain[128];
static int tweak;
// Shake
int shakePos = 0;
static int s_shakePos = 0;
// Keyboard
bool keyboardEnable = false;
bool leftHandedMode = false;
bool keyboardIcon = false;
static bool keyboardEnable = false;
static bool leftHandedMode = false;
static bool keyboardIcon = false;
// Touch
int touchScX, touchScY, touchX, touchY;
int mouseHotspotX, mouseHotspotY;
bool cursorEnable = false;
bool mouseCursorVisible = true;
bool rightButtonDown = false;
bool touchPadStyle = false;
int touchPadSensitivity = 8;
bool tapScreenClicks = true;
static int touchScX, touchScY, touchX, touchY;
static int mouseHotspotX, mouseHotspotY;
static bool cursorEnable = false;
static bool mouseCursorVisible = true;
static bool leftButtonDown = false;
static bool rightButtonDown = false;
static bool touchPadStyle = false;
static int touchPadSensitivity = 8;
static bool tapScreenClicks = true;
int tapCount = 0;
int tapTimeout = 0;
int tapComplete = 0;
static int tapCount = 0;
static int tapTimeout = 0;
static int tapComplete = 0;
// Dragging
int dragStartX, dragStartY;
bool dragging = false;
int dragScX, dragScY;
static int dragStartX, dragStartY;
static bool dragging = false;
static int dragScX, dragScY;
// Interface styles
char gameName[32];
static char gameName[32];
// 8-bit surface size
int gameWidth = 320;
int gameHeight = 200;
static int gameWidth = 320;
static int gameHeight = 200;
// Scale
bool twoHundredPercentFixedScale = false;
bool cpuScalerEnable = false;
static bool twoHundredPercentFixedScale = false;
static bool cpuScalerEnable = false;
// 100 256
// 150 192
@ -309,14 +306,14 @@ bool cpuScalerEnable = false;
#ifdef USE_PROFILER
int hBlankCount = 0;
static int hBlankCount = 0;
#endif
u8* scalerBackBuffer = NULL;
static u8 *scalerBackBuffer = NULL;
#define NUM_SUPPORTED_GAMES 21
gameListType gameList[NUM_SUPPORTED_GAMES] = {
static const gameListType gameList[NUM_SUPPORTED_GAMES] = {
// Unknown game - use normal SCUMM controls
{"unknown", CONT_SCUMM_ORIGINAL},
@ -345,31 +342,29 @@ gameListType gameList[NUM_SUPPORTED_GAMES] = {
{"parallaction", CONT_NIPPON},
};
gameListType* currentGame = NULL;
static const gameListType *s_currentGame = NULL;
// Stylus
#define ABS(x) ((x)>0?(x):-(x))
static bool penDown = FALSE;
static bool penHeld = FALSE;
static bool penReleased = FALSE;
static bool penDownLastFrame = FALSE;
static s32 penX = 0, penY = 0;
static s32 penDownX = 0, penDownY = 0;
static int keysDownSaved = 0;
static int keysReleasedSaved = 0;
static int keysChangedSaved = 0;
bool penDown = FALSE;
bool penHeld = FALSE;
bool penReleased = FALSE;
bool penDownLastFrame = FALSE;
s32 penX = 0, penY = 0;
s32 penDownX = 0, penDownY = 0;
int keysDownSaved = 0;
int keysReleasedSaved = 0;
int keysChangedSaved = 0;
static bool penDownSaved = FALSE;
static bool penReleasedSaved = FALSE;
static int penDownFrames = 0;
static int touchXOffset = 0;
static int touchYOffset = 0;
bool penDownSaved = FALSE;
bool penReleasedSaved = FALSE;
int penDownFrames = 0;
int touchXOffset = 0;
int touchYOffset = 0;
static int triggeredIcon = 0;
static int triggeredIconTimeout = 0;
int triggeredIcon = 0;
int triggeredIconTimeout = 0;
u16 savedPalEntry255 = RGB15(31, 31, 31);
static u16 savedPalEntry255 = RGB15(31, 31, 31);
extern "C" int scummvm_main(int argc, char *argv[]);
@ -382,8 +377,11 @@ void setIcon(int num, int x, int y, int imageNum, int flags, bool enable);
void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable);
void uploadSpriteGfx();
TransferSound soundControl;
static TransferSound soundControl;
static bool isScrollingWithDPad() {
return (getKeysHeld() & (KEY_L | KEY_R)) != 0;
}
bool isCpuScalerEnabled() {
return cpuScalerEnable || !displayModeIs8Bit;
@ -430,7 +428,7 @@ void setTopScreenZoom(int percentage) {
// return (ConfMan.hasKey("cpu_scaler", "ds") && ConfMan.getBool("cpu_scaler", "ds"));
controlType getControlType() {
return currentGame->control;
return s_currentGame->control;
}
@ -551,21 +549,8 @@ int getSoundFrequency() {
return soundFrequency;
}
void setControls(char* gameName) {
for (int r = 0; r < NUM_SUPPORTED_GAMES; r++) {
if (!stricmp(gameName, gameList[r].gameId)) {
currentGame = &gameList[r];
consolePrintf("Current game set to: %s\n", gameName);
return;
}
}
consolePrintf("Failed to set current game to: %s\n", gameName);
}
void exitGame() {
currentGame = NULL;
s_currentGame = NULL;
}
void initGame() {
@ -580,17 +565,17 @@ void initGame() {
setOptions();
//strcpy(gameName, ConfMan.getActiveDomain().c_str());
if (currentGame == NULL) {
if (s_currentGame == NULL) {
strcpy(gameName, ConfMan.get("gameid").c_str());
// consolePrintf("\n\n\n\nCurrent game: '%s' %d\n", gameName, gameName[0]);
currentGame = &gameList[0]; // Default game
s_currentGame = &gameList[0]; // Default game
for (int r = 0; r < NUM_SUPPORTED_GAMES; r++) {
if (!stricmp(gameName, gameList[r].gameId)) {
currentGame = &gameList[r];
// consolePrintf("Game list num: %d\n", currentGame);
s_currentGame = &gameList[r];
// consolePrintf("Game list num: %d\n", s_currentGame);
}
}
}
@ -785,7 +770,7 @@ void checkSleepMode() {
}
void setShowCursor(bool enable) {
if ((currentGame) && (currentGame->control == CONT_SCUMM_SAMNMAX)) {
if ((s_currentGame) && (s_currentGame->control == CONT_SCUMM_SAMNMAX)) {
if (cursorEnable) {
sprites[1].attribute[0] = ATTR0_BMP | 150;
} else {
@ -833,7 +818,7 @@ void setCursorIcon(const u8* icon, uint w, uint h, byte keycolor, int hotspotX,
}
}
if (currentGame->control != CONT_SCUMM_SAMNMAX)
if (s_currentGame->control != CONT_SCUMM_SAMNMAX)
return;
uint16 border = RGB15(24,24,24) | 0x8000;
@ -1031,7 +1016,7 @@ void displayMode16BitFlipBuffer() {
}
void setShakePos(int shakePos) {
shakePos = shakePos;
s_shakePos = shakePos;
}
@ -1040,8 +1025,9 @@ u16* get16BitBackBuffer() {
}
s32 get8BitBackBufferStride() {
// When the CPU scaler is enabled, the back buffer is in system RAM and is 320 pixels wide
// When the CPU scaler is disabled, the back buffer is in video memory and therefore must have a 512 pixel stride
// When the CPU scaler is enabled, the back buffer is in system RAM and is
// 320 pixels wide. When the CPU scaler is disabled, the back buffer is in
// video memory and therefore must have a 512 pixel stride.
if (isCpuScalerEnabled()){
return 320;
@ -1319,8 +1305,7 @@ bool getIsDisplayMode8Bit() {
return displayModeIs8Bit;
}
void doScreenTapMode(OSystem_DS* system)
{
void doScreenTapMode(OSystem_DS *system) {
Common::Event event;
static bool left = false, right = false;
@ -1353,7 +1338,7 @@ void doScreenTapMode(OSystem_DS* system)
right = true;
}
if (!(getKeysHeld() & (KEY_L | KEY_R))) {
if (!isScrollingWithDPad()) {
if (getKeysDown() & KEY_LEFT) {
event.type = Common::EVENT_LBUTTONDOWN;
@ -1386,21 +1371,17 @@ void doScreenTapMode(OSystem_DS* system)
system->addEvent(event);
}
void doButtonSelectMode(OSystem_DS* system)
{
void doButtonSelectMode(OSystem_DS *system) {
Common::Event event;
if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
if (!isScrollingWithDPad()) {
event.type = Common::EVENT_MOUSEMOVE;
event.mouse = Common::Point(getPenX(), getPenY());
system->addEvent(event);
//consolePrintf("x=%d y=%d \n", getPenX(), getPenY());
}
static bool leftButtonDown = false;
static bool rightButtonDown = false;
if (getPenReleased() && (leftButtonDown || rightButtonDown)) {
if (leftButtonDown) {
event.type = Common::EVENT_LBUTTONUP;
@ -1417,7 +1398,7 @@ void doButtonSelectMode(OSystem_DS* system)
if ((mouseMode != MOUSE_HOVER) || (!displayModeIs8Bit)) {
if (getPenDown() && (!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
if (getPenDown() && !isScrollingWithDPad()) {
if (mouseMode == MOUSE_LEFT) {
event.type = Common::EVENT_LBUTTONDOWN;
leftButtonDown = true;
@ -1459,7 +1440,7 @@ void doButtonSelectMode(OSystem_DS* system)
}
}
if (!((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) && (!getIndyFightState()) && (!getKeyboardEnable())) {
if (!isScrollingWithDPad() && !getIndyFightState() && !getKeyboardEnable()) {
if (!getPenHeld() || (mouseMode != MOUSE_HOVER)) {
if (getKeysDown() & KEY_LEFT) {
@ -1467,7 +1448,6 @@ void doButtonSelectMode(OSystem_DS* system)
}
if (rightButtonDown) {
Common::Event event;
event.mouse = Common::Point(getPenX(), getPenY());
event.type = Common::EVENT_RBUTTONUP;
system->addEvent(event);
@ -1476,14 +1456,13 @@ void doButtonSelectMode(OSystem_DS* system)
if (getKeysDown() & KEY_RIGHT) {
if ((currentGame->control != CONT_SCUMM_SAMNMAX) && (currentGame->control != CONT_FUTURE_WARS) && (currentGame->control != CONT_GOBLINS)) {
if ((s_currentGame->control != CONT_SCUMM_SAMNMAX) && (s_currentGame->control != CONT_FUTURE_WARS) && (s_currentGame->control != CONT_GOBLINS)) {
mouseMode = MOUSE_RIGHT;
} else {
// If we're playing sam and max, click and release the right mouse
// button to change verb
Common::Event event;
if (currentGame->control == CONT_FUTURE_WARS) {
if (s_currentGame->control == CONT_FUTURE_WARS) {
event.mouse = Common::Point(320 - 128, 200 - 128);
event.type = Common::EVENT_MOUSEMOVE;
system->addEvent(event);
@ -1557,8 +1536,8 @@ void addEventsToQueue() {
if (!indyFightState) {
if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R)) && (getKeysDown() & KEY_B)) {
if (currentGame->control == CONT_AGI) {
if (!isScrollingWithDPad() && (getKeysDown() & KEY_B)) {
if (s_currentGame->control == CONT_AGI) {
event.kbd.keycode = Common::KEYCODE_RETURN;
event.kbd.ascii = 13;
event.kbd.flags = 0;
@ -1596,8 +1575,7 @@ void addEventsToQueue() {
bool release = getKeysReleased() & (KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN);
bool shoulders = getKeysHeld() & (KEY_L | KEY_R);
if ( (down && (!shoulders)) || release)
{
if ( (down && (!shoulders)) || release) {
if (getKeysChanged() & KEY_LEFT) {
event.kbd.keycode = Common::KEYCODE_LEFT;
@ -1630,7 +1608,7 @@ void addEventsToQueue() {
}
if (!((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) && (!getIndyFightState()) && (!getKeyboardEnable())) {
if (!isScrollingWithDPad() && !getIndyFightState() && !getKeyboardEnable()) {
if ((getKeysDown() & KEY_A) && (!indyFightState)) {
gameScreenSwap = !gameScreenSwap;
@ -1669,14 +1647,12 @@ void addEventsToQueue() {
}
}
if (!getIndyFightState() && !((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) && (getKeysDown() & KEY_X)) {
if (!getIndyFightState() && !isScrollingWithDPad() && (getKeysDown() & KEY_X)) {
setKeyboardEnable(!keyboardEnable);
}
updateStatus();
Common::Event event;
if ((tapScreenClicks) && (getIsDisplayMode8Bit())) {
if ((!keyboardEnable) || (!isInsideKeyboard(penDownX, penDownY))) {
@ -1693,13 +1669,10 @@ void addEventsToQueue() {
if (!keyboardEnable) {
if (((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R)) || (indyFightState)) && (displayModeIs8Bit)) {
if ((isScrollingWithDPad() || (indyFightState)) && (displayModeIs8Bit)) {
// Controls specific to the control method
if (currentGame->control == CONT_SKY) {
if (s_currentGame->control == CONT_SKY) {
// Extra controls for Beneath a Steel Sky
if ((getKeysDown() & KEY_DOWN)) {
penY = 0;
@ -1707,9 +1680,8 @@ void addEventsToQueue() {
}
}
if (currentGame->control == CONT_AGI) {
if (s_currentGame->control == CONT_AGI) {
// Extra controls for Leisure Suit Larry and KQ4
if ((getKeysHeld() & KEY_UP) && (getKeysHeld() & KEY_START)
/*&& (!strcmp(gameName, "LLLLL"))*/) {
consolePrintf("Cheat key!\n");
@ -1722,16 +1694,11 @@ void addEventsToQueue() {
event.type = Common::EVENT_KEYUP;
system->addEvent(event);
}
}
if (currentGame->control == CONT_SIMON) {
if (s_currentGame->control == CONT_SIMON) {
// Extra controls for Simon the Sorcerer
if ((getKeysDown() & KEY_DOWN)) {
Common::Event event;
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = Common::KEYCODE_F10; // F10 or # - show hotspots
event.kbd.ascii = Common::ASCII_F10;
@ -1744,13 +1711,9 @@ void addEventsToQueue() {
}
}
if (currentGame->control == CONT_SCUMM_ORIGINAL) {
if (s_currentGame->control == CONT_SCUMM_ORIGINAL) {
// Extra controls for Scumm v1-5 games
if ((getKeysDown() & KEY_DOWN)) {
Common::Event event;
event.type = Common::EVENT_KEYDOWN;
event.kbd.keycode = Common::KEYCODE_PERIOD; // Full stop - skips current dialogue line
event.kbd.ascii = '.';
@ -1806,14 +1769,14 @@ void addEventsToQueue() {
if ((getKeysChanged() & KEY_START)) {
event.kbd.flags = 0;
event.type = getKeyEvent(KEY_START);
if (currentGame->control == CONT_FUTURE_WARS) {
if (s_currentGame->control == CONT_FUTURE_WARS) {
event.kbd.keycode = Common::KEYCODE_F10;
event.kbd.ascii = Common::ASCII_F10;
} else if (currentGame->control == CONT_GOBLINS) {
} else if (s_currentGame->control == CONT_GOBLINS) {
event.kbd.keycode = Common::KEYCODE_F1;
event.kbd.ascii = Common::ASCII_F1;
// consolePrintf("!!!!!F1!!!!!");
} else if (currentGame->control == CONT_AGI) {
} else if (s_currentGame->control == CONT_AGI) {
event.kbd.keycode = Common::KEYCODE_ESCAPE;
event.kbd.ascii = 27;
} else {
@ -1830,9 +1793,7 @@ void addEventsToQueue() {
}
consumeKeys();
consumePenEvents();
}
}
@ -1862,24 +1823,20 @@ void updateStatus() {
if (displayModeIs8Bit) {
if (!tapScreenClicks) {
switch (mouseMode) {
case MOUSE_LEFT: {
case MOUSE_LEFT:
offs = 1;
break;
}
case MOUSE_RIGHT: {
case MOUSE_RIGHT:
offs = 2;
break;
}
case MOUSE_HOVER: {
case MOUSE_HOVER:
offs = 0;
break;
}
default: {
default:
// Nothing!
offs = 0;
break;
}
}
setIcon(0, 208, 150, offs, 0, true);
}
@ -1962,15 +1919,12 @@ void setMainScreenScale(int x, int y) {
SUB_BG3_YDX = 0;
SUB_BG3_YDY = y;
} else*/ {
if (isCpuScalerEnabled() && (x==320))
{
if (isCpuScalerEnabled() && (x==320)) {
BG3_XDX = 256;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = y;
}
else
{
} else {
BG3_XDX = x;
BG3_XDY = 0;
BG3_YDX = 0;
@ -2057,11 +2011,9 @@ void VBlankHandler(void) {
soundUpdate();
if ((!gameScreenSwap) && (!(getKeysHeld() & KEY_L) && !(getKeysHeld() & KEY_R))) {
if (currentGame) {
if (currentGame->control != CONT_SCUMM_SAMNMAX) {
if ((!gameScreenSwap) && !isScrollingWithDPad()) {
if (s_currentGame) {
if (s_currentGame->control != CONT_SCUMM_SAMNMAX) {
if (getPenHeld() && (getPenY() < SCUMM_GAME_HEIGHT)) {
setTopScreenTarget(getPenX(), getPenY());
}
@ -2101,7 +2053,7 @@ void VBlankHandler(void) {
callbackTimer -= FRAME_TIME;
}
if ((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) {
if (isScrollingWithDPad()) {
if ((!dragging) && (getPenHeld()) && (penDownFrames > 5)) {
dragging = true;
@ -2144,7 +2096,7 @@ void VBlankHandler(void) {
SUB_BG3_CX = subScX + 64;
}
SUB_BG3_CY = subScY + (shakePos << 8);*/
SUB_BG3_CY = subScY + (s_shakePos << 8);*/
/*SUB_BG3_XDX = (int) (subScreenWidth / 256.0f * 256);
SUB_BG3_XDY = 0;
@ -2155,7 +2107,7 @@ void VBlankHandler(void) {
bool zooming = false;
if ((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) {
if (isScrollingWithDPad()) {
if ((getKeysHeld() & KEY_A) && (subScreenScale < ratio)) {
subScreenScale += 1;
zooming = true;
@ -2232,7 +2184,7 @@ void VBlankHandler(void) {
if (displayModeIs8Bit) {
if ((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) {
if (isScrollingWithDPad()) {
int offsX = 0, offsY = 0;
@ -2284,7 +2236,7 @@ void VBlankHandler(void) {
setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
setMainScreenScroll(scX << 8, (scY << 8) + (shakePos << 8));
setMainScreenScroll(scX << 8, (scY << 8) + (s_shakePos << 8));
setMainScreenScale(256, 256); // 1:1 scale
} else {
@ -2300,7 +2252,7 @@ void VBlankHandler(void) {
setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128));
setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8);
setMainScreenScroll(64, (scY << 8) + (shakePos << 8));
setMainScreenScroll(64, (scY << 8) + (s_shakePos << 8));
setMainScreenScale(320, 256); // 1:1 scale
}
@ -2388,7 +2340,7 @@ void uploadSpriteGfx() {
vramSetBankE(VRAM_E_MAIN_SPRITE);
// Convert texture from 24bit 888 to 16bit 1555, remembering to set top bit!
u8* srcTex = (u8 *) ::icons_raw;
const u8 *srcTex = (const u8 *) ::icons_raw;
for (int r = 32 * 256 ; r >= 0; r--) {
SPRITE_GFX_SUB[r] = 0x8000 | (srcTex[r * 3] >> 3) | ((srcTex[r * 3 + 1] >> 3) << 5) | ((srcTex[r * 3 + 2] >> 3) << 10);
SPRITE_GFX[r] = 0x8000 | (srcTex[r * 3] >> 3) | ((srcTex[r * 3 + 1] >> 3) << 5) | ((srcTex[r * 3 + 2] >> 3) << 10);
@ -2634,9 +2586,6 @@ void penUpdate() {
}
}
else
{
}
} else {
penDown = true;
@ -2822,31 +2771,6 @@ GLvector getPenPos() {
return v;
}
#ifdef GBA_SRAM_SAVE
void formatSramOption() {
consolePrintf("The following files are present in save RAM:\n");
DSSaveFileManager::instance()->listFiles();
consolePrintf("\nAre you sure you want to\n");
consolePrintf("DELETE all files?\n");
consolePrintf("A = Yes, X = No\n");
while (true) {
if (keysHeld() & KEY_A) {
DSSaveFileManager::instance()->formatSram();
consolePrintf("SRAM cleared!\n");
return;
}
if (keysHeld() & KEY_X) {
consolePrintf("Whew, that was close!\n");
return;
}
}
}
#endif
void setIndyFightState(bool st) {
indyFightState = st;
indyFightRight = true;
@ -2856,15 +2780,13 @@ bool getIndyFightState() {
return indyFightState;
}
gameListType* getCurrentGame() {
return currentGame;
}
///////////////////
// Fast Ram
///////////////////
#define FAST_RAM_SIZE (24000)
#define ITCM_DATA __attribute__((section(".itcm")))
u8 *fastRamPointer;
u8 fastRamData[FAST_RAM_SIZE] ITCM_DATA;
@ -2933,61 +2855,6 @@ void debug_print_stub(char *string) {
}
#endif
#ifdef USE_LIBCARTRESET
struct cardTranslate {
int cartResetId;
int svmId;
char dldiId[5];
};
cardTranslate cardReaderTable[] = {
{DEVICE_TYPE_M3SD, DEVICE_M3SD, "M3SD"},
{DEVICE_TYPE_M3CF, DEVICE_M3CF, "M3CF"},
{DEVICE_TYPE_MPCF, DEVICE_MPCF, "MPCF"},
{DEVICE_TYPE_SCCF, DEVICE_SCCF, "SCCF"},
{DEVICE_TYPE_SCSD, DEVICE_SCSD, "SCSD"},
{DEVICE_TYPE_SCSD, DEVICE_SCSD, "SCLT"},
{DEVICE_TYPE_NMMC, DEVICE_NMMC, "NMMC"},
};
void reboot() {
int deviceType = -1;
if (disc_getDeviceId() == DEVICE_DLDI) {
char id[6];
disc_getDldiId(id);
consolePrintf("DLDI Device ID: %s\n", id);
for (int r = 0; r < ARRAYSIZE(cardReaderTable); r++) {
if (!stricmp(id, cardReaderTable[r].dldiId)) {
deviceType = cardReaderTable[r].cartResetId;
}
}
} else {
for (int r = 0; r < ARRAYSIZE(cardReaderTable); r++) {
if (disc_getDeviceId() == cardReaderTable[r].svmId) {
deviceType = cardReaderTable[r].cartResetId;
}
}
}
consolePrintf("Device number: %x\n", deviceType);
if (deviceType == -1) {
IPC->reset = true; // Send message to ARM7 to turn power off
} else {
cartSetMenuMode(deviceType);
passmeloopEnter();
}
while (true); // Stop the program continuing beyond this point
}
#endif
void powerOff() {
while (keysHeld() != 0) { // Wait for all keys to be released.
@ -3002,12 +2869,10 @@ void powerOff() {
while (true);
} else {
#ifdef USE_LIBCARTRESET
reboot();
#else
IPC->reset = true; // Send message to ARM7 to turn power off
while (true); // Stop the program continuing beyond this point
#endif
while (true) {
// Stop the program from continuing beyond this point
}
}
}
@ -3056,7 +2921,10 @@ void dsExceptionHandler() {
registerNames[i], exceptionRegisters[i],
registerNames[i+8],exceptionRegisters[i+8]);
}
while(1);
while(1)
; // endles loop
u32 *stack = (u32 *)exceptionRegisters[13];
@ -3311,12 +3179,6 @@ int main(void) {
g_system = new OSystem_DS();
assert(g_system);
#ifdef GBA_SRAM_SAVE
if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R)) {
formatSramOption();
}
#endif
IPC->adpcm.semaphore = false;
// printf("'%s'", Common::ConfigManager::kTransientDomain.c_str());
@ -3344,6 +3206,11 @@ int main(void) {
const char *argv[] = {"/scummvmds", "--config=scummvmj.ini"};
#elif defined(DS_BUILD_K)
const char *argv[] = {"/scummvmds", "--config=scummvmk.ini"};
#else
// Use the default config file if no build was specified. This currently
// only happens with builds made using the regular ScummVM build system (as
// opposed to the nds specific build system).
const char *argv[] = {"/scummvmds"};
#endif
@ -3356,7 +3223,8 @@ int main(void) {
return 0;
}
}
} // End of namespace DS
int main() {
DS::main();
@ -3377,7 +3245,6 @@ extern "C" void consolePrintf(char * format, ...) __attribute__ ((no_instrument_
extern "C" void consolePrintf(const char * format, ...) {
char buffer[256];
va_list args;
va_start(args, format);
viprintf(format, args);

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -25,7 +28,6 @@
#include <nds.h>
#include "osystem_ds.h"
#include "NDS/scummvm_ipc.h"
namespace DS {
@ -38,7 +40,7 @@ enum controlType {
CONT_FUTURE_WARS,
CONT_AGI,
CONT_GOBLINS,
CONT_NIPPON,
CONT_NIPPON
};
struct gameListType {
@ -68,9 +70,6 @@ int leftHandedSwap(int keys);
void setGameScreenSwap(bool enable);
void setSensitivity(int sensitivity);
// Controls options
void setControls(char* gameName);
// Video
void displayMode8Bit(); // Switch to 8-bit mode5
void displayMode16Bit(); // Switch to 16-bit mode5
@ -155,10 +154,10 @@ void fastRamReset();
void* fastRamAlloc(int size);
void exitGame();
gameListType* getCurrentGame();
}
} // End of namespace DS
int cygprofile_getHBlanks();

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -31,6 +34,8 @@
#include "touchkeyboard.h"
#include "gui/PopUpWidget.h"
#include "common/translation.h"
#define ALLOW_CPU_SCALER
namespace DS {
@ -51,27 +56,27 @@ static int confGetInt(Common::String key, int defaultVal) {
DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
new GUI::ButtonWidget(this, 10, 170, 72, 16, "Close", GUI::kCloseCmd, 'C');
new GUI::ButtonWidget(this, 320 - 10 - 130, 170, 120, 16, "ScummVM Main Menu", 0x40000000, 'M');
new GUI::ButtonWidget(this, 10, 170, 72, 16, _("~C~lose"), 0, GUI::kCloseCmd);
new GUI::ButtonWidget(this, 320 - 10 - 130, 170, 120, 16, _("ScummVM Main Menu"), 0, 0x40000000, 'M');
_tab = new GUI::TabWidget(this, 10, 5, 300, 230 - 20 - 40 - 20);
_tab->addTab("Controls");
_leftHandedCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 130, 20, "Left handed mode", 0, 'L');
_indyFightCheckbox = new GUI::CheckboxWidget(_tab, 5, 20, 140, 20, "Indy fight controls", 0, 'I');
_showCursorCheckbox = new GUI::CheckboxWidget(_tab, 150, 5, 130, 20, "Show mouse cursor", 0, 'T');
_snapToBorderCheckbox = new GUI::CheckboxWidget(_tab, 150, 20, 130, 20, "Snap to edges", 0, 'T');
_leftHandedCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 130, 20, _("~L~eft handed mode"));
_indyFightCheckbox = new GUI::CheckboxWidget(_tab, 5, 20, 140, 20, _("~I~ndy fight controls"));
_showCursorCheckbox = new GUI::CheckboxWidget(_tab, 150, 5, 130, 20, _("Show mouse cursor"), 0, 0, 'T');
_snapToBorderCheckbox = new GUI::CheckboxWidget(_tab, 150, 20, 130, 20, _("Snap to edges"), 0, 0, 'T');
new GUI::StaticTextWidget(_tab, 20, 35, 100, 15, "Touch X Offset", Graphics::kTextAlignLeft);
_touchX = new GUI::SliderWidget(_tab, 130, 35, 130, 12, 1);
new GUI::StaticTextWidget(_tab, 20, 35, 100, 15, _("Touch X Offset"), Graphics::kTextAlignLeft);
_touchX = new GUI::SliderWidget(_tab, 130, 35, 130, 12, "TODO: Add tooltip", 1);
_touchX->setMinValue(-8);
_touchX->setMaxValue(+8);
_touchX->setValue(0);
_touchX->setFlags(GUI::WIDGET_CLEARBG);
new GUI::StaticTextWidget(_tab, 20, 50, 100, 15, "Touch Y Offset", Graphics::kTextAlignLeft);
_touchY = new GUI::SliderWidget(_tab, 130, 50, 130, 12, 2);
new GUI::StaticTextWidget(_tab, 20, 50, 100, 15, _("Touch Y Offset"), Graphics::kTextAlignLeft);
_touchY = new GUI::SliderWidget(_tab, 130, 50, 130, 12, "TODO: Add tooltip", 2);
_touchY->setMinValue(-8);
_touchY->setMaxValue(+8);
_touchY->setValue(0);
@ -82,11 +87,11 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
new GUI::StaticTextWidget(_tab, 130 - 20, 65, 20, 15, "-8", Graphics::kTextAlignCenter);
_touchPadStyle = new GUI::CheckboxWidget(_tab, 5, 80, 270, 20, "Use laptop trackpad-style cursor control", 0x20000001, 'T');
_screenTaps = new GUI::CheckboxWidget(_tab, 5, 95, 285, 20, "Tap for left click, double tap right click", 0x20000002, 'T');
_touchPadStyle = new GUI::CheckboxWidget(_tab, 5, 80, 270, 20, _("Use laptop trackpad-style cursor control"), 0, 0x20000001, 'T');
_screenTaps = new GUI::CheckboxWidget(_tab, 5, 95, 285, 20, _("Tap for left click, double tap right click"), 0, 0x20000002, 'T');
_sensitivityLabel = new GUI::StaticTextWidget(_tab, 20, 110, 110, 15, "Sensitivity", Graphics::kTextAlignLeft);
_sensitivity = new GUI::SliderWidget(_tab, 130, 110, 130, 12, 1);
_sensitivityLabel = new GUI::StaticTextWidget(_tab, 20, 110, 110, 15, _("Sensitivity"), Graphics::kTextAlignLeft);
_sensitivity = new GUI::SliderWidget(_tab, 130, 110, 130, 12, "TODO: Add tooltip", 1);
_sensitivity->setMinValue(4);
_sensitivity->setMaxValue(16);
_sensitivity->setValue(8);
@ -94,20 +99,20 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
_tab->addTab("Graphics");
new GUI::StaticTextWidget(_tab, 5, 67, 180, 15, "Initial top screen scale:", Graphics::kTextAlignLeft);
new GUI::StaticTextWidget(_tab, 5, 67, 180, 15, _("Initial top screen scale:"), Graphics::kTextAlignLeft);
_100PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 82, 80, 20, "100%", 0x30000001, 'T');
_150PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 97, 80, 20, "150%", 0x30000002, 'T');
_200PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 112, 80, 20, "200%", 0x30000003, 'T');
_100PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 82, 80, 20, "100%", "TODO: Add tooltip", 0x30000001, 'T');
_150PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 97, 80, 20, "150%", "TODO: Add tooltip", 0x30000002, 'T');
_200PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 112, 80, 20, "200%", "TODO: Add tooltip", 0x30000003, 'T');
new GUI::StaticTextWidget(_tab, 5, 5, 180, 15, "Main screen scaling:", Graphics::kTextAlignLeft);
new GUI::StaticTextWidget(_tab, 5, 5, 180, 15, _("Main screen scaling:"), Graphics::kTextAlignLeft);
_hardScaler = new GUI::CheckboxWidget(_tab, 5, 20, 270, 20, "Hardware scale (fast, but low quality)", 0x10000001, 'T');
_cpuScaler = new GUI::CheckboxWidget(_tab, 5, 35, 270, 20, "Software scale (good quality, but slower)", 0x10000002, 'S');
_unscaledCheckbox = new GUI::CheckboxWidget(_tab, 5, 50, 270, 20, "Unscaled (you must scroll left and right)", 0x10000003, 'S');
_hardScaler = new GUI::CheckboxWidget(_tab, 5, 20, 270, 20, _("Hardware scale (fast, but low quality)"), 0, 0x10000001, 'T');
_cpuScaler = new GUI::CheckboxWidget(_tab, 5, 35, 270, 20, _("Software scale (good quality, but slower)"), 0, 0x10000002, 'S');
_unscaledCheckbox = new GUI::CheckboxWidget(_tab, 5, 50, 270, 20, _("Unscaled (you must scroll left and right)"), 0, 0x10000003, 'S');
new GUI::StaticTextWidget(_tab, 5, 125, 110, 15, "Brightness:", Graphics::kTextAlignLeft);
_gammaCorrection = new GUI::SliderWidget(_tab, 130, 120, 130, 12, 1);
new GUI::StaticTextWidget(_tab, 5, 125, 110, 15, _("Brightness:"), Graphics::kTextAlignLeft);
_gammaCorrection = new GUI::SliderWidget(_tab, 130, 120, 130, 12, "TODO: Add tooltip", 1);
_gammaCorrection->setMinValue(0);
_gammaCorrection->setMaxValue(8);
_gammaCorrection->setValue(0);
@ -116,8 +121,8 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
_tab->addTab("General");
_highQualityAudioCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 250, 20, "High quality audio (slower) (reboot)", 0, 'T');
_disablePowerOff = new GUI::CheckboxWidget(_tab, 5, 20, 200, 20, "Disable power off", 0, 'T');
_highQualityAudioCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 250, 20, _("High quality audio (slower) (reboot)"), 0, 0, 'T');
_disablePowerOff = new GUI::CheckboxWidget(_tab, 5, 20, 200, 20, _("Disable power off"), 0, 0, 'T');
_tab->setActiveTab(0);
@ -125,7 +130,7 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
#ifdef DS_SCUMM_BUILD
if (!DS::isGBAMPAvailable()) {
// addButton(this, 100, 140, "Delete Save", 'dels', 'D');
// addButton(this, 100, 140, "Delete Save", 0, 'dels', 'D');
}
#endif
@ -133,7 +138,7 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
//#ifdef ALLOW_CPU_SCALER
// _cpuScaler = new GUI::CheckboxWidget(this, 160, 115, 90, 20, "CPU scaler", 0, 'T');
// _cpuScaler = new GUI::CheckboxWidget(this, 160, 115, 90, 20, "CPU scaler", 0, 0, 'T');
//#endif
@ -418,7 +423,7 @@ void setOptions() {
DS::setTrackPadStyleEnable(enable);
if ((enable) and (firstLoad)) {
if (enable && firstLoad) {
// If we've just booted up, want to swap screens when trackpad mode is in use
// but not every time we enter the options dialog.
DS::setGameScreenSwap(true);
@ -436,4 +441,5 @@ void setOptions() {
firstLoad = false;
}
}
} // End of namespace DS

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -78,6 +81,6 @@ protected:
extern void showOptionsDialog();
extern void setOptions();
}
} // End of namespace DS
#endif

View file

@ -294,9 +294,9 @@ u16 getRTCtoFileTime (void)
{
#ifdef NDS
return (
( ( (IPC->rtc_hours > 11 ? IPC->rtc_hours - 40 : IPC->rtc_hours) & 0x1F) << 11) |
( (IPC->rtc_minutes & 0x3F) << 5) |
( (IPC->rtc_seconds >> 1) & 0x1F) );
( ( (IPC->rtc.hours > 11 ? IPC->rtc.hours - 40 : IPC->rtc.hours) & 0x1F) << 11) |
( (IPC->rtc.minutes & 0x3F) << 5) |
( (IPC->rtc.seconds >> 1) & 0x1F) );
#else
return 0;
#endif
@ -306,9 +306,9 @@ u16 getRTCtoFileDate (void)
{
#ifdef NDS
return (
( ((IPC->rtc_year + 20) & 0x7F) <<9) |
( (IPC->rtc_month & 0xF) << 5) |
(IPC->rtc_day & 0x1F) );
( ((IPC->rtc.year + 20) & 0x7F) <<9) |
( (IPC->rtc.month & 0xF) << 5) |
(IPC->rtc.day & 0x1F) );
#else
return 0;
#endif

View file

@ -170,7 +170,7 @@ bool NMMC_IsInserted(void) {
Neo_EnableMMC( true ); // Open SPI port to MMC card
Neo_SendMMCCommand(MMC_SEND_CSD, 0);
if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured
if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occurred
Neo_EnableMMC( false );
return false;
}
@ -227,14 +227,14 @@ bool NMMC_StartUp(void) {
// Set block length
Neo_SendMMCCommand(MMC_SET_BLOCKLEN, BYTE_PER_READ );
if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured
if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occurred
Neo_EnableMMC( false );
return false;
}
// Check if we can use a higher SPI frequency
Neo_SendMMCCommand(MMC_SEND_CSD, 0);
if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured
if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occurred
Neo_EnableMMC( false );
return false;
}
@ -268,7 +268,7 @@ bool NMMC_WriteSectors (u32 sector, u8 numSecs, void* buffer)
Neo_EnableMMC( true ); // Open SPI port to MMC card
Neo_SendMMCCommand( 25, sector );
if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured
if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occurred
Neo_EnableMMC( false );
return false;
}
@ -318,7 +318,7 @@ bool NMMC_ReadSectors (u32 sector, u8 numSecs, void* buffer)
while (totalSecs--) {
Neo_SendMMCCommand(MMC_READ_BLOCK, sector );
if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured
if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occurred
Neo_EnableMMC( false );
return false;
}

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -44,10 +47,10 @@ GBAMPSaveFile::~GBAMPSaveFile() {
// consolePrintf("Closed file\n");
}
uint32 GBAMPSaveFile::read(void *buf, uint32 size) {
saveSize += size;
// consolePrintf("Read %d %d ", size, saveSize);
return DS::std_fread(buf, 1, size, handle);
uint32 GBAMPSaveFile::read(void *buf, uint32 length) {
saveSize += length;
// consolePrintf("Read %d %d ", length, saveSize);
return DS::std_fread(buf, 1, length, handle);
}
bool GBAMPSaveFile::eos() const {
@ -74,27 +77,27 @@ int32 GBAMPSaveFile::pos() const {
int32 GBAMPSaveFile::size() const {
int position = pos();
DS::std_fseek(handle, 0, SEEK_END);
int size = DS::std_ftell(handle);
int length = DS::std_ftell(handle);
DS::std_fseek(handle, position, SEEK_SET);
return size;
return length;
}
bool GBAMPSaveFile::seek(int32 pos, int whence) {
return DS::std_fseek(handle, pos, whence) == 0;
bool GBAMPSaveFile::seek(int32 newPos, int whence) {
return DS::std_fseek(handle, newPos, whence) == 0;
}
uint32 GBAMPSaveFile::write(const void *buf, uint32 size) {
if (bufferPos + size > SAVE_BUFFER_SIZE) {
uint32 GBAMPSaveFile::write(const void *buf, uint32 length) {
if (bufferPos + length > SAVE_BUFFER_SIZE) {
flushSaveBuffer();
saveSize += size;
// consolePrintf("Writing %d bytes from %x", size, buf);
// DS::std_fwrite(buf, 1, size, handle);
saveSize += length;
// consolePrintf("Writing %d bytes from %x", length, buf);
// DS::std_fwrite(buf, 1, length, handle);
memcpy(buffer + bufferPos, buf, size);
bufferPos += size;
memcpy(buffer + bufferPos, buf, length);
bufferPos += length;
saveSize += size;
saveSize += length;
/* int pos = 0;
@ -104,31 +107,31 @@ uint32 GBAMPSaveFile::write(const void *buf, uint32 size) {
bufferPos = 512;
pos += rest;
flushSaveBuffer();
size -= rest;
length -= rest;
// consolePrintf("First section: %d\n", rest);
while (size >= 512) {
while (length >= 512) {
DS::std_fwrite(((char *) (buf)) + pos, 1, 512, handle);
size -= 512;
length -= 512;
pos += 512;
// consolePrintf("Full chunk, %d left ", size);
// consolePrintf("Full chunk, %d left ", length);
}
bufferPos = 0;
memcpy(buffer + bufferPos, ((char *) (buf)) + pos, size);
bufferPos += size;
memcpy(buffer + bufferPos, ((char *) (buf)) + pos, length);
bufferPos += length;
// consolePrintf("%d left in buffer ", bufferPos);*/
} else {
memcpy(buffer + bufferPos, buf, size);
bufferPos += size;
memcpy(buffer + bufferPos, buf, length);
bufferPos += length;
saveSize += size;
saveSize += length;
}
// if ((size > 100) || (size <= 0)) consolePrintf("Write %d bytes\n", size);
return size;
// if ((length > 100) || (length <= 0)) consolePrintf("Write %d bytes\n", length);
return length;
}

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -24,6 +27,7 @@
#define _GBAMPSAVE_H_
#include "common/system.h"
#include "common/savefile.h"
#include "backends/fs/ds/ds-fs.h"
#define SAVE_BUFFER_SIZE 100000

View file

@ -74,7 +74,6 @@
#include <nds/system.h>
#include <nds/arm9/input.h>
//------------------------------------------------------------------------------
#define KEYS_CUR (( ((~REG_KEYINPUT)&0x3ff) | (((~IPC->buttons)&3)<<10) | (((~IPC->buttons)<<6) & (KEY_TOUCH|KEY_LID) ))^KEY_LID)
@ -89,9 +88,7 @@ static u8 delay = 60, repeat = 30, count = 60;
static uint16 oldx = 0;
static uint16 oldy = 0;
//------------------------------------------------------------------------------
void scanKeys(void) {
//------------------------------------------------------------------------------
keysold = keys;
keys = KEYS_CUR;
@ -110,42 +107,31 @@ void scanKeys(void) {
}
}
//------------------------------------------------------------------------------
uint32 keysHeld(void) {
//------------------------------------------------------------------------------
return keys;
}
//------------------------------------------------------------------------------
uint32 keysDown(void) {
//------------------------------------------------------------------------------
return (keys ^ keysold) & keys;
}
//------------------------------------------------------------------------------
uint32 keysDownRepeat(void) {
//------------------------------------------------------------------------------
uint32 tmp = keysrepeat;
keysrepeat = 0;
return tmp;
}
//------------------------------------------------------------------------------
void keysSetRepeat( u8 setDelay, u8 setRepeat ) {
//------------------------------------------------------------------------------
delay = setDelay;
repeat = setRepeat;
count = delay;
keysrepeat = 0;
}
//------------------------------------------------------------------------------
uint32 keysUp(void) {
//------------------------------------------------------------------------------
return (keys ^ keysold) & (~keys);
}
} // namespace ds
} // End of namespace DS

View file

@ -1,4 +1,27 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
namespace DS {
@ -10,4 +33,4 @@ uint32 keysDownRepeat(void);
void keysSetRepeat(u8 setDelay, u8 setRepeat);
uint32 keysUp(void);
}
} // End of namespace DS

View file

@ -1,107 +0,0 @@
/**********************************
Copyright (C) Rick Wong (Lick)
http://licklick.wordpress.com/
***********************************/
#include <cartreset_nolibfat.h>
#ifdef ARM9
bool cartSetMenuMode(u32 _deviceType)
{
*(vu16*)(0x04000204) &= ~0x0880; //sysSetBusOwners(true, true);
u32 deviceType = _deviceType;
*((vu32*)0x027FFFF8) = 0x080000C0; // ARM7 reset address
if(deviceType == DEVICE_TYPE_EFA2)
{
*(u16 *)0x9FE0000 = 0xD200;
*(u16 *)0x8000000 = 0x1500;
*(u16 *)0x8020000 = 0xD200;
*(u16 *)0x8040000 = 0x1500;
*(u16 *)0x9880000 = 1 << 15;
*(u16 *)0x9FC0000 = 0x1500;
return true;
}
else if(deviceType == DEVICE_TYPE_MPCF)
{
return true;
}
else if(deviceType == DEVICE_TYPE_EZSD)
{
return true;
}
else if(deviceType == DEVICE_TYPE_M3CF || deviceType == DEVICE_TYPE_M3SD)
{
u32 mode = 0x00400004;
vu16 tmp;
tmp = *(vu16*)(0x08E00002);
tmp = *(vu16*)(0x0800000E);
tmp = *(vu16*)(0x08801FFC);
tmp = *(vu16*)(0x0800104A);
tmp = *(vu16*)(0x08800612);
tmp = *(vu16*)(0x08000000);
tmp = *(vu16*)(0x08801B66);
tmp = *(vu16*)(0x08000000 + (mode << 1));
tmp = *(vu16*)(0x0800080E);
tmp = *(vu16*)(0x08000000);
tmp = *(vu16*)(0x080001E4);
tmp = *(vu16*)(0x080001E4);
tmp = *(vu16*)(0x08000188);
tmp = *(vu16*)(0x08000188);
return true;
}
else if(deviceType == DEVICE_TYPE_SCCF || deviceType == DEVICE_TYPE_SCSD)
{
*(vu16*)0x09FFFFFE = 0xA55A;
*(vu16*)0x09FFFFFE = 0xA55A;
*(vu16*)0x09FFFFFE = 0;
*(vu16*)0x09FFFFFE = 0;
*((vu32*)0x027FFFF8) = 0x08000000; // Special ARM7 reset address
return true;
}
return false;
}
void passmeloopEnter()
{
*(vu16*)(0x04000208) = 0; //REG_IME = IME_DISABLE;
*(vu16*)(0x04000204) |= 0x0880; //sysSetBusOwners(false, false);
*((vu32*)0x027FFFFC) = 0;
*((vu32*)0x027FFE04) = (u32)0xE59FF018;
*((vu32*)0x027FFE24) = (u32)0x027FFE04;
asm("swi 0x00"); //swiSoftReset();
asm("bx lr");
}
#endif
#ifdef ARM7
bool passmeloopQuery()
{
if(*((vu32*)0x027FFE24) == (u32)0x027FFE04)
return true;
return false;
}
void cartExecute()
{
*(vu16*)(0x04000208) = 0; //REG_IME = IME_DISABLE;
*((vu32*)0x027FFE34) = *((vu32*)0x027FFFF8);
asm("swi 0x00"); //swiSoftReset();
asm("bx lr");
}
#endif

View file

@ -1,57 +0,0 @@
/**********************************
Copyright (C) Rick Wong (Lick)
http://licklick.wordpress.com/
***********************************/
#ifndef CARTRESET_H
#define CARTRESET_H
//#include <fat.h>
#include <nds.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef ARM9
// Auto detect:
#define DEVICE_TYPE_AUTO 0x00000000 // doesn't work in libcartreset "nolibfat" version
// Not supported:
#define DEVICE_TYPE_FCSR 0x52534346
#define DEVICE_TYPE_MMCF 0x46434D4D
#define DEVICE_TYPE_NJSD 0x44534A4E
#define DEVICE_TYPE_NMMC 0x434D4D4E
// Supported:
#define DEVICE_TYPE_EFA2 0x32414645
#define DEVICE_TYPE_MPCF 0x4643504D
#define DEVICE_TYPE_M3CF 0x4643334D
#define DEVICE_TYPE_M3SD 0x4453334D
#define DEVICE_TYPE_SCCF 0x46434353
#define DEVICE_TYPE_SCSD 0x44534353
// Supported, but libfat doesn't detect the device:
#define DEVICE_TYPE_EZSD 0x44535A45
bool cartSetMenuMode(u32 _deviceType);
void passmeloopEnter();
#endif
#ifdef ARM7
bool passmeloopQuery();
void cartExecute();
#endif
#ifdef __cplusplus
}
#endif
#endif

View file

@ -66,6 +66,11 @@
#define DEFAULT_CONFIG_FILE "scummvmj.ini"
#elif defined(DS_BUILD_K)
#define DEFAULT_CONFIG_FILE "scummvmk.ini"
#else
// Use the "scummvm.ini" as config file if no build was specified. This
// currently only happens with builds made using the regular ScummVM build
// system (as opposed to the nds specific build system).
#define DEFAULT_CONFIG_FILE "scummvm.ini"
#endif
OSystem_DS *OSystem_DS::_instance = NULL;
@ -203,8 +208,7 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
}
}
void OSystem_DS::restoreHardwarePalette()
{
void OSystem_DS::restoreHardwarePalette() {
// Set the hardware palette up based on the stored palette
for (int r = 0; r < 255; r++) {
@ -305,7 +309,7 @@ void OSystem_DS::copyRectToScreen(const byte *buf, int pitch, int x, int y, int
for (int dy = y; dy < y + h; dy++) {
u8 *dest = ((u8 *) (bg)) + (dy * stride) + x;
u8* src = (u8 *) buf + (pitch * by);
const u8 *src = (const u8 *) buf + (pitch * by);
u32 dx;
@ -357,7 +361,7 @@ void OSystem_DS::copyRectToScreen(const byte *buf, int pitch, int x, int y, int
for (int dy = y; dy < y + h; dy++) {
u8 *dest = ((u8 *) (bg)) + (dy * stride) + x;
u8 *destSub = ((u8 *) (bgSub)) + (dy * 512) + x;
u8* src = (u8 *) buf + (pitch * by);
const u8 *src = (const u8 *) buf + (pitch * by);
u32 dx;
@ -458,7 +462,7 @@ void OSystem_DS::copyRectToScreen(const byte *buf, int pitch, int x, int y, int
}
void OSystem_DS::updateScreen() {
static int cnt = 0;
// static int cnt = 0;
// consolePrintf("updatescr %d\n", cnt++);
if ((_frameBufferExists) && (DS::getIsDisplayMode8Bit())) {
@ -586,7 +590,7 @@ void OSystem_DS::refreshCursor() {
DS::setCursorIcon(_cursorImage, _cursorW, _cursorH, _cursorKey, _cursorHotX, _cursorHotY);
}
void OSystem_DS::addEvent(Common::Event& e) {
void OSystem_DS::addEvent(const Common::Event& e) {
eventQueue[queuePos++] = e;
}
@ -725,26 +729,10 @@ void OSystem_DS::quit() {
}
Common::SaveFileManager *OSystem_DS::getSavefileManager() {
bool forceSram;
if (ConfMan.hasKey("forcesramsave", "ds")) {
forceSram = ConfMan.getBool("forcesramsave", "ds");
} else {
forceSram = false;
}
if (forceSram) {
consolePrintf("Using SRAM save method!\n");
}
if (DS::isGBAMPAvailable() && (!forceSram)) {
if (DS::isGBAMPAvailable()) {
return &mpSaveManager;
} else {
#ifdef GBA_SRAM_SAVE
return &saveManager;
#else
return NULL;
#endif
}
return NULL;
}

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -27,7 +30,6 @@
#include "backends/base-backend.h"
#include "common/events.h"
#include "nds.h"
#include "ramsave.h"
#include "gbampsave.h"
#include "backends/saves/default/default-saves.h"
#include "backends/timer/default/default-timer.h"
@ -44,9 +46,6 @@ protected:
Common::Event eventQueue[96];
int queuePos;
#ifdef GBA_SRAM_SAVE
DSSaveFileManager saveManager;
#endif
GBAMPSaveFileManager mpSaveManager;
Audio::MixerImpl *_mixer;
DefaultTimerManager *_timer;
@ -136,8 +135,8 @@ public:
virtual Common::SaveFileManager *getSavefileManager();
void addEvent(Common::Event& e);
bool isEventQueueEmpty() { return queuePos == 0; }
void addEvent(const Common::Event& e);
bool isEventQueueEmpty() const { return queuePos == 0; }
virtual bool grabRawScreen(Graphics::Surface *surf);
@ -161,8 +160,8 @@ public:
virtual void clearAutoComplete();
virtual void setCharactersEntered(int count);
u16 getDSPaletteEntry(u32 entry) { return _palette[entry]; }
u16 getDSCursorPaletteEntry(u32 entry) { return !_disableCursorPalette? _cursorPalette[entry]: _palette[entry]; }
u16 getDSPaletteEntry(u32 entry) const { return _palette[entry]; }
u16 getDSCursorPaletteEntry(u32 entry) const { return !_disableCursorPalette? _cursorPalette[entry]: _palette[entry]; }
virtual void setCursorPalette(const byte *colors, uint start, uint num);

View file

@ -8,39 +8,26 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef _PORTDEFS_H_
#define _PORTDEFS_H_
/*
typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;
*/
#include "nds/ndstypes.h"
// Somebody removed these from scummsys.h, but they're still required, so I'm adding them here
// in the hope that they'll stay.
// Somebody removed these from scummsys.h, but they're still required, so I'm
// adding them here in the hope that they'll stay.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -50,18 +37,20 @@ typedef signed int s32;
#define double float
#define CT_NO_TRANSPARENCY
#ifndef DISABLE_TEXT_CONSOLE
#define DISABLE_TEXT_CONSOLE
#endif
#ifndef DISABLE_COMMAND_LINE
#define DISABLE_COMMAND_LINE
#endif
#ifndef STREAM_AUDIO_FROM_DISK
#define STREAM_AUDIO_FROM_DISK
#endif
//#undef assert
//#define assert(expr) consolePrintf("Asserted!")
#define NO_DEBUG_MSGS
// This is defined in dsmain.cpp
#ifdef __cplusplus
extern "C" {
@ -76,15 +65,17 @@ void consolePrintf(const char *format, ...);
#undef assert
#endif
#define assert(s) if (!(s)) consolePrintf("Assertion failed: '##s##' at file %s, line %d\n", __FILE__, __LINE__)
#define assert(s) \
do { \
if (!(s)) \
consolePrintf("Assertion failed: '##s##' at file %s, line %d\n", __FILE__, __LINE__); \
} while (0)
//#include "ds-fs.h"
//#define debug(fmt, ...) consolePrintf(fmt, ##__VA_ARGS__)
//#define debug(fmt, ...) debug(0, fmt, ##__VA_ARGS__)
#define ITCM_DATA __attribute__((section(".itcm")))
// FIXME: Since I can't change the engine at the moment (post lockdown) this define can go here.
// This define changes the mouse-relative motion which doesn't make sense on a touch screen to
// a more conventional form of input where the menus can be clicked on.

View file

@ -1,538 +0,0 @@
/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifdef GBA_SRAM_SAVE
#include "ramsave.h"
#include "nds.h"
#include "compressor/lz.h"
#define CART_RAM ((vu8 *) (0x0A000000))
#define SRAM_SAVE_MAX (65533)
DSSaveFile::DSSaveFile() {
ptr = 0;
saveCompressed = false;
save.isValid = false;
ownsData = false;
isOpenFlag = true;
isTempFile = false;
}
DSSaveFile::DSSaveFile(SCUMMSave* s, bool compressed, u8* data) {
save = *s;
saveData = data;
ptr = 0;
saveCompressed = compressed;
isOpenFlag = true;
if (saveCompressed) {
u8* uncompressed = new unsigned char[save.size];
if (!uncompressed) consolePrintf("Out of memory allocating %d!\n", save.size);
LZ_Uncompress(saveData, uncompressed, save.compressedSize);
saveData = uncompressed;
ownsData = true;
saveCompressed = false;
// consolePrintf("Decompressed. name=%s size=%d (%d)", save.name, save.size, save.compressedSize);
} else {
ownsData = false;
origHeader = s;
}
if (save.magic == (int) 0xBEEFCAFE) {
save.isValid = true;
} else {
save.isValid = false;
}
isTempFile = false;
eosReached = false;
}
DSSaveFile::~DSSaveFile() {
if (!ownsData) {
*origHeader = save;
DSSaveFileManager::instance()->flushToSaveRAM();
}
if (ownsData) {
delete[] saveData;
}
}
bool DSSaveFile::loadFromSaveRAM(vu8* address) {
SCUMMSave newSave;
for (int t = 0; t < (int) sizeof(newSave); t++) {
((char *) (&newSave))[t] = *(address + t);
}
if (newSave.magic == 0xBEEFCAFE) {
newSave.isValid = true;
*((u16 *) (0x4000204)) |= 0x3;
saveData = new unsigned char[newSave.compressedSize];
for (int t = 0; t < (int) newSave.compressedSize; t++) {
((char *) (saveData))[t] = *(address + t + sizeof(newSave));
}
if (ownsData) delete[] this->saveData;
save = newSave;
saveCompressed = true;
this->saveData = saveData;
ownsData = true;
ptr = 0;
return true;
}
return false;
}
void DSSaveFile::compress() {
if (!saveCompressed) {
unsigned char* compBuffer = new unsigned char[(save.size * 110) / 100];
int compSize = LZ_Compress((u8 *) saveData, compBuffer, save.size);
save.compressedSize = compSize;
delete[] saveData;
// Make the save smaller
saveData = (u8 *) realloc(compBuffer, save.compressedSize);
saveCompressed = true;
}
}
int DSSaveFile::saveToSaveRAM(vu8* address) {
unsigned char* compBuffer;
bool failed;
int compSize;
compress();
compSize = save.compressedSize;
compBuffer = saveData;
if (DSSaveFileManager::instance()->getBytesFree() >= getRamUsage()) {
DSSaveFileManager::instance()->addBytesFree(-getRamUsage());
// Write header
for (int t = 0; t < sizeof(save); t++) {
while (*(address + t) != ((char *) (&save))[t]) {
*(address + t) = ((char *) (&save))[t];
}
}
// Write compressed buffer
for (int t = sizeof(save); t < (int) sizeof(save) + compSize; t++) {
while (*(address + t) != compBuffer[t - sizeof(save)]) {
*(address + t) = compBuffer[t - sizeof(save)];
}
}
failed = false;
} else {
failed = true;
}
return failed? 0: compSize + sizeof(save);
}
void DSSaveFile::reset() {
ptr = 0;
eosReached = false;
}
uint32 DSSaveFile::read(void *buf, uint32 size) {
if (ptr + size > save.size) {
size = save.size - ptr;
eosReached = true;
if (size < 0) size = 0;
}
memcpy(buf, saveData + ptr, size);
// consolePrintf("byte: %d ", ((u8 *) (buf))[0]);
ptr += size;
return size;
}
int32 DSSaveFile::pos() const {
return ptr;
}
int32 DSSaveFile::size() const {
return save.size;
}
bool DSSaveFile::seek(int32 pos, int whence) {
switch (whence) {
case SEEK_SET: {
ptr = pos;
break;
}
case SEEK_CUR: {
ptr += pos;
break;
}
case SEEK_END: {
ptr = save.size + pos;
break;
}
}
eosReached = false;
return true;
}
bool DSSaveFile::eos() const {
return eosReached;
}
void DSSaveFile::clearErr() {
eosReached = false;
}
bool DSSaveFile::skip(uint32 bytes) {
ptr = ptr + bytes;
if (ptr > (int) save.size) ptr = save.size;
return true;
}
uint32 DSSaveFile::write(const void *buf, uint32 size) {
if (ptr + size > DS_MAX_SAVE_SIZE) {
size = DS_MAX_SAVE_SIZE - ptr;
}
memcpy(saveData + ptr, buf, size);
ptr += size;
save.size += size;
return size;
}
bool DSSaveFile::matches(const char *prefix, int num) {
char str[16];
if (isValid()) {
sprintf(str, "%s%02d", prefix, num);
if (!strcmp(str, save.name)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
bool DSSaveFile::matches(const char *filename) {
if (isValid()) {
return !strcmp(save.name, filename);
} else {
return false;
}
}
void DSSaveFile::setName(char *name) {
save.isValid = true;
save.magic = 0xBEEFCAFE;
ownsData = true;
save.size = 0;
save.compressedSize = 0;
saveData = new unsigned char[DS_MAX_SAVE_SIZE];
strcpy(save.name, name);
if ((strstr(name, ".s99")) || (strstr(name, ".c"))) {
isTempFile = true;
} else {
isTempFile = false;
}
}
void DSSaveFile::clearData() {
save.size = 0;
if (saveCompressed) {
if (ownsData) {
delete[] saveData;
DSSaveFileManager::instance()->addBytesFree(getRamUsage());
}
saveData = new unsigned char[DS_MAX_SAVE_SIZE];
saveCompressed = false;
ownsData = true;
}
}
void DSSaveFile::deleteFile() {
if (isValid()) {
if (ownsData) {
DSSaveFileManager::instance()->addBytesFree(getRamUsage());
delete[] saveData;
saveData = NULL;
}
ptr = 0;
saveCompressed = false;
save.isValid = false;
ownsData = false;
isOpenFlag = true;
}
}
DSSaveFileManager::DSSaveFileManager() {
instancePtr = this;
*((u16 *) (0x4000204)) |= 0x3;
swiWaitForVBlank();
loadAllFromSRAM();
}
DSSaveFileManager::~DSSaveFileManager() {
instancePtr = NULL;
}
void DSSaveFileManager::loadAllFromSRAM() {
int addr = 1;
for (int r = 0; r < 8; r++) {
gbaSave[r].deleteFile();
}
sramBytesFree = SRAM_SAVE_MAX;
// Try to find saves in save RAM
for (int r = 0; r < 8; r++) {
if (gbaSave[r].loadFromSaveRAM(CART_RAM + addr)) {
addr += gbaSave[r].getRamUsage();
sramBytesFree -= gbaSave[r].getRamUsage();
}
}
}
void DSSaveFileManager::formatSram() {
for (int r = 0; r < SRAM_SAVE_MAX; r++) {
*(CART_RAM + r) = 0;
}
loadAllFromSRAM();
}
void DSSaveFileManager::listFiles() {
for (int r = 0; r < 8; r++) {
if (gbaSave[r].isValid()) {
consolePrintf("'%s': %d bytes\n", gbaSave[r].getName(), gbaSave[r].getRamUsage());
}
}
consolePrintf("SRAM free: %d bytes\n", getBytesFree());
}
DSSaveFileManager* DSSaveFileManager::instancePtr = NULL;
DSSaveFile *DSSaveFileManager::openSavefile(const char *filename, bool saveOrLoad) {
for (int r = 0; r < 8; r++) {
if (gbaSave[r].isValid() && (gbaSave[r].matches(filename))) {
// consolePrintf("Matched save %d (%d)\n", r, gbaSave[r].getSize());
gbaSave[r].reset();
//consolePrintf("reset ");
if (saveOrLoad) gbaSave[r].clearData();
// consolePrintf("cleared ");
return gbaSave[r].clone();
}
}
if (saveOrLoad) {
return makeSaveFile(filename, saveOrLoad);
} else {
return NULL;
}
}
DSSaveFile* DSSaveFile::clone() {
// consolePrintf("Clone %s %d\n", save.name, save.size);
return new DSSaveFile(&save, saveCompressed, saveData);
}
void DSSaveFileManager::deleteFile(const char* name) {
// consolePrintf("Deleting %s", name);
for (int r = 0; r < 8; r++) {
if (gbaSave[r].isValid() && (gbaSave[r].matches(name))) {
gbaSave[r].deleteFile();
}
}
flushToSaveRAM();
}
bool DSSaveFileManager::removeSavefile(const Common::String &filename) {
consolePrintf("DSSaveFileManager::removeSavefile : Not implemented yet.\n");
assert(false);
//TODO: Implement this. Most likely, you just have to use the code of deleteFile?
return false;
}
Common::StringArray DSSaveFileManager::listSavefiles(const Common::String &pattern) {
consolePrintf("DSSaveFileManager::listSavefiles : Not implemented yet.\n");
assert(false);
return Common::StringArray();
/*
TODO: Implement this. If you don't understand what it should do, just ask
(e.g. on scummvm-devel or Fingolfin). It should be pretty simple if you
use Common::matchString from common/util.h and read the Doxygen docs,
then combine this with the old code below...
*/
}
/*
void DSSaveFileManager::listSavefiles(const char *prefix, bool *marks, int num) {
memset(marks, true, num * sizeof(bool));
return;
memset(marks, false, num*sizeof(bool));
for (int saveNum = 0; saveNum < num; saveNum++) {
for (int r = 0; r < 8; r++) {
if (gbaSave[r].isValid() && (gbaSave[r].matches(prefix, saveNum))) {
marks[saveNum] = true;
}
}
}
}
*/
DSSaveFile *DSSaveFileManager::makeSaveFile(const char *filename, bool saveOrLoad) {
// Find a free save slot
int r = 0;
while ((r < 8) && (gbaSave[r].isValid())) {
r++;
}
if ((r == 8) && (gbaSave[r].isValid())) {
// No more saves
return NULL;
} else {
// Allocate this save
// consolePrintf("Allocated save %d\n", r);
gbaSave[r].setName((char *) filename);
gbaSave[r].reset();
return gbaSave[r].clone();
}
}
void DSSaveFileManager::flushToSaveRAM() {
int cartAddr = 1;
int s;
int extraData = DSSaveFileManager::getExtraData();
*((u16 *) (0x4000204)) |= 0x3;
swiWaitForVBlank();
int size = 0;
for (int r = 0; (r < 8); r++) {
if (gbaSave[r].isValid()) {
gbaSave[r].compress();
if (!gbaSave[r].isTemp()) size += gbaSave[r].getRamUsage();
}
}
if (size <= SRAM_SAVE_MAX) {
for (int r = 0; r < SRAM_SAVE_MAX; r++) {
*(CART_RAM + r) = 0;
}
sramBytesFree = SRAM_SAVE_MAX;
for (int r = 0; (r < 8); r++) {
if (gbaSave[r].isValid() && (!gbaSave[r].isTemp())) {
cartAddr += s = gbaSave[r].saveToSaveRAM(CART_RAM + cartAddr);
/* if (s == 0) {
consolePrintf("WARNING: Save didn't fit in cart RAM and has been lost!! Delete files and save again.", gbaSave[r].getName());
failed = true;
}*/
}
}
} else {
consolePrintf("WARNING: Save didn't fit in cart RAM and has been lost!! Delete files and save again.");
loadAllFromSRAM();
}
DSSaveFileManager::setExtraData(extraData);
// consolePrintf("SRAM free: %d bytes\n", getBytesFree());
}
void DSSaveFileManager::setExtraData(int data) {
// Offset of extra data is 31. This overlaps the padding and reserved bytes of the first save entry.
// which have not been used up until now. So it should be safe.
vu8* sram = CART_RAM + 31;
*(sram + 0) = 0xF0; // This is an identifier to check
*(sram + 1) = 0x0D; // that extra data is present.
*(sram + 2) = (data & 0xFF000000) >> 24; // Now write the actual data
*(sram + 3) = (data & 0x00FF0000) >> 16; // taking care to use single
*(sram + 4) = (data & 0x0000FF00) >> 8; // byte writes (it's an 8-bit bus)
*(sram + 5) = (data & 0x000000FF);
}
bool DSSaveFileManager::isExtraDataPresent() {
vu8* sram = CART_RAM + 31;
// Check for the identifier
return ((*(sram + 0) == 0xF0) && (*(sram + 1) == 0x0D));
}
int DSSaveFileManager::getExtraData() {
vu8* sram = CART_RAM + 31;
if (isExtraDataPresent()) {
int value = (*(sram + 2) << 24) | (*(sram + 3) << 16) | (*(sram + 4) << 8) | (*(sram + 5));
return value;
} else {
return 0;
}
}
#endif

View file

@ -1,150 +0,0 @@
/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef _RAMSAVE_H_
#define _RAMSAVE_H_
#include "common/system.h"
#include "common/savefile.h"
// SaveFileManager class
#define DS_MAX_SAVE_SIZE 150000
class DSSaveFile : public Common::InSaveFile, public Common::OutSaveFile {
int address;
int ptr;
bool ownsData;
bool saveCompressed;
struct SCUMMSave {
u32 magic; // 4
bool isValid; // 5
bool pad; // 6
char name[16]; // 22
u32 size; // 26
u32 compressedSize; // 30
u16 extraMagic; // 32
u32 reserved; // 36
} __attribute__ ((packed));
SCUMMSave save;
u8* saveData;
SCUMMSave* origHeader;
bool isOpenFlag;
bool isTempFile;
bool eosReached;
public:
DSSaveFile();
DSSaveFile(SCUMMSave* s, bool saveCompressed, u8* data);
~DSSaveFile();
void reset();
bool isOpen() const { return isOpenFlag; }
virtual bool eos() const;
virtual void clearErr();
virtual bool skip(uint32 size);
virtual int32 pos() const;
virtual int32 size() const;
virtual bool seek(int32 pos, int whence);
uint32 read(void *buf, uint32 size);
uint32 write(const void *buf, uint32 size);
void setName(char *name);
char* getName() { return save.name; }
bool isValid() { return save.isValid; }
bool isTemp() { return isTempFile; }
bool matches(const char *prefix, int num);
bool matches(const char *filename);
void clearData();
void compress();
int getRamUsage() { return sizeof(save) + save.compressedSize; }
char* getRamImage() { return (char *) &save; }
int getSize() { return save.size; }
DSSaveFile* clone();
bool loadFromSaveRAM(vu8* address);
int saveToSaveRAM(vu8* address);
void deleteFile();
void operator delete(void *p) {
// consolePrintf("Finished! size=%d\n", ((DSSaveFile *) (p))->save->size);
}
};
class DSSaveFileManager : public Common::SaveFileManager {
DSSaveFile gbaSave[8];
static DSSaveFileManager* instancePtr;
int sramBytesFree;
public:
DSSaveFileManager();
~DSSaveFileManager();
static DSSaveFileManager* instance() { return instancePtr; }
DSSaveFile *openSavefile(const char *filename, bool saveOrLoad);
virtual Common::OutSaveFile* openForSaving(const Common::String &filename) { return openSavefile(filename.c_str(), true); }
virtual Common::InSaveFile* openForLoading(const Common::String &filename) { return openSavefile(filename.c_str(), false); }
virtual bool removeSavefile(const Common::String &filename);
virtual Common::StringArray listSavefiles(const Common::String &pattern);
void flushToSaveRAM();
void addBytesFree(int size) { sramBytesFree += size; }
int getBytesFree() { return sramBytesFree; }
void deleteFile(char* name);
void listFiles();
void formatSram();
void loadAllFromSRAM();
static bool isExtraDataPresent();
static int getExtraData();
static void setExtraData(int data);
protected:
DSSaveFile *makeSaveFile(const Common::String &filename, bool saveOrLoad);
};
#endif

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -91,7 +94,8 @@ void updateStrings(byte gameId, byte version, Common::Platform platform,
}
}
} // End of namespace DS
#undef ADD_BIND

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -31,6 +34,7 @@ namespace DS {
void updateStrings(byte gameId, byte version, Common::Platform platform,
int page, Common::String &title, Common::String *&key, Common::String *&dsc);
}
} // End of namespace DS
#endif

View file

@ -20,6 +20,7 @@
*
*/
#include <nds.h>
#include "NDS/scummvm_ipc.h"
#include "touchkeyboard.h"
#include "keyboard_raw.h"
#include "keyboard_pal_raw.h"
@ -43,124 +44,124 @@ struct key_data {
#define DS_CAPSLOCK 1
key_data keys[DS_NUM_KEYS] = {
static key_data keys[DS_NUM_KEYS] = {
// Key number x y character
// Numbers
{28, 3, 0, '1'},
{29, 5, 0, '2'},
{30, 7, 0, '3'},
{31, 9, 0, '4'},
{32, 11, 0, '5'},
{33, 13, 0, '6'},
{34, 15, 0, '7'},
{35, 17, 0, '8'},
{36, 19, 0, '9'},
{27, 21, 0, '0'},
{45, 23, 0, Common::KEYCODE_MINUS},
{50, 25, 0, Common::KEYCODE_EQUALS},
{52, 27, 0, Common::KEYCODE_BACKSPACE},
{28, 3, 0, '1', false},
{29, 5, 0, '2', false},
{30, 7, 0, '3', false},
{31, 9, 0, '4', false},
{32, 11, 0, '5', false},
{33, 13, 0, '6', false},
{34, 15, 0, '7', false},
{35, 17, 0, '8', false},
{36, 19, 0, '9', false},
{27, 21, 0, '0', false},
{45, 23, 0, Common::KEYCODE_MINUS, false},
{50, 25, 0, Common::KEYCODE_EQUALS, false},
{52, 27, 0, Common::KEYCODE_BACKSPACE, false},
// Top row
{'Q'-'A' + 1, 4, 2, 'Q'},
{'W'-'A' + 1, 6, 2, 'W'},
{'E'-'A' + 1, 8, 2, 'E'},
{'R'-'A' + 1, 10, 2, 'R'},
{'T'-'A' + 1, 12, 2, 'T'},
{'Y'-'A' + 1, 14, 2, 'Y'},
{'U'-'A' + 1, 16, 2, 'U'},
{'I'-'A' + 1, 18, 2, 'I'},
{'O'-'A' + 1, 20, 2, 'O'},
{'P'-'A' + 1, 22, 2, 'P'},
{43, 24, 2, Common::KEYCODE_LEFTBRACKET},
{44, 26, 2, Common::KEYCODE_RIGHTBRACKET},
{'Q'-'A' + 1, 4, 2, 'Q', false},
{'W'-'A' + 1, 6, 2, 'W', false},
{'E'-'A' + 1, 8, 2, 'E', false},
{'R'-'A' + 1, 10, 2, 'R', false},
{'T'-'A' + 1, 12, 2, 'T', false},
{'Y'-'A' + 1, 14, 2, 'Y', false},
{'U'-'A' + 1, 16, 2, 'U', false},
{'I'-'A' + 1, 18, 2, 'I', false},
{'O'-'A' + 1, 20, 2, 'O', false},
{'P'-'A' + 1, 22, 2, 'P', false},
{43, 24, 2, Common::KEYCODE_LEFTBRACKET, false},
{44, 26, 2, Common::KEYCODE_RIGHTBRACKET, false},
// Middle row
{55, 3, 4, DS_CAPSLOCK},
{'A'-'A' + 1, 5, 4, 'A'},
{'S'-'A' + 1, 7, 4, 'S'},
{'D'-'A' + 1, 9, 4, 'D'},
{'F'-'A' + 1, 11, 4, 'F'},
{'G'-'A' + 1, 13, 4, 'G'},
{'H'-'A' + 1, 15, 4, 'H'},
{'J'-'A' + 1, 17, 4, 'J'},
{'K'-'A' + 1, 19, 4, 'K'},
{'L'-'A' + 1, 21, 4, 'L'},
{42, 23, 4, Common::KEYCODE_SEMICOLON},
{41, 25, 4, Common::KEYCODE_QUOTE},
{46, 27, 4, Common::KEYCODE_RETURN},
{55, 3, 4, DS_CAPSLOCK, false},
{'A'-'A' + 1, 5, 4, 'A', false},
{'S'-'A' + 1, 7, 4, 'S', false},
{'D'-'A' + 1, 9, 4, 'D', false},
{'F'-'A' + 1, 11, 4, 'F', false},
{'G'-'A' + 1, 13, 4, 'G', false},
{'H'-'A' + 1, 15, 4, 'H', false},
{'J'-'A' + 1, 17, 4, 'J', false},
{'K'-'A' + 1, 19, 4, 'K', false},
{'L'-'A' + 1, 21, 4, 'L', false},
{42, 23, 4, Common::KEYCODE_SEMICOLON, false},
{41, 25, 4, Common::KEYCODE_QUOTE, false},
{46, 27, 4, Common::KEYCODE_RETURN, false},
// Bottom row
{51, 4, 6, DS_SHIFT},
{'Z'-'A' + 1, 6, 6, 'Z'},
{'X'-'A' + 1, 8, 6, 'X'},
{'C'-'A' + 1, 10, 6, 'C'},
{'V'-'A' + 1, 12, 6, 'V'},
{'B'-'A' + 1, 14, 6, 'B'},
{'N'-'A' + 1, 16, 6, 'N'},
{'M'-'A' + 1, 18, 6, 'M'},
{38, 20, 6, Common::KEYCODE_COMMA},
{39, 22, 6, Common::KEYCODE_PERIOD},
{40, 24, 6, Common::KEYCODE_SLASH},
{51, 4, 6, DS_SHIFT, false},
{'Z'-'A' + 1, 6, 6, 'Z', false},
{'X'-'A' + 1, 8, 6, 'X', false},
{'C'-'A' + 1, 10, 6, 'C', false},
{'V'-'A' + 1, 12, 6, 'V', false},
{'B'-'A' + 1, 14, 6, 'B', false},
{'N'-'A' + 1, 16, 6, 'N', false},
{'M'-'A' + 1, 18, 6, 'M', false},
{38, 20, 6, Common::KEYCODE_COMMA, false},
{39, 22, 6, Common::KEYCODE_PERIOD, false},
{40, 24, 6, Common::KEYCODE_SLASH, false},
// Space bar
{47, 9, 8, Common::KEYCODE_SPACE},
{48, 11, 8, Common::KEYCODE_SPACE},
{48, 13, 8, Common::KEYCODE_SPACE},
{48, 15, 8, Common::KEYCODE_SPACE},
{48, 17, 8, Common::KEYCODE_SPACE},
{49, 19, 8, Common::KEYCODE_SPACE},
{47, 9, 8, Common::KEYCODE_SPACE, false},
{48, 11, 8, Common::KEYCODE_SPACE, false},
{48, 13, 8, Common::KEYCODE_SPACE, false},
{48, 15, 8, Common::KEYCODE_SPACE, false},
{48, 17, 8, Common::KEYCODE_SPACE, false},
{49, 19, 8, Common::KEYCODE_SPACE, false},
// Cursor arrows
{52, 27, 8, Common::KEYCODE_LEFT},
{54, 29, 8, Common::KEYCODE_DOWN},
{53, 31, 8, Common::KEYCODE_RIGHT},
{51, 29, 6, Common::KEYCODE_UP},
{52, 27, 8, Common::KEYCODE_LEFT, false},
{54, 29, 8, Common::KEYCODE_DOWN, false},
{53, 31, 8, Common::KEYCODE_RIGHT, false},
{51, 29, 6, Common::KEYCODE_UP, false},
// Close button
{56, 30, 0, Common::KEYCODE_INVALID},
{56, 30, 0, Common::KEYCODE_INVALID, false},
// Function keys (needed for AGI)
{57, 4, -2, Common::KEYCODE_F1},
{58, 6, -2, Common::KEYCODE_F2},
{59, 8, -2, Common::KEYCODE_F3},
{60, 10, -2, Common::KEYCODE_F4},
{61, 14, -2, Common::KEYCODE_F5},
{62, 16, -2, Common::KEYCODE_F6},
{63, 18, -2, Common::KEYCODE_F7},
{64, 20, -2, Common::KEYCODE_F8},
{65, 24, -2, Common::KEYCODE_F9},
{66, 26, -2, Common::KEYCODE_F10},
{67, 28, -2, Common::KEYCODE_F11},
{68, 30, -2, Common::KEYCODE_F12},
{57, 4, -2, Common::KEYCODE_F1, false},
{58, 6, -2, Common::KEYCODE_F2, false},
{59, 8, -2, Common::KEYCODE_F3, false},
{60, 10, -2, Common::KEYCODE_F4, false},
{61, 14, -2, Common::KEYCODE_F5, false},
{62, 16, -2, Common::KEYCODE_F6, false},
{63, 18, -2, Common::KEYCODE_F7, false},
{64, 20, -2, Common::KEYCODE_F8, false},
{65, 24, -2, Common::KEYCODE_F9, false},
{66, 26, -2, Common::KEYCODE_F10, false},
{67, 28, -2, Common::KEYCODE_F11, false},
{68, 30, -2, Common::KEYCODE_F12, false},
};
int keyboardX;
int keyboardY;
static int keyboardX;
static int keyboardY;
int mapBase;
int tileBase;
static int s_mapBase;
static int s_tileBase;
u16* baseAddress;
static u16 *baseAddress;
bool shiftState;
bool capsLockState;
static bool shiftState;
static bool capsLockState;
bool closed;
static bool closed;
char autoCompleteWord[NUM_WORDS][32];
int autoCompleteCount;
static char autoCompleteWord[NUM_WORDS][32];
static int autoCompleteCount;
char autoCompleteBuffer[128];
static char autoCompleteBuffer[128];
int selectedCompletion = -1;
int charactersEntered = 0;
int typingTimeout = 0;
static int selectedCompletion = -1;
static int charactersEntered = 0;
static int typingTimeout = 0;
// Render text onto the tiled screen
void drawText(int tx, int ty, char* string, bool highlight) {
void drawText(int tx, int ty, const char *string, bool highlight) {
u16 baseValue = 0;
@ -212,7 +213,7 @@ void drawKeyboard(int tileBase, int mapBase, u16* saveSpace) {
for (int tile = 0; tile < 94; tile++) {
u16 *tileAddr = (u16 *) (CHAR_BASE_BLOCK_SUB(tileBase) + ((KEYBOARD_DATA_SIZE) + (tile * 32)));
u8* src = ((u8 *) (::_8x8font_tga_raw)) + 18 + tile * 8;
const u8 *src = ((const u8 *) (::_8x8font_tga_raw)) + 18 + tile * 8;
for (int y = 0 ; y < 8; y++) {
for (int x = 0; x < 2; x++) {
@ -247,8 +248,8 @@ void drawKeyboard(int tileBase, int mapBase, u16* saveSpace) {
keyboardX = -2;
keyboardY = 2;
DS::mapBase = mapBase;
DS::tileBase = tileBase;
DS::s_mapBase = mapBase;
DS::s_tileBase = tileBase;
shiftState = false;
capsLockState = false;
@ -314,7 +315,7 @@ bool getKeyboardClosed() {
}
void setKeyHighlight(int key, bool highlight) {
u16* base = ((u16 *) SCREEN_BASE_BLOCK_SUB(DS::mapBase));
u16 *base = ((u16 *) SCREEN_BASE_BLOCK_SUB(DS::s_mapBase));
if (highlight) {
base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x] |= 0x1000;
@ -395,8 +396,7 @@ void updateTypeEvents() {
event.type = Common::EVENT_KEYUP;
system->addEvent(event);
for (int r = 0; r < (int)strlen(autoCompleteBuffer); r++)
{
for (int r = 0; r < (int)strlen(autoCompleteBuffer); r++) {
autoCompleteBuffer[r] = autoCompleteBuffer[r + 1];
}
@ -404,8 +404,7 @@ void updateTypeEvents() {
}
}
void createKeyEvent(int keyNum, Common::Event& event)
{
void createKeyEvent(int keyNum, Common::Event& event) {
event.kbd.flags = 0;
if ((keys[keyNum].character >= '0') && (keys[keyNum].character <= '9')) {
@ -586,5 +585,4 @@ void addKeyboardEvents() {
}
}
} // End of namespace DS

View file

@ -8,15 +8,18 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
@ -27,9 +30,11 @@
namespace DS {
static const int NUM_WORDS = 12;
static const int KEYBOARD_DATA_SIZE = 4736 * 2;
static const int KEYBOARD_BOTTOM_Y = 105;
enum {
NUM_WORDS = 12,
KEYBOARD_DATA_SIZE = 4736 * 2,
KEYBOARD_BOTTOM_Y = 105
};
void createKeyEvent(int keyNum, Common::Event& event);
@ -44,6 +49,6 @@ void clearAutoComplete();
void setCharactersEntered(int count);
void releaseAllKeys();
}
} // End of namespace DS
#endif

View file

@ -1,3 +1,28 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "wordcompletion.h"
#include "osystem_ds.h"
#include "engines/agi/agi.h" // Caution for #define for NUM_CHANNELS, causes problems in mixer_intern.h
@ -176,5 +201,6 @@ bool findWordCompletions(const char* input) {
}
}
} // End of namespace DS
#endif

View file

@ -1,3 +1,28 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
namespace DS {
extern void clearAutoCompleteWordList();
@ -5,4 +30,4 @@ extern bool findWordCompletions(const char *input);
extern void addAutoCompleteLine(const char *line);
extern void sortAutoCompleteWordList();
}
} // End of namespace DS

View file

@ -8,19 +8,23 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "common/scummsys.h"
#include "zipreader.h"
ZipFile::ZipFile() {
@ -75,7 +79,6 @@ bool ZipFile::restartFile() {
bool more = true;
while (!currentFileInFolder() && more) {
char name[128];
getFileName(name);
more = skipFile();
}

View file

@ -8,21 +8,26 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef _ZIPREADER_H_
#define _ZIPREADER_H_
#include "portdefs.h"
#include <nds/ndstypes.h>
#define ZF_SEARCH_START 0x08000000
#define ZF_SEARCH_END 0x09000000
#define ZF_SEARCH_STRIDE 16

View file

@ -33,8 +33,7 @@
//////////////////////////////////////////////////////////////////////
typedef struct sTransferSoundData {
//---------------------------------------------------------------------------------
typedef struct {
const void *data;
u32 len;
u32 rate;
@ -42,22 +41,21 @@ typedef struct sTransferSoundData {
u8 pan;
u8 format;
u8 PADDING;
} TransferSoundData, * pTransferSoundData;
} TransferSoundData;
//---------------------------------------------------------------------------------
typedef struct sTransferSound {
//---------------------------------------------------------------------------------
typedef struct {
TransferSoundData data[16];
u8 count;
u8 PADDING[3];
} TransferSound, * pTransferSound;
} TransferSound;
typedef struct _adpcmBuffer {
typedef struct {
u8 *buffer[8];
bool filled[8];
u8 *arm7Buffer[8];
@ -82,22 +80,22 @@ typedef struct scummvmTransferRegion {
uint8 curtime[8]; // current time response from RTC
struct {
u8 rtc_command;
u8 rtc_year; //add 2000 to get 4 digit year
u8 rtc_month; //1 to 12
u8 rtc_day; //1 to (days in month)
u8 command;
u8 year; //add 2000 to get 4 digit year
u8 month; //1 to 12
u8 day; //1 to (days in month)
u8 rtc_incr;
u8 rtc_hours; //0 to 11 for AM, 52 to 63 for PM
u8 rtc_minutes; //0 to 59
u8 rtc_seconds; //0 to 59
};
u8 incr;
u8 hours; //0 to 11 for AM, 52 to 63 for PM
u8 minutes; //0 to 59
u8 seconds; //0 to 59
} rtc;
};
uint16 battery; // battery life ?? hopefully. :)
uint16 aux; // i have no idea...
pTransferSound soundData;
TransferSound *soundData;
adpcmBuffer adpcm;
@ -127,7 +125,7 @@ typedef struct scummvmTransferRegion {
// Streaming sound
bool streamFillNeeded[4];
int streamPlayingSection;
} scummTransferRegion, * pscummTransferRegion;
} scummTransferRegion;
//////////////////////////////////////////////////////////////////////

View file

@ -1,12 +1,64 @@
# Repeat "all" target here, to make sure it is the first target
# Currently disabled, so only arm7.bin gets build
#all:
# To approximate the DS builds A, B, C, ... run our configure like this
# configure --host=ds --disable-translation --disable-all-engines OPTIONS
# where OPTIONS is...
# build A: --enable-scumm
# build B: --enable-sky --enable-queen
# build C: --enable-agos
# build D: --enable-gob --enable-cine --enable-agi
# build E: --enable-saga --disable-mad
# build F: --enable-kyra --disable-mad
# build G: --enable-lure
# build H: --enable-parallaction
# build I: --enable-made --disable-mad
# build K: --enable-cruise --disable-mad
#
# This does not currently take care of some things:
# * It does not #define DS_BUILD_A etc. -- most uses of that should be
# eliminated, though. Only usage should be for selecting the default config
# file (and for that we should really rather allow overriding the value of
# DEFAULT_CONFIG_FILE).
# There are a few game specific hacks which are currently controlled by this,
# too; we need to investigate those.
# * It does not currently adjust the logo. Ideally, if we ever get real plugin
# support, that should be necessary anymore anyway.
# * ...
# Set location of ndsdir so that we can easily refer to files in it
ndsdir = backends/platform/ds
# Until we fix logo support, always use the A logo
LOGO = logoa.bmp
# Uncomment the following line to enable support for the
# ace DS Debugger (remembering to make the same change in the arm7 makefile):
#USE_DEBUGGER = 1
# TODO: Need to reimplement this (for arm9 and arm7).
#ifdef USE_DEBUGGER
# DEFINES += -DUSE_DEBUGGER
# CFLAGS += -g
#endif
# Uncomment the following line to enable the profiler
#USE_PROFILER = 1
# TODO: Need to reimplement this; and maybe replace it by the --enable-profiling
# configure directive. Below is USE_PROFILER related code from the old NDS
# build system:
#ifdef USE_PROFILER
# CFLAGS += -mpoke-function-name -finstrument-functions -g
# DEFINES += -DUSE_PROFILER
#endif
# And this for module.mk:
#ifdef USE_PROFILER
# PORT_OBJS += arm9/source/profiler/cyg-profile.o
#endif
# Files in this list will be optimisied for speed, otherwise they will be optimised for space
OPTLIST := actor.cpp ds_main.cpp osystem_ds.cpp blitters.cpp fmopl.cpp rate.cpp isomap.cpp image.cpp gfx.cpp sprite.cpp actor_path.cpp actor_walk.cpp
#OPTLIST :=
# NOTE: The header and libs for the debugger is assumed to be in the libnds
# folder.
# Compiler options for files which should be optimised for speed
OPT_SPEED := -O3
@ -14,31 +66,71 @@ OPT_SPEED := -O3
# Compiler options for files which should be optimised for space
OPT_SIZE := -Os -mthumb
# By default optimize for size
CXXFLAGS += $(OPT_SIZE)
#-mthumb -fno-gcse -fno-schedule-insns2
OBJS := $(DATA_OBJS) $(LIBCARTRESET_OBJS) $(PORT_OBJS) $(COMPRESSOR_OBJS) $(FAT_OBJS)
# TODO: Handle files in OPTLIST.
# For this, the list should be made explicit. So, replace actor.cpp by path/to/actor.cpp --
# in fact, there are several actor.cpp files, and right now all are "optimized", but
# I think Neil only had the SAGA one in mind. Same for gfx.cpp
# Files listed below will be optimisied for speed, otherwise they will be optimised for space
# TODO: speed original list contained three more files that should be optimized
# for speed: actor.cpp gfx.cpp sprite.cpp -- but there are many files with these
# names, which are the "right" ones?
$(ndsdir)/arm9/source/dsmain.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
$(ndsdir)/arm9/source/osystem_ds.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
$(ndsdir)/arm9/source/blitters.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
$(ndsdir)/arm9/source/ds_main.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/saga/isomap.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
sound/rate.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/saga/actor_walk.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/saga/actor_path.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/saga/image.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
sound/fmopl.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/saga/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/scumm/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/m4/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/scumm/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/cine/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/agos/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/saga/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/saga/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/m4/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
engines/agi/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
# TODO: Fingolfin says: optimizing staticres for size would
# save about 30k, so maybe consider that?
#engines/kyra/staticres.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
#############################################################################
#
# ARM9 rules.
#
#############################################################################
all: scummvm.nds scummvm.ds.gba
clean: dsclean
dsclean:
$(RM) $(addprefix $(ndsdir)/, $(ARM7_MODULE_OBJS)) scummvm.nds scummvm.ds.gba
.PHONY: dsclean
# TODO: Add a 'dsdist' target ?
%.bin: %.elf
$(OBJCOPY) -S -O binary $< $@
%.nds: %.bin $(ndsdir)/arm7/arm7.bin
ndstool -c $@ -9 $< -7 $(ndsdir)/arm7/arm7.bin -b $(srcdir)/$(ndsdir)/$(LOGO) "$(@F);ScummVM $(VERSION);DS Port"
%.ds.gba: %.nds
dsbuild $< -o $@ -l $(srcdir)/$(ndsdir)/arm9/ndsloader.bin
padbin 16 $@
#############################################################################
#############################################################################
#############################################################################
#ndsdir = $(srcdir)/backends/platform/ds
ndsdir = backends/platform/ds
#############################################################################
#
# ARM7 rules.
@ -47,12 +139,6 @@ ndsdir = backends/platform/ds
#
#############################################################################
$(ndsdir)/arm7/arm7.bin: $(ndsdir)/arm7/arm7.elf
$(ndsdir)/arm7/arm7.elf: \
$(ndsdir)/arm7/source/libcartreset/cartreset.o \
$(ndsdir)/arm7/source/main.o
# HACK/FIXME: C compiler, for cartreset.c -- we should switch this to use CXX
# as soon as possible.
CC := $(DEVKITARM)/bin/arm-eabi-gcc
@ -65,7 +151,7 @@ OBJCOPY := $(DEVKITARM)/bin/arm-eabi-objcopy
#
ARM7_ARCH := -mthumb-interwork
# note: arm9tdmi isn't the correct CPU arch, but anything newer and LD
# note: arm7tdmi isn't the correct CPU arch, but anything newer and LD
# *insists* it has a FPU or VFP, and it won't take no for an answer!
ARM7_CFLAGS := -g -Wall -O2\
-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
@ -89,7 +175,6 @@ ARM7_LDFLAGS := -g $(ARM7_ARCH) -mno-fpu
$(MKDIR) $(*D)/$(DEPDIR)
$(CC) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
# Set custom build flags for cartreset.o
$(ndsdir)/arm7/source/libcartreset/cartreset.o: CXXFLAGS=$(ARM7_CFLAGS)
$(ndsdir)/arm7/source/libcartreset/cartreset.o: CPPFLAGS=
@ -98,14 +183,28 @@ $(ndsdir)/arm7/source/libcartreset/cartreset.o: CPPFLAGS=
$(ndsdir)/arm7/source/main.o: CXXFLAGS=$(ARM7_CXXFLAGS)
$(ndsdir)/arm7/source/main.o: CPPFLAGS=
# Rule for creating ARM7 .elf files by linking .o files together with a special linker script
$(ndsdir)/arm7/arm7.elf: \
$(ndsdir)/arm7/source/libcartreset/cartreset.o \
$(ndsdir)/arm7/source/main.o
$(CXX) $(ARM7_LDFLAGS) -specs=ds_arm7.specs $+ -L$(DEVKITPRO)/libnds/lib -lnds7 -o $@
# Rule for creating ARM7 .bin files from .elf files
%.bin: %.elf
@echo ------
@echo Building $@...
$(ndsdir)/arm7/arm7.bin: $(ndsdir)/arm7/arm7.elf
$(OBJCOPY) -O binary $< $@
# Rule for creating ARM7 .elf files by linking .o files together with a special linker script
%.elf:
@echo ------
@echo Building $@...
$(CXX) $(ARM7_LDFLAGS) -specs=ds_arm7.specs $+ -L/opt/devkitPro/libnds/lib -lnds7 -o $@
# Command to build libmad is:
# ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork'
#
# I actually had to use
# ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork' LDFLAGS='C:/Progra~1/devkitpro/libnds/lib/libnds9.a' --disable-shared --disable-debugging
#
# Fingolfin used
# CXX=arm-eabi-g++ CC=arm-eabi-gcc ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork' --disable-shared --disable-debugging LDFLAGS=$DEVKITPRO/libnds/lib/libnds9.a

View file

@ -12,8 +12,6 @@ PORT_OBJS := \
arm9/source/gbampsave.o \
arm9/source/scummhelp.o \
arm9/source/osystem_ds.o \
arm9/source/portdefs.o \
arm9/source/ramsave.o \
arm9/source/touchkeyboard.o \
arm9/source/zipreader.o \
arm9/source/dsoptions.o \
@ -21,10 +19,6 @@ PORT_OBJS := \
arm9/source/wordcompletion.o \
arm9/source/interrupt.o
ifdef USE_PROFILER
PORT_OBJS += arm9/source/profiler/cyg-profile.o
endif
DATA_OBJS := \
arm9/data/icons.o \
arm9/data/keyboard.o \
@ -32,9 +26,9 @@ DATA_OBJS := \
arm9/data/default_font.o \
arm9/data/8x8font_tga.o
COMPRESSOR_OBJS := #arm9/source/compressor/lz.o
FAT_OBJS := arm9/source/fat/disc_io.o arm9/source/fat/gba_nds_fat.o\
FAT_OBJS := \
arm9/source/fat/disc_io.o \
arm9/source/fat/gba_nds_fat.o \
arm9/source/fat/io_fcsr.o \
arm9/source/fat/io_m3cf.o \
arm9/source/fat/io_mpcf.o \
@ -51,21 +45,65 @@ FAT_OBJS := arm9/source/fat/disc_io.o arm9/source/fat/gba_nds_fat.o\
arm9/source/fat/m3sd.o
# arm9/source/fat/io_cf_common.o arm9/source/fat/io_m3_common.o\
# arm9/source/fat/io_sd_common.o arm9/source/fat/io_scsd_s.o \
# arm9/source/fat/io_sc_common.o arm9/source/fat/io_sd_common.o
LIBCARTRESET_OBJS :=
#arm9/source/libcartreset/cartreset.o
MODULE_OBJS := $(DATA_OBJS) $(PORT_OBJS) $(FAT_OBJS)
MODULE_OBJS :=
#---------------------------------------------------------------------------------
# canned command sequence for binary data
#---------------------------------------------------------------------------------
define bin2o
$(MKDIR) $(*D)
bin2s $< | $(AS) -mthumb -mthumb-interwork -o $(@)
endef
define bin2h
$(MKDIR) $(*D)
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > $@
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> $@
echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> $@
endef
vpath %.raw $(srcdir)
vpath %.pal $(srcdir)
vpath %.bin $(srcdir)
%.o: %.raw
$(bin2o)
%_raw.h: %.raw
$(bin2h)
%.o: %.pal
$(bin2o)
%_raw.h: %.pal
$(bin2h)
%.o: %.bin
$(bin2o)
%_raw.h: %.bin
$(bin2h)
# Mark files which require the *_raw.h files manually (for now, at least)
$(MODULE)/arm9/source/dsmain.o: \
$(MODULE)/arm9/data/icons_raw.h \
$(MODULE)/arm9/data/keyboard_raw.h \
$(MODULE)/arm9/data/keyboard_pal_raw.h
$(MODULE)/arm9/source/touchkeyboard.o: \
$(MODULE)/arm9/data/keyboard_raw.h \
$(MODULE)/arm9/data/keyboard_pal_raw.h \
$(MODULE)/arm9/data/8x8font_tga_raw.h
# TODO: Should add more dirs to MODULE_DIRS so that "make distclean" can remove .deps dirs.
MODULE_DIRS += \
backends/platform/ds/
backends/platform/ds/ \
backends/platform/ds/arm7/source/ \
backends/platform/ds/arm7/source/libcartreset/ \
backends/platform/ds/arm9/source/ \
backends/platform/ds/arm9/source/fat/
# We don't use the rules.mk here on purpose
OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS)

View file

@ -1,52 +1,10 @@
#!/bin/bash
#!/bin/sh
echo Quick script to make building a distribution of the GP2X port more consistent.
PATH=/opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/bin:$PATH
PATH=/opt/open2x/gcc-4.1.1-glibc-2.3.6/bin:$PATH
export CXX=arm-open2x-linux-g++
export CXXFLAGS=-march=armv4t
export CPPFLAGS=-I/opt/open2x/gcc-4.1.1-glibc-2.3.6/include
export LDFLAGS=-L/opt/open2x/gcc-4.1.1-glibc-2.3.6/lib
cd ../../../..
echo Collecting files.
mkdir "scummvm-gp2x-`date '+%Y-%m-%d'`"
mkdir "scummvm-gp2x-`date '+%Y-%m-%d'`/saves"
mkdir "scummvm-gp2x-`date '+%Y-%m-%d'`/plugins"
mkdir "scummvm-gp2x-`date '+%Y-%m-%d'`/engine-data"
echo Building ScummVM for GP2X Wiz.
echo "Please put your save games in this dir" >> "scummvm-gp2x-`date '+%Y-%m-%d'`/saves/PUT_SAVES_IN_THIS_DIR"
make gp2x-bundle
cp ./scummvm.gpe ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ./scummvm.png ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ./README-GP2X ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ./mmuhack.o ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../scummvm.gp2x ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../AUTHORS ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../README ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../COPYING ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../COPYRIGHT ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../NEWS ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../gui/themes/scummmodern.zip ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../backends/vkeybd/packs/vkeybd_default.zip ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../dists/pred.dic ./scummvm-gp2x-`date '+%Y-%m-%d'`/
cp ../../../../dists/engine-data/* ./scummvm-gp2x-`date '+%Y-%m-%d'`/engine-data
cp ../../../../plugins/* ./scummvm-gp2x-`date '+%Y-%m-%d'`/plugins
echo Making Stripped GPE.
arm-open2x-linux-strip ./scummvm-gp2x-`date '+%Y-%m-%d'`/scummvm.gp2x
echo Building ZIP bundle.
if [ -f /usr/bin/zip ]
then
rm ./"scummvm-gp2x-`date '+%Y-%m-%d'`.zip"
cd "scummvm-gp2x-`date '+%Y-%m-%d'`"
zip -r -9 "../scummvm-gp2x-`date '+%Y-%m-%d'`.zip" *
echo You should have a "scummvm-gp2x-`date '+%Y-%m-%d'`.zip" for the GP2X port ready to go.
cd ..
rm -R ./"scummvm-gp2x-`date '+%Y-%m-%d'`"
else
echo - /usr/bin/zip not found, ZIP bundle not created.
echo All included files can also be found in ./"scummvm-gp2x-`date '+%Y-%m-%d'`"
echo - Please use you preferred archive tool to bundle these files.
fi

View file

@ -0,0 +1,60 @@
# Special target to create bundles for the GP2X.
bundle_name = release/scummvm-gp2x
gp2x-bundle: $(EXECUTABLE)
$(MKDIR) "$(bundle_name)"
$(MKDIR) "$(bundle_name)/saves"
$(MKDIR) "$(bundle_name)/engine-data"
echo "Please put your save games in this dir" >> "$(bundle_name)/saves/PUT_SAVES_IN_THIS_DIR"
$(CP) $(srcdir)/backends/platform/gp2x/build/scummvm.gpe $(bundle_name)/
$(CP) $(srcdir)/backends/platform/gp2x/build/scummvm.png $(bundle_name)/
$(CP) $(srcdir)/backends/platform/gp2x/build/README-GP2X $(bundle_name)/
$(CP) $(srcdir)/backends/platform/gp2x/build/mmuhack.o $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_ENGINEDATA) $(bundle_name)/engine-data
$(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip $(bundle_name)/
$(STRIP) $(EXECUTABLE) -o $(bundle_name)/$(EXECUTABLE)
ifdef DYNAMIC_MODULES
$(INSTALL) -d "$(bundle_name)/plugins"
$(INSTALL) -c -m 644 $(PLUGINS) "$(bundle_name)/plugins"
$(STRIP) $(bundle_name)/plugins/*
endif
tar -C $(bundle_name) -cvjf $(bundle_name).tar.bz2 .
rm -R ./$(bundle_name)
gp2x-bundle-debug: $(EXECUTABLE)
$(MKDIR) "$(bundle_name)"
$(MKDIR) "$(bundle_name)/saves"
$(MKDIR) "$(bundle_name)/engine-data"
echo "Please put your save games in this dir" >> "$(bundle_name)/saves/PUT_SAVES_IN_THIS_DIR"
$(CP) $(srcdir)/backends/platform/gp2x/build/scummvm.gpe $(bundle_name)/
$(CP) $(srcdir)/backends/platform/gp2x/build/scummvm.png $(bundle_name)/
$(CP) $(srcdir)/backends/platform/gp2x/build/README-GP2X $(bundle_name)/
$(CP) $(srcdir)/backends/platform/gp2x/build/mmuhack.o $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_ENGINEDATA) $(bundle_name)/engine-data
$(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip $(bundle_name)/
$(INSTALL) -c -m 777 $(srcdir)/$(EXECUTABLE) $(bundle_name)/$(EXECUTABLE)
ifdef DYNAMIC_MODULES
$(INSTALL) -d "$(bundle_name)/scummvm/plugins"
$(INSTALL) -c -m 644 $(PLUGINS) "$(bundle_name)/scummvm/plugins"
endif
tar -C $(bundle_name) -cvjf $(bundle_name)-debug.tar.bz2 .
rm -R ./$(bundle_name)
.PHONY: gp2x-bundle gp2x-bundle-debug

View file

@ -0,0 +1,9 @@
#!/bin/bash
echo Quick script to make building a distribution of the GP2X Wiz backend more consistent.
cd ../../../..
echo Building ScummVM for GP2X Wiz.
make gp2xwiz-bundle-debug

View file

@ -2,56 +2,8 @@
echo Quick script to make building a distribution of the GP2X Wiz backend more consistent.
echo Collecting files.
mkdir "scummvm-wiz-`date '+%Y-%m-%d'`"
mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm"
mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/saves"
mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/plugins"
mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/engine-data"
mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib"
cd ../../../..
echo Building ScummVM for GP2X Wiz.
echo "Please put your save games in this dir" >> "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/saves/PUT_SAVES_IN_THIS_DIR"
cp ./scummvm.gpe ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ./scummvm.png ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ./README-GP2XWIZ ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ./scummvm.ini ./scummvm-wiz-`date '+%Y-%m-%d'`/
cp ../../../../scummvm.wiz ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ../../../../AUTHORS ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ../../../../README ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ../../../../COPYING ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ../../../../COPYRIGHT ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ../../../../NEWS ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ../../../../gui/themes/scummmodern.zip ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ../../../../backends/vkeybd/packs/vkeybd_default.zip ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ../../../../dists/pred.dic ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/
cp ../../../../dists/engine-data/* ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/engine-data
cp ../../../../plugins/* ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/plugins
# Copy over dynamic libs needed by the app (as the ones in the default filesystem are broken).
f=`which arm-open2x-linux-g++`
loc=`dirname "$f"`
cp $loc/../lib/libz.so.1.2.3 ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib/libz.so.1
cp $loc/../lib/libvorbisidec.so.1.0.2 ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib/libvorbisidec.so.1
echo Making Stripped Binary.
arm-open2x-linux-strip ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/scummvm.wiz
echo Making Stripped Plugins.
arm-open2x-linux-strip ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/plugins/*
echo Building ZIP bundle.
if [ -f /usr/bin/zip ]
then
rm ./"scummvm-wiz-`date '+%Y-%m-%d'`.zip"
cd "scummvm-wiz-`date '+%Y-%m-%d'`"
zip -r -9 "../scummvm-wiz-`date '+%Y-%m-%d'`.zip" *
echo You should have a "scummvm-wiz-`date '+%Y-%m-%d'`.zip" for the GP2X Wiz backend ready to go.
cd ..
rm -R ./"scummvm-wiz-`date '+%Y-%m-%d'`"
else
echo - /usr/bin/zip not found, ZIP bundle not created.
echo All included files can also be found in ./"scummvm-wiz-`date '+%Y-%m-%d'`"
echo - Please use you preferred archive tool to bundle these files.
fi
make gp2xwiz-bundle

View file

@ -0,0 +1,16 @@
#!/bin/sh
# Export the location of any libs ScummVM depends on
# (to avoid installing to the NAND and overwriting the broken ones there).
export LD_LIBRARY_PATH=`pwd`/lib:$LD_LIBRARY_PATH
# Run ScummVM via GDB (so make sure you have a terminal open or serial).
# Oh, and GDB installed of course ;)
gdb --args ./scummvm.wiz --fullscreen --gfx-mode=1x --config=$(pwd)/.scummvmrc
# Sync the SD card to check that everything is written.
sync
# Return to the GPH menu screen
cd /usr/gp2x
exec /usr/gp2x/gp2xmenu

View file

@ -0,0 +1,73 @@
# Special target to create bundles for the GP2X Wiz.
#bundle_name = release/scummvm-wiz-`date '+%Y-%m-%d'`
bundle_name = release/scummvm-gp2xwiz
f=$(shell which $(STRIP))
libloc = $(shell dirname $(f))
gp2xwiz-bundle: $(EXECUTABLE)
$(MKDIR) "$(bundle_name)"
$(MKDIR) "$(bundle_name)/scummvm"
$(MKDIR) "$(bundle_name)/scummvm/saves"
$(MKDIR) "$(bundle_name)/scummvm/engine-data"
$(MKDIR) "$(bundle_name)/scummvm/lib"
echo "Please put your save games in this dir" >> "$(bundle_name)/scummvm/saves/PUT_SAVES_IN_THIS_DIR"
$(CP) $(srcdir)/backends/platform/gp2xwiz/build/scummvm.gpe $(bundle_name)/scummvm/
$(CP) $(srcdir)/backends/platform/gp2xwiz/build/scummvm.png $(bundle_name)/scummvm/
$(CP) $(srcdir)/backends/platform/gp2xwiz/build/README-GP2XWIZ $(bundle_name)/scummvm/
$(CP) $(srcdir)/backends/platform/gp2xwiz/build/scummvm.ini $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/scummvm/
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)/scummvm/
$(INSTALL) -c -m 644 $(DIST_FILES_ENGINEDATA) $(bundle_name)/scummvm/engine-data
$(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip $(bundle_name)/scummvm/
$(STRIP) $(EXECUTABLE) -o $(bundle_name)/scummvm/$(EXECUTABLE)
ifdef DYNAMIC_MODULES
$(INSTALL) -d "$(bundle_name)/scummvm/plugins"
$(INSTALL) -c -m 644 $(PLUGINS) "$(bundle_name)/scummvm/plugins"
$(STRIP) $(bundle_name)/scummvm/plugins/*
endif
$(CP) $(libloc)/../lib/libz.so.1.2.3 $(bundle_name)/scummvm/lib/libz.so.1
$(CP) $(libloc)/../lib/libvorbisidec.so.1.0.2 $(bundle_name)/scummvm/lib/libvorbisidec.so.1
tar -C $(bundle_name) -cvjf $(bundle_name).tar.bz2 .
rm -R ./$(bundle_name)
gp2xwiz-bundle-debug: $(EXECUTABLE)
$(MKDIR) "$(bundle_name)"
$(MKDIR) "$(bundle_name)/scummvm"
$(MKDIR) "$(bundle_name)/scummvm/saves"
$(MKDIR) "$(bundle_name)/scummvm/engine-data"
$(MKDIR) "$(bundle_name)/scummvm/lib"
echo "Please put your save games in this dir" >> "$(bundle_name)/scummvm/saves/PUT_SAVES_IN_THIS_DIR"
$(CP) $(srcdir)/backends/platform/gp2xwiz/build/scummvm-gdb.gpe $(bundle_name)/scummvm/scummvm.gpe
$(CP) $(srcdir)/backends/platform/gp2xwiz/build/scummvm.png $(bundle_name)/scummvm/
$(CP) $(srcdir)/backends/platform/gp2xwiz/build/README-GP2XWIZ $(bundle_name)/scummvm/
$(CP) $(srcdir)/backends/platform/gp2xwiz/build/scummvm.ini $(bundle_name)/
$(INSTALL) -c -m 644 $(DIST_FILES_DOCS) $(bundle_name)/scummvm/
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(bundle_name)/scummvm/
$(INSTALL) -c -m 644 $(DIST_FILES_ENGINEDATA) $(bundle_name)/scummvm/engine-data
$(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip $(bundle_name)/scummvm/
$(INSTALL) -c -m 777 $(srcdir)/$(EXECUTABLE) $(bundle_name)/scummvm/$(EXECUTABLE)
ifdef DYNAMIC_MODULES
$(INSTALL) -d "$(bundle_name)/scummvm/plugins"
$(INSTALL) -c -m 644 $(PLUGINS) "$(bundle_name)/scummvm/plugins"
endif
$(CP) $(libloc)/../lib/libz.so.1.2.3 $(bundle_name)/scummvm/lib/libz.so.1
$(CP) $(libloc)/../lib/libvorbisidec.so.1.0.2 $(bundle_name)/scummvm/lib/libvorbisidec.so.1
tar -C $(bundle_name) -cvjf $(bundle_name)-debug.tar.bz2 .
rm -R ./$(bundle_name)
.PHONY: gp2xwiz-bundle gp2xwiz-bundle-debug

View file

@ -24,6 +24,7 @@
*/
#include "gui/message.h"
#include "common/translation.h"
#include "osys_main.h"
@ -335,9 +336,9 @@ bool OSystem_IPHONE::handleEvent_mouseSecondDragged(Common::Event &event, int x,
_touchpadModeEnabled = !_touchpadModeEnabled;
const char *dialogMsg;
if (_touchpadModeEnabled)
dialogMsg = "Touchpad mode enabled.";
dialogMsg = _("Touchpad mode enabled.");
else
dialogMsg = "Touchpad mode disabled.";
dialogMsg = _("Touchpad mode disabled.");
GUI::TimedMessageDialog dialog(dialogMsg, 1500);
dialog.runModal();
return false;

View file

@ -124,17 +124,13 @@ CXXFLAGS += -pg -g
LDFLAGS += -pg
endif
# SDL Libs and Flags
SDLFLAGS := $(shell $(PSPBIN)/sdl-config --cflags)
SDLLIBS := $(shell $(PSPBIN)/sdl-config --libs)
# PSP LIBS
PSPLIBS = -lpspprof -lpspvfpu -lpspdebug -lpspgu -lpspge -lpspdisplay -lpspctrl -lpspsdk \
-lpsputility -lpspuser -lpsppower -lpsphprm -lpspsdk -lpsprtc -lpspaudio -lpspaudiocodec \
-lpspkernel
# Add in PSPSDK includes and libraries.
CXXFLAGS += $(SDLFLAGS)
LIBS += -lpng -lSDL -lz $(findstring -lGL,$(SDLLIBS)) -lstdc++ -lc -lm $(filter -L%,$(SDLLIBS)) $(PSPLIBS)
LIBS += -lpng -lz -lstdc++ -lc -lm $(PSPLIBS)
OBJS := powerman.o \
psp_main.o \
@ -151,6 +147,7 @@ OBJS := powerman.o \
pspkeyboard.o \
audio.o \
thread.o \
rtc.o \
mp3.o
# Include common Scummvm makefile

View file

@ -99,8 +99,6 @@ To build ScummVM for PSP you need:
Note: This usually gets installed by the PSP toolchain,
so you don't have to do it manually.
- SDL (svn co svn://svn.pspdev.org/psp/trunk/SDL)
- zlib (svn co svn://svn.pspdev.org/psp/trunk/zlib)
- libPNG (svn co svn://svn.pspdev.org/psp/trunk/libpng)

View file

@ -99,8 +99,6 @@ To build ScummVM for PSP you need:
Note: This usually gets installed by the PSP toolchain,
so you don't have to do it manually.
- SDL (svn co svn://svn.pspdev.org/psp/trunk/SDL)
- zlib (svn co svn://svn.pspdev.org/psp/trunk/zlib)
- libPNG (svn co svn://svn.pspdev.org/psp/trunk/libpng)

View file

@ -311,27 +311,29 @@ void DisplayManager::calculateScaleParams() {
}
}
void DisplayManager::renderAll() {
// return true if we really rendered or no dirty. False otherwise
bool DisplayManager::renderAll() {
DEBUG_ENTER_FUNC();
#ifdef USE_DISPLAY_CALLBACK
if (!_masterGuRenderer.isRenderFinished()) {
PSP_DEBUG_PRINT("Callback render not finished.\n");
return;
return false; // didn't render
}
#endif /* USE_DISPLAY_CALLBACK */
if (!isTimeToUpdate())
return;
// This is cheaper than checking time, so we do it first
if (!_screen->isDirty() &&
(!_overlay->isDirty()) &&
(!_cursor->isDirty()) &&
(!_keyboard->isDirty())) {
PSP_DEBUG_PRINT("Nothing dirty\n");
return;
return true; // nothing to render
}
if (!isTimeToUpdate())
return false; // didn't render
PSP_DEBUG_PRINT("screen[%s], overlay[%s], cursor[%s], keyboard[%s]\n",
_screen->isDirty() ? "true" : "false",
_overlay->isDirty() ? "true" : "false",
@ -361,6 +363,8 @@ void DisplayManager::renderAll() {
_keyboard->setClean();
_masterGuRenderer.guPostRender();
return true; // rendered successfully
}
inline bool DisplayManager::isTimeToUpdate() {
@ -375,7 +379,7 @@ inline bool DisplayManager::isTimeToUpdate() {
return true;
}
Common::List<Graphics::PixelFormat> DisplayManager::getSupportedPixelFormats() {
Common::List<Graphics::PixelFormat> DisplayManager::getSupportedPixelFormats() const {
Common::List<Graphics::PixelFormat> list;
// In order of preference

View file

@ -40,12 +40,12 @@ public:
void setupCallbackThread();
private:
static uint32 _displayList[];
uint32 _lastRenderTime; // For measuring rendering
uint32 _lastRenderTime; // For measuring rendering time
void guProgramDisplayBufferSizes();
static int guCallbackThread(SceSize, void *); // for the graphics callbacks
static int guCallback(int, int, void *__this);
bool _renderFinished;
int _callbackId;
bool _renderFinished; // for sync with render callback
int _callbackId; // to keep track of render callback
};
class Screen;
@ -68,7 +68,7 @@ public:
~DisplayManager();
void init();
void renderAll();
bool renderAll(); // return true if rendered or nothing dirty. False otherwise
bool setGraphicsMode(int mode);
bool setGraphicsMode(const char *name);
int getGraphicsMode() const { return _graphicsMode; }
@ -83,12 +83,12 @@ public:
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();
float getScaleX() const { return _displayParams.scaleX; }
float getScaleY() const { return _displayParams.scaleY; }
uint32 getOutputWidth() const { return _displayParams.screenOutput.width; }
uint32 getOutputHeight() const { return _displayParams.screenOutput.height; }
uint32 getOutputBitsPerPixel() const { return _displayParams.outputBitsPerPixel; }
Common::List<Graphics::PixelFormat> getSupportedPixelFormats() const;
private:
struct GlobalDisplayParams {

View file

@ -15,6 +15,7 @@ MODULE_OBJS := powerman.o \
pspkeyboard.o \
audio.o \
thread.o \
rtc.o \
mp3.o
MODULE_DIRS += \

View file

@ -85,13 +85,13 @@ bool Mp3PspStream::initDecoder() {
}
} else {
if (sceUtilityLoadAvModule(PSP_AV_MODULE_AVCODEC) < 0) {
PSP_ERROR("failed to load AVCODEC module.\n");
PSP_ERROR("failed to load AVCODEC module. ME cannot start.\n");
_decoderFail = true;
return false;
}
}
PSP_INFO_PRINT("Using PSP's ME for MP3\n"); // important to know this is happening
PSP_DEBUG_PRINT("Using PSP's ME for MP3\n"); // important to know this is happening
_decoderInit = true;
return true;
@ -319,7 +319,7 @@ void Mp3PspStream::decodeMP3Data() {
// This function blocks. We'll want to put it in a thread
int ret = sceAudiocodecDecode(_codecParams, 0x1002);
if (ret < 0) {
PSP_ERROR("failed to decode MP3 data in ME. sceAudiocodecDecode returned 0x%x\n", ret);
PSP_INFO_PRINT("failed to decode MP3 data in ME. sceAudiocodecDecode returned 0x%x\n", ret);
// handle error here
}

View file

@ -110,7 +110,7 @@ public:
bool endOfData() const { return _state == MP3_STATE_EOS; }
bool isStereo() const { return MAD_NCHANNELS(&_header) == 2; }
int getRate() const { return _header.samplerate; }
int getRate() const { return _sampleRate; }
bool seek(const Timestamp &where);
Timestamp getLength() const { return _length; }

View file

@ -37,6 +37,7 @@
#include "backends/platform/psp/psppixelformat.h"
#include "backends/platform/psp/osys_psp.h"
#include "backends/platform/psp/powerman.h"
#include "backends/platform/psp/rtc.h"
#include "backends/saves/psp/psp-saves.h"
#include "backends/timer/default/default-timer.h"
@ -48,8 +49,6 @@
#include "backends/platform/psp/trace.h"
#define USE_PSP_AUDIO
#define SAMPLES_PER_SEC 44100
static int timer_handler(int t) {
@ -58,14 +57,6 @@ static int timer_handler(int t) {
return t;
}
void OSystem_PSP::initSDL() {
#ifdef USE_PSP_AUDIO
SDL_Init(0);
#else
SDL_Init(SDL_INIT_AUDIO);
#endif
}
OSystem_PSP::~OSystem_PSP() {}
#define PSP_SCREEN_WIDTH 480
@ -74,6 +65,9 @@ OSystem_PSP::~OSystem_PSP() {}
void OSystem_PSP::initBackend() {
DEBUG_ENTER_FUNC();
// Instantiate real time clock
PspRtc::instance();
_cursor.enableCursorPalette(false);
_cursor.setXY(PSP_SCREEN_WIDTH >> 1, PSP_SCREEN_HEIGHT >> 1); // Mouse in the middle of the screen
@ -89,8 +83,6 @@ void OSystem_PSP::initBackend() {
_inputHandler.setKeyboard(&_keyboard);
_inputHandler.init();
initSDL();
_savefile = new PSPSaveFileManager;
_timer = new DefaultTimerManager();
@ -127,11 +119,13 @@ int OSystem_PSP::getDefaultGraphicsMode() const {
bool OSystem_PSP::setGraphicsMode(int mode) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
return _displayManager.setGraphicsMode(mode);
}
bool OSystem_PSP::setGraphicsMode(const char *name) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
return _displayManager.setGraphicsMode(name);
}
@ -146,7 +140,7 @@ Graphics::PixelFormat OSystem_PSP::getScreenFormat() const {
return _screen.getScummvmPixelFormat();
}
Common::List<Graphics::PixelFormat> OSystem_PSP::getSupportedFormats() {
Common::List<Graphics::PixelFormat> OSystem_PSP::getSupportedFormats() const {
return _displayManager.getSupportedPixelFormats();
}
@ -154,6 +148,7 @@ Common::List<Graphics::PixelFormat> OSystem_PSP::getSupportedFormats() {
void OSystem_PSP::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_displayManager.setSizeAndPixelFormat(width, height, format);
_cursor.setVisible(false);
@ -172,6 +167,7 @@ int16 OSystem_PSP::getHeight() {
void OSystem_PSP::setPalette(const byte *colors, uint start, uint num) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_screen.setPartialPalette(colors, start, num);
_cursor.setScreenPalette(colors, start, num);
_cursor.clearKeyColor();
@ -179,6 +175,7 @@ void OSystem_PSP::setPalette(const byte *colors, uint start, uint num) {
void OSystem_PSP::setCursorPalette(const byte *colors, uint start, uint num) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_cursor.setCursorPalette(colors, start, num);
_cursor.enableCursorPalette(true);
_cursor.clearKeyColor(); // Do we need this?
@ -186,37 +183,43 @@ void OSystem_PSP::setCursorPalette(const byte *colors, uint start, uint num) {
void OSystem_PSP::disableCursorPalette(bool disable) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_cursor.enableCursorPalette(!disable);
}
void OSystem_PSP::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_screen.copyFromRect(buf, pitch, x, y, w, h);
}
Graphics::Surface *OSystem_PSP::lockScreen() {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
return _screen.lockAndGetForEditing();
}
void OSystem_PSP::unlockScreen() {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
// The screen is always completely updated anyway, so we don't have to force a full update here.
_screen.unlock();
}
void OSystem_PSP::updateScreen() {
DEBUG_ENTER_FUNC();
_displayManager.renderAll();
_pendingUpdate = !_displayManager.renderAll(); // if we didn't update, we have a pending update
}
void OSystem_PSP::setShakePos(int shakeOffset) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_screen.setShakePos(shakeOffset);
}
void OSystem_PSP::showOverlay() {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_overlay.setVisible(true);
_cursor.setLimits(_overlay.getWidth(), _overlay.getHeight());
_cursor.useGlobalScaler(false); // mouse with overlay is 1:1
@ -224,6 +227,7 @@ void OSystem_PSP::showOverlay() {
void OSystem_PSP::hideOverlay() {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_overlay.setVisible(false);
_cursor.setLimits(_screen.getWidth(), _screen.getHeight());
_cursor.useGlobalScaler(true); // mouse needs to be scaled with screen
@ -231,6 +235,7 @@ void OSystem_PSP::hideOverlay() {
void OSystem_PSP::clearOverlay() {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_overlay.clearBuffer();
}
@ -241,6 +246,7 @@ void OSystem_PSP::grabOverlay(OverlayColor *buf, int pitch) {
void OSystem_PSP::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_overlay.copyFromRect(buf, pitch, x, y, w, h);
}
@ -259,6 +265,8 @@ void OSystem_PSP::grabPalette(byte *colors, uint start, uint num) {
bool OSystem_PSP::showMouse(bool v) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
PSP_DEBUG_PRINT("%s\n", v ? "true" : "false");
bool last = _cursor.isVisible();
_cursor.setVisible(v);
@ -268,11 +276,14 @@ bool OSystem_PSP::showMouse(bool v) {
void OSystem_PSP::warpMouse(int x, int y) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_cursor.setXY(x, y);
}
void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
PSP_DEBUG_PRINT("pbuf[%p], w[%u], h[%u], hotspot:X[%d], Y[%d], keycolor[%d], scale[%d], pformat[%p]\n", buf, w, h, hotspotX, hotspotY, keycolor, cursorTargetScale, format);
if (format) {
PSP_DEBUG_PRINT("format: bpp[%d], rLoss[%d], gLoss[%d], bLoss[%d], aLoss[%d], rShift[%d], gShift[%d], bShift[%d], aShift[%d]\n", format->bytesPerPixel, format->rLoss, format->gLoss, format->bLoss, format->aLoss, format->rShift, format->gShift, format->bShift, format->aShift);
@ -292,14 +303,28 @@ bool OSystem_PSP::pollEvent(Common::Event &event) {
// Pausing the engine is a necessary fix for games that use the timer for music synchronization
// recovering many hours later causes the game to crash. We're polling without mutexes since it's not critical to
// get it right now.
PowerMan.pollPauseEngine();
// A hack:
// Check if we have a pending update that we missed for some reason (FPS throttling for example)
// Time between event polls is usually 5-10ms, so waiting for 4 calls before checking to update the screen should be fine
if (_pendingUpdate) {
_pendingUpdateCounter++;
if (_pendingUpdateCounter >= 4) {
PSP_DEBUG_PRINT("servicing pending update\n");
updateScreen();
if (!_pendingUpdate) // we handled the update
_pendingUpdateCounter = 0;
}
} else
_pendingUpdateCounter = 0; // reset the counter, no pending
return _inputHandler.getAllInputs(event);
}
uint32 OSystem_PSP::getMillis() {
return _pspRtc.getMillis();
return PspRtc::instance().getMillis();
}
void OSystem_PSP::delayMillis(uint msecs) {
@ -313,19 +338,19 @@ void OSystem_PSP::setTimerCallback(TimerProc callback, int interval) {
}
OSystem::MutexRef OSystem_PSP::createMutex(void) {
return (MutexRef)SDL_CreateMutex();
return (MutexRef) new PspMutex(true); // start with a full mutex
}
void OSystem_PSP::lockMutex(MutexRef mutex) {
SDL_mutexP((SDL_mutex *)mutex);
((PspMutex *)mutex)->lock();
}
void OSystem_PSP::unlockMutex(MutexRef mutex) {
SDL_mutexV((SDL_mutex *)mutex);
((PspMutex *)mutex)->unlock();
}
void OSystem_PSP::deleteMutex(MutexRef mutex) {
SDL_DestroyMutex((SDL_mutex *)mutex);
delete (PspMutex *)mutex;
}
void OSystem_PSP::mixCallback(void *sys, byte *samples, int len) {
@ -355,7 +380,6 @@ void OSystem_PSP::setupMixer(void) {
assert(!_mixer);
#ifdef USE_PSP_AUDIO
if (!_audio.open(samplesPerSec, 2, samples, mixCallback, this)) {
PSP_ERROR("failed to open audio\n");
return;
@ -365,46 +389,10 @@ void OSystem_PSP::setupMixer(void) {
assert(_mixer);
_mixer->setReady(true);
_audio.unpause();
#else
SDL_AudioSpec obtained;
SDL_AudioSpec desired;
memset(&desired, 0, sizeof(desired));
desired.freq = samplesPerSec;
desired.format = AUDIO_S16SYS;
desired.channels = 2;
desired.samples = samples;
desired.callback = mixCallback;
desired.userdata = this;
if (SDL_OpenAudio(&desired, &obtained) != 0) {
warning("Could not open audio: %s", SDL_GetError());
_mixer = new Audio::MixerImpl(this, samplesPerSec);
assert(_mixer);
_mixer->setReady(false);
} else {
// Note: This should be the obtained output rate, but it seems that at
// least on some platforms SDL will lie and claim it did get the rate
// even if it didn't. Probably only happens for "weird" rates, though.
samplesPerSec = obtained.freq;
// Create the mixer instance and start the sound processing
_mixer = new Audio::MixerImpl(this, samplesPerSec);
assert(_mixer);
_mixer->setReady(true);
SDL_PauseAudio(0);
}
#endif /* USE_PSP_AUDIO */
}
void OSystem_PSP::quit() {
#ifdef USE_PSP_AUDIO
_audio.close();
#else
SDL_CloseAudio();
#endif
SDL_Quit();
sceKernelExitGame();
}

View file

@ -42,14 +42,14 @@
#include "backends/timer/psp/timer.h"
#include "backends/platform/psp/thread.h"
#include <SDL.h>
class OSystem_PSP : public BaseBackend {
private:
Common::SaveFileManager *_savefile;
Audio::MixerImpl *_mixer;
Common::TimerManager *_timer;
bool _pendingUpdate; // save an update we couldn't perform
uint32 _pendingUpdateCounter; // prevent checking for pending update too often, in a cheap way
// All needed sub-members
Screen _screen;
@ -60,12 +60,9 @@ private:
InputHandler _inputHandler;
PspAudio _audio;
PspTimer _pspTimer;
PspRtc _pspRtc;
void initSDL();
public:
OSystem_PSP() : _savefile(0), _mixer(0), _timer(0) {}
OSystem_PSP() : _savefile(0), _mixer(0), _timer(0), _pendingUpdate(false), _pendingUpdateCounter(0) {}
~OSystem_PSP();
static OSystem *instance();
@ -85,7 +82,7 @@ public:
int getGraphicsMode() const;
#ifdef USE_RGB_COLOR
virtual Graphics::PixelFormat getScreenFormat() const;
virtual Common::List<Graphics::PixelFormat> getSupportedFormats();
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
#endif
// Screen size

View file

@ -23,16 +23,16 @@
*
*/
//#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 "backends/platform/psp/powerman.h"
#include "engine.h"
//#define __PSP_DEBUG_FUNCS__ /* can put this locally too */
//#define __PSP_DEBUG_PRINT__
#include "backends/platform/psp/trace.h"
DECLARE_SINGLETON(PowerManager)
// Function to debug the Power Manager (we have no output to screen)
@ -47,68 +47,30 @@ inline void PowerManager::debugPM() {
* Constructor
*
********************************************/
PowerManager::PowerManager() {
DEBUG_ENTER_FUNC();
_flagMutex = NULL; /* Init mutex handle */
_listMutex = NULL; /* Init mutex handle */
_condSuspendable = NULL; /* Init condition variable */
_condPM = NULL;
_condSuspendable = SDL_CreateCond();
if (_condSuspendable <= 0) {
PSP_ERROR("Couldn't create Suspendable condition variable\n");
}
_condPM = SDL_CreateCond();
if (_condPM <= 0) {
PSP_ERROR("Couldn't create PM condition variable\n");
}
_flagMutex = SDL_CreateMutex();
if (_flagMutex <= 0) {
PSP_ERROR("Couldn't create flag Mutex\n");
}
_listMutex = SDL_CreateMutex();
if (_listMutex <= 0) {
PSP_ERROR("Couldn't create list Mutex\n");
}
_suspendFlag = false;
_criticalCounter = 0; // How many are in the critical section
_pauseFlag = 0;
_pauseFlagOld = 0;
_pauseClientState = 0;
_listCounter = 0;
PMStatusSet(kInitDone);
_error = 0;
}
PowerManager::PowerManager() : _pauseFlag(false), _pauseFlagOld(false), _pauseClientState(UNPAUSED),
_suspendFlag(false), _flagMutex(true), _listMutex(true),
_criticalCounter(0), _listCounter(0), _error(0), _PMStatus(kInitDone) {}
/*******************************************
*
* Function to register to be notified when suspend/resume time comes
*
********************************************/
int PowerManager::registerSuspend(Suspendable *item) {
bool PowerManager::registerForSuspend(Suspendable *item) {
DEBUG_ENTER_FUNC();
// Register in list
debugPM();
if (SDL_mutexP(_listMutex) != 0) {
PSP_ERROR("Couldn't lock _listMutex[%p]\n", _listMutex);
}
_listMutex.lock();
_suspendList.push_front(item);
_listCounter++;
if (SDL_mutexV(_listMutex) != 0) {
PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
}
_listMutex.unlock();
debugPM();
return 0;
return true;
}
/*******************************************
@ -116,26 +78,20 @@ int PowerManager::registerSuspend(Suspendable *item) {
* Function to unregister to be notified when suspend/resume time comes
*
********************************************/
int PowerManager::unregisterSuspend(Suspendable *item) {
bool PowerManager::unregisterForSuspend(Suspendable *item) {
DEBUG_ENTER_FUNC();
debugPM();
// Unregister from stream list
if (SDL_mutexP(_listMutex) != 0) {
PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
}
_listMutex.lock();
_suspendList.remove(item);
_listCounter--;
if (SDL_mutexV(_listMutex) != 0) {
PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
}
_listMutex.unlock();
PSP_DEBUG_PRINT("Out of unregisterSuspend\n");
debugPM();
return 0;
return true;
}
/*******************************************
@ -144,21 +100,7 @@ int PowerManager::unregisterSuspend(Suspendable *item) {
*
********************************************/
PowerManager::~PowerManager() {
DEBUG_ENTER_FUNC();
PMStatusSet(kDestroyPM);
SDL_DestroyCond(_condSuspendable);
_condSuspendable = 0;
SDL_DestroyCond(_condPM);
_condPM = 0;
SDL_DestroyMutex(_flagMutex);
_flagMutex = 0;
SDL_DestroyMutex(_listMutex);
_listMutex = 0;
_PMStatus = kDestroyPM;
}
/*******************************************
@ -171,114 +113,92 @@ PowerManager::~PowerManager() {
*
********************************************/
void PowerManager::pollPauseEngine() {
DEBUG_ENTER_FUNC();
bool pause = _pauseFlag; // We copy so as not to have multiple values
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
if (pause != _pauseFlagOld) {
if (g_engine) { // Check to see if we have an engine
if (pause && _pauseClientState == UNPAUSED) {
_pauseClientState = PAUSING; // Tell PM we're in the middle of pausing
g_engine->pauseEngine(true);
PSP_DEBUG_PRINT_FUNC("Pausing engine\n");
_pauseClientState = PowerManager::Paused; // Tell PM we're done pausing
} else if (!pause && _pauseClientState == PowerManager::Paused) {
_pauseClientState = PAUSED; // Tell PM we're done pausing
} else if (!pause && _pauseClientState == PAUSED) {
g_engine->pauseEngine(false);
PSP_DEBUG_PRINT_FUNC("Unpausing for resume\n");
_pauseClientState = PowerManager::Unpaused; // Tell PM we're in the middle of pausing
_pauseClientState = UNPAUSED; // Tell PM we're unpaused
}
}
_pauseFlagOld = pause;
}
}
/*******************************************
*
* Function to be called by threads wanting to block on the PSP entering suspend
* Use this for small critical sections where you can easily restore the previous state.
*
********************************************/
int PowerManager::blockOnSuspend() {
return beginCriticalSection(true);
}
/*******************************************
*
* Function to block on a suspend, then start a non-suspendable critical section
* Use this for large or REALLY critical critical-sections.
* Make sure to call endCriticalSection or the PSP won't suspend.
* returns true if blocked, false if not blocked
********************************************/
int PowerManager::beginCriticalSection(bool justBlock) {
bool PowerManager::beginCriticalSection() {
DEBUG_ENTER_FUNC();
int ret = NotBlocked;
bool ret = false;
if (SDL_mutexP(_flagMutex) != 0) {
PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't lock flagMutex[%p]\n", _flagMutex);
ret = Error;
}
_flagMutex.lock();
// Check the access flag
if (_suspendFlag == true) {
PSP_DEBUG_PRINT("We're being blocked!\n");
if (_suspendFlag) {
ret = true;
PSP_DEBUG_PRINT("I got blocked. ThreadId[%x]\n", sceKernelGetThreadId());
debugPM();
ret = Blocked;
// If it's true, we wait for a signal to continue
if (SDL_CondWait(_condSuspendable, _flagMutex) != 0) {
PSP_DEBUG_PRINT("PowerManager::blockOnSuspend(): Couldn't wait on cond[%p]\n", _condSuspendable);
}
_threadSleep.wait(_flagMutex);
PSP_DEBUG_PRINT("We got blocked!!\n");
PSP_DEBUG_PRINT_FUNC("I got released. ThreadId[%x]\n", sceKernelGetThreadId());
debugPM();
}
// Now prevent the PM from suspending until we're done
if (justBlock == false)
_criticalCounter++;
if (SDL_mutexV(_flagMutex) != 0) {
PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex[%p]\n", _flagMutex);
ret = Error;
}
_flagMutex.unlock();
return ret;
}
int PowerManager::endCriticalSection() {
// returns success = true
void PowerManager::endCriticalSection() {
DEBUG_ENTER_FUNC();
int ret = 0;
if (SDL_mutexP(_flagMutex) != 0) {
PSP_ERROR("PowerManager::endCriticalSection(): Couldn't lock flagMutex[%p]\n", _flagMutex);
ret = Error;
}
_flagMutex.lock();
// We're done with our critical section
_criticalCounter--;
if (_criticalCounter <= 0) {
if (_suspendFlag == true) { // If the PM is sleeping, this flag must be set
PSP_DEBUG_PRINT("Unblocked thread waking up the PM.\n");
if (_suspendFlag) { // If the PM is sleeping, this flag must be set
PSP_DEBUG_PRINT_FUNC("PM is asleep. Waking it up.\n");
debugPM();
SDL_CondBroadcast(_condPM);
_pmSleep.releaseAll();
PSP_DEBUG_PRINT_FUNC("Woke up the PM\n");
PSP_DEBUG_PRINT("Woke up the PM\n");
debugPM();
}
if (_criticalCounter < 0) { // Check for bad usage of critical sections
PSP_ERROR("Critical counter[%d]\n", _criticalCounter);
PSP_ERROR("Critical counter[%d]!!!\n", _criticalCounter);
debugPM();
}
}
if (SDL_mutexV(_flagMutex) != 0) {
PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
ret = Error;
}
return ret;
_flagMutex.unlock();
}
/*******************************************
@ -286,90 +206,77 @@ int PowerManager::endCriticalSection() {
* Callback function to be called to put every Suspendable to suspend
*
********************************************/
int PowerManager::suspend() {
void PowerManager::suspend() {
DEBUG_ENTER_FUNC();
int ret = 0;
if (_pauseFlag) return ret; // Very important - make sure we only suspend once
if (_pauseFlag)
return; // Very important - make sure we only suspend once
scePowerLock(0); // Critical to make sure PSP doesn't suspend before we're done
scePowerLock(0); // Also critical to make sure PSP doesn't suspend before we're done
// The first stage of suspend is pausing the engine if possible. We don't want to cause files
// to block, or we might not get the engine to pause. On the other hand, we might wait for polling
// and it'll never happen. We also want to do this w/o mutexes (for speed) which is ok in this case.
_pauseFlag = true;
PMStatusSet(kWaitForClientPause);
_PMStatus = kWaitForClientPause;
// Now we wait, giving the engine thread some time to find our flag.
for (int i = 0; i < 10 && _pauseClientState == Unpaused; i++)
sceKernelDelayThread(50000); // We wait 50 msec x 10 times = 0.5 seconds
for (int i = 0; i < 10 && _pauseClientState == UNPAUSED; i++)
PspThread::delayMicros(50000); // We wait 50 msec x 10 times = 0.5 seconds
if (_pauseClientState == Pausing) { // Our event has been acknowledged. Let's wait until the client is done.
PMStatusSet(kWaitForClientToFinishPausing);
if (_pauseClientState == PAUSING) { // Our event has been acknowledged. Let's wait until the client is done.
_PMStatus = kWaitForClientToFinishPausing;
while (_pauseClientState != Paused)
sceKernelDelayThread(50000); // We wait 50 msec at a time
while (_pauseClientState != PAUSED)
PspThread::delayMicros(50000); // We wait 50 msec at a time
}
// It's possible that the polling thread missed our pause event, but there's nothing we can do about that.
// We can't know if there's polling going on or not. It's usually not a critical thing anyway.
// It's possible that the polling thread missed our pause event, but there's
// nothing we can do about that.
// We can't know if there's polling going on or not.
// It's usually not a critical thing anyway.
PMStatusSet(kGettingFlagMutexSuspend);
_PMStatus = kGettingFlagMutexSuspend;
// Now we set the suspend flag to true to cause reading threads to block
_flagMutex.lock();
if (SDL_mutexP(_flagMutex) != 0) {
PSP_ERROR("Couldn't lock flagMutex[%p]\n", _flagMutex);
_error = Error;
ret = Error;
}
PMStatusSet(kGotFlagMutexSuspend);
_PMStatus = kGotFlagMutexSuspend;
_suspendFlag = true;
// Check if anyone is in a critical section. If so, we'll wait for them
if (_criticalCounter > 0) {
PMStatusSet(kWaitCritSectionSuspend);
SDL_CondWait(_condPM, _flagMutex);
PMStatusSet(kDoneWaitingCritSectionSuspend);
_PMStatus = kWaitCritSectionSuspend;
_pmSleep.wait(_flagMutex);
_PMStatus = kDoneWaitingCritSectionSuspend;
}
if (SDL_mutexV(_flagMutex) != 0) {
PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
_error = Error;
ret = Error;
}
_flagMutex.unlock();
PMStatusSet(kGettingListMutexSuspend);
_PMStatus = kGettingListMutexSuspend;
// Loop over list, calling suspend()
if (SDL_mutexP(_listMutex) != 0) {
PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex);
_error = Error;
ret = Error;
}
PMStatusSet(kIteratingListSuspend);
_listMutex.lock();
_PMStatus = kIteratingListSuspend;
// Iterate
Common::List<Suspendable *>::iterator i;
for (i = _suspendList.begin(); i != _suspendList.end(); ++i) {
(*i)->suspend();
}
_PMStatus = kDoneIteratingListSuspend;
PMStatusSet(kDoneIteratingListSuspend);
if (SDL_mutexV(_listMutex) != 0) {
PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
_error = Error;
ret = Error;
}
PMStatusSet(kDoneSuspend);
_listMutex.unlock();
_PMStatus = kDoneSuspend;
scePowerUnlock(0); // Allow the PSP to go to sleep now
return ret;
_PMStatus = kDonePowerUnlock;
}
/*******************************************
@ -377,24 +284,26 @@ int PowerManager::suspend() {
* Callback function to resume every Suspendable
*
********************************************/
int PowerManager::resume() {
void PowerManager::resume() {
DEBUG_ENTER_FUNC();
int ret = 0;
_PMStatus = kBeginResume;
// Make sure we can't get another suspend
scePowerLock(0);
if (!_pauseFlag) return ret; // Make sure we can only resume once
_PMStatus = kCheckingPauseFlag;
PMStatusSet(kGettingListMutexResume);
if (!_pauseFlag)
return; // Make sure we can only resume once
_PMStatus = kGettingListMutexResume;
// First we notify our Suspendables. Loop over list, calling resume()
if (SDL_mutexP(_listMutex) != 0) {
PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex);
_error = Error;
ret = Error;
}
PMStatusSet(kIteratingListResume);
_listMutex.lock();
_PMStatus = kIteratingListResume;
// Iterate
Common::List<Suspendable *>::iterator i = _suspendList.begin();
@ -402,46 +311,31 @@ int PowerManager::resume() {
(*i)->resume();
}
PMStatusSet(kDoneIteratingListResume);
_PMStatus = kDoneIteratingListResume;
if (SDL_mutexV(_listMutex) != 0) {
PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
_error = Error;
ret = Error;
}
_listMutex.unlock();
PMStatusSet(kGettingFlagMutexResume);
_PMStatus = kGettingFlagMutexResume;
// Now we set the suspend flag to false
if (SDL_mutexP(_flagMutex) != 0) {
PSP_ERROR("Couldn't lock flagMutex %p\n", _flagMutex);
_error = Error;
ret = Error;
}
PMStatusSet(kGotFlagMutexResume);
_flagMutex.lock();
_PMStatus = kGotFlagMutexResume;
_suspendFlag = false;
PMStatusSet(kSignalSuspendedThreadsResume);
_PMStatus = kSignalSuspendedThreadsResume;
// Signal the other threads to wake up
if (SDL_CondBroadcast(_condSuspendable) != 0) {
PSP_ERROR("Couldn't broadcast condition[%p]\n", _condSuspendable);
_error = Error;
ret = Error;
}
PMStatusSet(kDoneSignallingSuspendedThreadsResume);
// Signal the threads to wake up
_threadSleep.releaseAll();
if (SDL_mutexV(_flagMutex) != 0) {
PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
_error = Error;
ret = Error;
}
PMStatusSet(kDoneResume);
_PMStatus = kDoneSignallingSuspendedThreadsResume;
_pauseFlag = false; // Signal engine to unpause
_flagMutex.unlock();
_PMStatus = kDoneResume;
_pauseFlag = false; // Signal engine to unpause -- no mutex needed
scePowerUnlock(0); // Allow new suspends
return ret;
}

Some files were not shown because too many files have changed in this diff Show more