aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorAlejandro Marzini2010-08-06 03:21:21 +0000
committerAlejandro Marzini2010-08-06 03:21:21 +0000
commit33e40e1a20c4cc60031854c87d6da5e461f9eb73 (patch)
treef76425d516e75d147ffbbacbec3fad49297da1b1 /backends
parentf97809a9a62a2d8840229facb2c2b6f75e37bad3 (diff)
parent6c8bcd2ba1cad1312f0a588ca284110bbbb81ccc (diff)
downloadscummvm-rg350-33e40e1a20c4cc60031854c87d6da5e461f9eb73.tar.gz
scummvm-rg350-33e40e1a20c4cc60031854c87d6da5e461f9eb73.tar.bz2
scummvm-rg350-33e40e1a20c4cc60031854c87d6da5e461f9eb73.zip
Merged from trunk, from r51495 to r51775
svn-id: r51776
Diffstat (limited to 'backends')
-rw-r--r--backends/audiocd/audiocd.h13
-rw-r--r--backends/audiocd/default/default-audiocd.cpp36
-rw-r--r--backends/audiocd/default/default-audiocd.h2
-rw-r--r--backends/platform/ds/arm9/makefile6
-rw-r--r--backends/platform/ds/arm9/source/portdefs.h20
-rw-r--r--backends/platform/ds/ds.mk53
-rwxr-xr-xbackends/platform/ds/setup-builddirs.sh57
-rw-r--r--backends/platform/iphone/iphone_video.m2
-rw-r--r--backends/platform/n64/README.N642
-rw-r--r--backends/platform/n64/module.mk7
-rw-r--r--backends/platform/psp/audio.cpp45
-rw-r--r--backends/platform/psp/audio.h10
-rw-r--r--backends/platform/psp/display_manager.cpp30
-rw-r--r--backends/platform/psp/display_manager.h12
-rw-r--r--backends/platform/psp/memory.cpp71
-rw-r--r--backends/platform/psp/memory.h1
-rw-r--r--backends/platform/psp/thread.cpp45
-rw-r--r--backends/platform/psp/thread.h20
18 files changed, 293 insertions, 139 deletions
diff --git a/backends/audiocd/audiocd.h b/backends/audiocd/audiocd.h
index 70eabf650b..5ea5bfcfd4 100644
--- a/backends/audiocd/audiocd.h
+++ b/backends/audiocd/audiocd.h
@@ -27,6 +27,7 @@
#define BACKENDS_AUDIOCD_ABSTRACT_H
#include "common/noncopyable.h"
+#include "common/scummsys.h"
/**
* Abstract Audio CD manager class. Subclasses implement the actual
@@ -45,6 +46,8 @@ public:
int start;
int duration;
int numLoops;
+ int volume;
+ int balance;
};
/**
@@ -72,6 +75,16 @@ public:
virtual bool isPlaying() const = 0;
/**
+ * Set the audio volume
+ */
+ virtual void setVolume(byte volume) = 0;
+
+ /**
+ * Set the speakers balance
+ */
+ virtual void setBalance(int8 balance) = 0;
+
+ /**
* Stop CD or emulated audio playback.
*/
virtual void stop() = 0;
diff --git a/backends/audiocd/default/default-audiocd.cpp b/backends/audiocd/default/default-audiocd.cpp
index 0e7dc66ba1..56e737d359 100644
--- a/backends/audiocd/default/default-audiocd.cpp
+++ b/backends/audiocd/default/default-audiocd.cpp
@@ -33,6 +33,8 @@ DefaultAudioCDManager::DefaultAudioCDManager() {
_cd.start = 0;
_cd.duration = 0;
_cd.numLoops = 0;
+ _cd.volume = Audio::Mixer::kMaxChannelVolume;
+ _cd.balance = 0;
_mixer = g_system->getMixer();
_emulating = false;
assert(_mixer);
@@ -70,7 +72,7 @@ void DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int du
*/
_emulating = true;
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle,
- Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops));
+ Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance);
} else {
_emulating = false;
if (!only_emulate)
@@ -100,6 +102,38 @@ bool DefaultAudioCDManager::isPlaying() const {
}
}
+void DefaultAudioCDManager::setVolume(byte volume) {
+ _cd.volume = volume;
+ if (_emulating) {
+ // Audio CD emulation
+ if (_mixer->isSoundHandleActive(_handle))
+ _mixer->setChannelVolume(_handle, _cd.volume);
+ } else {
+ // Real Audio CD
+
+ // Unfortunately I can't implement this atm
+ // since SDL doesn't seem to offer an interface method for this.
+
+ // g_system->setVolumeCD(_cd.volume);
+ }
+}
+
+void DefaultAudioCDManager::setBalance(int8 balance) {
+ _cd.balance = balance;
+ if (_emulating) {
+ // Audio CD emulation
+ if (isPlaying())
+ _mixer->setChannelBalance(_handle, _cd.balance);
+ } else {
+ // Real Audio CD
+
+ // Unfortunately I can't implement this atm
+ // since SDL doesn't seem to offer an interface method for this.
+
+ // g_system->setBalanceCD(_cd.balance);
+ }
+}
+
void DefaultAudioCDManager::update() {
if (_emulating) {
// Check whether the audio track stopped playback
diff --git a/backends/audiocd/default/default-audiocd.h b/backends/audiocd/default/default-audiocd.h
index ec209d9eb5..3f9df0bbbb 100644
--- a/backends/audiocd/default/default-audiocd.h
+++ b/backends/audiocd/default/default-audiocd.h
@@ -40,6 +40,8 @@ public:
void play(int track, int numLoops, int startFrame, int duration, bool only_emulate = false);
void stop();
bool isPlaying() const;
+ void setVolume(byte volume);
+ void setBalance(int8 balance);
void update();
virtual Status getStatus() const; // Subclasses should override for better status results
diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile
index fac50178b4..eedf75c256 100644
--- a/backends/platform/ds/arm9/makefile
+++ b/backends/platform/ds/arm9/makefile
@@ -205,7 +205,6 @@ CXX = arm-eabi-g++
LD = arm-eabi-g++
CFLAGS = -Wno-multichar -Wall\
- -Wno-multichar -mcpu=arm9tdmi -mtune=arm9tdmi \
-mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer\
-mthumb-interwork -DUSE_ARM_COSTUME_ASM=1 -DDISABLE_SID
@@ -281,7 +280,6 @@ 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 \
@@ -297,14 +295,14 @@ ifdef USE_PROFILER
endif
-DATA_OBJS :=
+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
-FAT_OBJS :=
+FAT_OBJS := \
$(portdir)/source/fat/disc_io.o \
$(portdir)/source/fat/gba_nds_fat.o \
$(portdir)/source/fat/io_fcsr.o \
diff --git a/backends/platform/ds/arm9/source/portdefs.h b/backends/platform/ds/arm9/source/portdefs.h
index bdb42993d1..cc38d66a73 100644
--- a/backends/platform/ds/arm9/source/portdefs.h
+++ b/backends/platform/ds/arm9/source/portdefs.h
@@ -26,6 +26,9 @@
#ifndef _PORTDEFS_H_
#define _PORTDEFS_H_
+// Include ndstypes.h for uint16 etc. typedefs
+#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.
#include <stdio.h>
@@ -49,6 +52,7 @@
#define STREAM_AUDIO_FROM_DISK
#endif
+// FIXME: What is "NO_DEBUG_MSGS" good for?
#define NO_DEBUG_MSGS
// This is defined in dsmain.cpp
@@ -65,16 +69,22 @@ void consolePrintf(const char *format, ...);
#undef assert
#endif
+#ifdef NDEBUG
+
+#define assert(e) ((void)0)
+
+#else
+
+// FIXME: Shouldn't assert() also bail out / exit / halt the program? Right now we just
+// print an error message...
#define assert(s) \
do { \
- if (!(s)) \
+ 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__)
+#endif
// 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
diff --git a/backends/platform/ds/ds.mk b/backends/platform/ds/ds.mk
index 97f104c391..a9ed3e0096 100644
--- a/backends/platform/ds/ds.mk
+++ b/backends/platform/ds/ds.mk
@@ -75,7 +75,7 @@ endif
# Compiler options for files which should be optimised for speed
-OPT_SPEED := -O3
+OPT_SPEED := -O3 -mno-thumb
# Compiler options for files which should be optimised for space
OPT_SIZE := -Os -mthumb
@@ -83,31 +83,46 @@ OPT_SIZE := -Os -mthumb
# By default optimize for size
CXXFLAGS += $(OPT_SIZE)
-# 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?
+# Files listed below will be optimisied for speed, otherwise they will be optimised for space.
+# TODO: Several of these files probably should not be optimized for speed, but for now
+# we replicate the *precise* list from the old DS makefile, to ensure full compatibility.
+# Eventually, we should tune this list.
+$(ndsdir)/arm9/source/blitters.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
$(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)
+base/main.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
sound/rate.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
-engines/saga/actor_walk.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+sound/softsynth/opl/mame.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/agi/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/agos/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/agos/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/cine/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/cruise/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/cruise/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/draci/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/draci/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/gob/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/groovie/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/kyra/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/m4/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/m4/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/m4/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/made/script.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_walk.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/image.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/saga/isomap.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/saga/script.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
+engines/sci/engine/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/scumm/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/scumm/gfx.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/scumm/script.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/sword2/sprite.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+engines/teenagent/actor.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
+# TODO: Fingolfin says: optimizing kyra/staticres.o for size would
# save about 30k, so maybe consider that?
#engines/kyra/staticres.o: CXXFLAGS:=$(CXXFLAGS) $(OPT_SPEED)
diff --git a/backends/platform/ds/setup-builddirs.sh b/backends/platform/ds/setup-builddirs.sh
new file mode 100755
index 0000000000..11aacc1233
--- /dev/null
+++ b/backends/platform/ds/setup-builddirs.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# TODO: Allow specifying (a list of) build ids (a, b, ...) on the command line.
+# TODO: Allow overriding the LOGO variable
+
+# TODO: Computer srcdir in a better way
+srcdir=../../../`dirname $0`/..
+
+BASE_PARAM="--host=ds --disable-translation --disable-debug --disable-all-engines"
+
+for build in a b c d e f g h i k; do
+ echo "--- Setting up build $build ---"
+ mkdir -p build-$build && cd build-$build
+ case $build in
+ a)
+ EXTRA_PARAM="--enable-scumm"
+ ;;
+ b)
+ EXTRA_PARAM="--enable-sky --enable-queen"
+ ;;
+ c)
+ EXTRA_PARAM="--enable-agos"
+ ;;
+ d)
+ EXTRA_PARAM="--enable-gob --enable-cine --enable-agi"
+ ;;
+ e)
+ EXTRA_PARAM="--enable-saga --disable-mad"
+ ;;
+ f)
+ EXTRA_PARAM="--enable-kyra --disable-mad"
+ ;;
+ g)
+ EXTRA_PARAM="--enable-lure"
+ ;;
+ h)
+ EXTRA_PARAM="--enable-parallaction"
+ ;;
+ i)
+ EXTRA_PARAM="--enable-made --disable-mad"
+ ;;
+ k)
+ EXTRA_PARAM="--enable-cruise --disable-mad"
+ ;;
+ *)
+ echo "Invalid build $build selected"
+ exit 1
+ ;;
+ esac
+
+ defname="DS_BUILD_`echo $build | tr '[a-z]' '[A-Z]'`"
+ CPPFLAGS="$CPPFLAGS -D$defname"
+ $srcdir/configure $BASE_PARAM $EXTRA_PARAM
+ cd ..
+ echo DONE
+ echo
+done
diff --git a/backends/platform/iphone/iphone_video.m b/backends/platform/iphone/iphone_video.m
index faa0719b6c..cd8b38acb3 100644
--- a/backends/platform/iphone/iphone_video.m
+++ b/backends/platform/iphone/iphone_video.m
@@ -276,7 +276,7 @@ uint getSizeNextPOT(uint size) {
glGenTextures(1, &_screenTexture);
glBindTexture(GL_TEXTURE_2D, _screenTexture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (_textureBuffer) {
free(_textureBuffer);
diff --git a/backends/platform/n64/README.N64 b/backends/platform/n64/README.N64
index 1cdd82e1e9..276436b676 100644
--- a/backends/platform/n64/README.N64
+++ b/backends/platform/n64/README.N64
@@ -13,6 +13,8 @@ Requirements
Build cart images from sources
==============================
+You can download hkz-libn64 sources from here: http://hkzlab.ipv7.net/consoles.html
+hkz-libn64 is a library to control Nintendo64 hardware (es, video, audio, input, etc.).
* TODO *
Build cart images from binaries
diff --git a/backends/platform/n64/module.mk b/backends/platform/n64/module.mk
index 8fb6ba49ab..429b63802e 100644
--- a/backends/platform/n64/module.mk
+++ b/backends/platform/n64/module.mk
@@ -1,7 +1,12 @@
MODULE := backends/platform/n64
MODULE_OBJS := \
- nintendo64.o
+ nintendo64.o \
+ osys_n64_base.o \
+ osys_n64_events.o \
+ osys_n64_utilities.o \
+ pakfs_save_manager.o \
+ framfs_save_manager.o
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
diff --git a/backends/platform/psp/audio.cpp b/backends/platform/psp/audio.cpp
index bf1fb9ab41..e540733162 100644
--- a/backends/platform/psp/audio.cpp
+++ b/backends/platform/psp/audio.cpp
@@ -28,7 +28,6 @@
#include "common/scummsys.h"
#include "backends/platform/psp/audio.h"
-#include "backends/platform/psp/thread.h"
//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
//#define __PSP_DEBUG_PRINT__ /* For debug printouts */
@@ -85,43 +84,13 @@ bool PspAudio::open(uint32 freq, uint32 numOfChannels, uint32 numOfSamples, call
_init = true;
_paused = true; // start in paused mode
- createThread();
+ threadCreateAndStart("audioThread", PRIORITY_AUDIO_THREAD, STACK_AUDIO_THREAD); // start the consumer thread
return true;
}
-bool PspAudio::createThread() {
- DEBUG_ENTER_FUNC();
- int threadId = sceKernelCreateThread("audioThread", thread, PRIORITY_AUDIO_THREAD, STACK_AUDIO_THREAD, THREAD_ATTR_USER, 0);
-
- if (threadId < 0) { // error
- PSP_ERROR("failed to create audio thread. Error code %d\n", threadId);
- return false;
- }
-
- PspAudio *_this = this; // trick to get into context when the thread starts
-
- if (sceKernelStartThread(threadId, sizeof(uint32 *), &_this) < 0) {
- PSP_ERROR("failed to start thread %d\n", threadId);
- return false;
- }
-
- PSP_DEBUG_PRINT("created audio thread[%x]\n", threadId);
-
- return true;
-}
-
-// Static function to be called upon thread startup. Will call a non-static function
-int PspAudio::thread(SceSize, void *__this) {
- DEBUG_ENTER_FUNC();
- PspAudio *_this = *(PspAudio **)__this; // get our this for the context
-
- _this->audioThread();
- return 0;
-};
-
// The real thread function
-void PspAudio::audioThread() {
+void PspAudio::threadFunction() {
assert(_callback);
PSP_DEBUG_PRINT_FUNC("audio thread started\n");
@@ -129,15 +98,15 @@ void PspAudio::audioThread() {
if (_paused)
PSP_DEBUG_PRINT("audio thread paused\n");
while (_paused) { // delay until we stop pausing
- sceKernelDelayThread(100000); // 100ms
+ PspThread::delayMicros(100000); // 100ms
if (!_paused)
PSP_DEBUG_PRINT("audio thread unpaused\n");
}
- PSP_DEBUG_PRINT("remaining samples[%d]\n", remainingSamples);
+ PSP_DEBUG_PRINT("remaining samples[%d]\n", _remainingSamples);
PSP_DEBUG_PRINT("filling buffer[%d]\n", _bufferToFill);
- _callback(_userData, _buffers[_bufferToFill], _bufferSize); // ask mixer to fill in
+ _callback(_userData, _buffers[_bufferToFill], _bufferSize); // ask mixer to fill in data
nextBuffer(_bufferToFill);
PSP_DEBUG_PRINT("playing buffer[%d].\n", _bufferToPlay);
@@ -151,7 +120,7 @@ void PspAudio::audioThread() {
PSP_DEBUG_PRINT("audio thread exiting. ****************************\n");
}
-// Much faster than using %
+// Much faster than using %, especially with conditional moves (MIPS)
inline void PspAudio::nextBuffer(int &bufferIdx) {
DEBUG_ENTER_FUNC();
bufferIdx++;
@@ -176,6 +145,6 @@ inline bool PspAudio::playBuffer() {
}
void PspAudio::close() {
- PSP_DEBUG_PRINT("close had been called ***************\n");
+ PSP_DEBUG_PRINT("close has been called ***************\n");
_init = false;
}
diff --git a/backends/platform/psp/audio.h b/backends/platform/psp/audio.h
index 603f8f6bfc..eeba598fed 100644
--- a/backends/platform/psp/audio.h
+++ b/backends/platform/psp/audio.h
@@ -26,13 +26,15 @@
#ifndef PSP_AUDIO_H
#define PSP_AUDIO_H
-class PspAudio {
+#include "backends/platform/psp/thread.h"
+
+class PspAudio : public PspThreadable {
public:
enum {
NUM_BUFFERS = 2,
FREQUENCY = 44100 /* only frequency we allow */
};
- typedef void (* callbackFunc)(void *userData, byte *samples, int len);
+ typedef void (* callbackFunc)(void *userData, byte *samples, int len); // audio callback to call
PspAudio() : _pspChannel(0),
_numOfChannels(0), _numOfSamples(0), _callback(0),
_bufferToPlay(0), _bufferToFill(0),
@@ -43,14 +45,12 @@ public:
~PspAudio() { close(); }
bool playBuffer();
void nextBuffer(int &bufferIdx);
- static int thread(SceSize, void *);
- void audioThread();
bool open(uint32 freq, uint32 numOfChannels, uint32 numOfSamples, callbackFunc callback, void *userData);
- bool createThread();
void close();
uint32 getFrequency() { return FREQUENCY; }
void pause() { _paused = true; }
void unpause() { _paused = false; }
+ virtual void threadFunction(); // actual audio thread
private:
int _pspChannel; // chosen hardware output channel
diff --git a/backends/platform/psp/display_manager.cpp b/backends/platform/psp/display_manager.cpp
index a9f33f6091..5037543f12 100644
--- a/backends/platform/psp/display_manager.cpp
+++ b/backends/platform/psp/display_manager.cpp
@@ -34,7 +34,6 @@
#include "backends/platform/psp/default_display_client.h"
#include "backends/platform/psp/cursor.h"
#include "backends/platform/psp/pspkeyboard.h"
-#include "backends/platform/psp/thread.h"
#define USE_DISPLAY_CALLBACK // to use callback for finishing the render
#include "backends/platform/psp/display_manager.h"
@@ -65,37 +64,24 @@ const OSystem::GraphicsMode DisplayManager::_supportedModes[] = {
void MasterGuRenderer::setupCallbackThread() {
DEBUG_ENTER_FUNC();
- int thid = sceKernelCreateThread("displayCbThread", guCallbackThread, PRIORITY_DISPLAY_THREAD, STACK_DISPLAY_THREAD, THREAD_ATTR_USER, 0);
- PSP_DEBUG_PRINT("Display CB thread id is %x\n", thid);
-
- // We want to pass the pointer to this, but we'll have to take address of this so use a little trick
- MasterGuRenderer *_this = this;
-
- if (thid >= 0) {
- sceKernelStartThread(thid, sizeof(uint32 *), &_this);
- } else
- PSP_ERROR("failed to create display callback thread\n");
+ // start the thread that updates the display
+ threadCreateAndStart("DisplayCbThread", PRIORITY_DISPLAY_THREAD, STACK_DISPLAY_THREAD);
}
-// thread that reacts to the callback
-int MasterGuRenderer::guCallbackThread(SceSize, void *__this) {
+// this function gets called by PspThread when starting the new thread
+void MasterGuRenderer::threadFunction() {
DEBUG_ENTER_FUNC();
- // Dereferenced the copied value which was this
- MasterGuRenderer *_this = *(MasterGuRenderer **)__this;
-
// Create the callback. It should always get the pointer to MasterGuRenderer
- _this->_callbackId = sceKernelCreateCallback("Display Callback", guCallback, _this);
- if (_this->_callbackId < 0) {
- PSP_ERROR("failed to create display callback\n");
- return -1;
+ _callbackId = sceKernelCreateCallback("Display Callback", guCallback, this);
+ if (_callbackId < 0) {
+ PSP_ERROR("failed to create display callback\n");
}
PSP_DEBUG_PRINT("created callback. Going to sleep\n");
- sceKernelSleepThreadCB(); // sleep until we get a callback
- return 0;
+ sceKernelSleepThreadCB(); // sleep until we get a callback
}
// This callback is called when the render is finished. It swaps the buffers
diff --git a/backends/platform/psp/display_manager.h b/backends/platform/psp/display_manager.h
index dbbdf2022c..1f7320902c 100644
--- a/backends/platform/psp/display_manager.h
+++ b/backends/platform/psp/display_manager.h
@@ -26,10 +26,12 @@
#ifndef PSP_DISPLAY_MAN_H
#define PSP_DISPLAY_MAN_H
+#include "backends/platform/psp/thread.h"
+
/**
* Class used only by DisplayManager to start/stop GU rendering
*/
-class MasterGuRenderer {
+class MasterGuRenderer : public PspThreadable {
public:
MasterGuRenderer() : _lastRenderTime(0), _renderFinished(true), _callbackId(-1) {}
void guInit();
@@ -37,15 +39,15 @@ public:
void guPostRender();
void guShutDown();
bool isRenderFinished() { return _renderFinished; }
- void setupCallbackThread();
+ void setupCallbackThread();
private:
+ virtual void threadFunction(); // for the display callback thread
static uint32 _displayList[];
uint32 _lastRenderTime; // For measuring rendering time
void guProgramDisplayBufferSizes();
- static int guCallbackThread(SceSize, void *); // for the graphics callbacks
- static int guCallback(int, int, void *__this);
+ static int guCallback(int, int, void *__this); // for the display callback
bool _renderFinished; // for sync with render callback
- int _callbackId; // to keep track of render callback
+ int _callbackId; // to keep track of render callback
};
class Screen;
diff --git a/backends/platform/psp/memory.cpp b/backends/platform/psp/memory.cpp
index 8eef223f8c..29d0482d9a 100644
--- a/backends/platform/psp/memory.cpp
+++ b/backends/platform/psp/memory.cpp
@@ -39,9 +39,17 @@
extern "C" {
+#ifdef TEST_MEMORY_COPY /* we won't be able to run in this case b/c of printouts */
+extern void *__real_memcpy(void *dst, void *src, size_t bytes);
+#endif
+
void *__wrap_memcpy(void *dst, void *src, size_t bytes) {
+#ifdef TEST_MEMORY_COPY /* we won't be able to run in this case */
+ return __real_memcpy(dst, src, bytes);
+#else
PspMemory::fastCopy((byte *)dst, (byte *)src, bytes);
return dst;
+#endif
}
}
@@ -291,43 +299,31 @@ void PspMemory::copy32Misaligned(uint32 *dst32, const byte *src, uint32 bytes, u
PSP_DEBUG_PRINT("copy32Misaligned: dst32[%p], src[%p], bytes[%d], alignSrc[%d]\n", dst32, src, bytes, alignSrc);
uint32 *src32 = (uint32 *)(((uint32)src) & 0xFFFFFFFC); // remove misalignment
- uint32 offset;
+ uint32 shiftValue, lastShiftValue;
switch (alignSrc) {
case 1:
- offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 8, 24);
+ shiftValue = 8;
+ lastShiftValue = 24;
break;
case 2:
- offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 16, 16);
+ shiftValue = 16;
+ lastShiftValue = 16;
break;
default: /* 3 */
- offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 24, 8);
+ shiftValue = 24;
+ lastShiftValue = 8;
break;
}
-
- uint32 remainingBytes = bytes & 3;
-
- if (remainingBytes) {
- byte *dst = (byte *)dst32;
- src += offset;
- dst += offset;
- copy8(dst, src, remainingBytes);
- }
-}
-// returns offset in dst
-uint32 PspMemory::misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, uint32 alignSrc, const uint32 shiftValue, const uint32 lastShiftValue) {
- uint32 *origDst32 = dst32;
- register uint32 dstWord, srcWord;
-
- PSP_DEBUG_PRINT("misaligned32Detail(): alignSrc[%d], dst32[%p], src32[%p], bytes[%d]\n", alignSrc, dst32, src32, bytes);
-
+ uint32 dstWord, srcWord;
+
// Try to do groups of 4 words
uint32 words4 = bytes >> 4;
- srcWord = src32[0];
-
- while (words4--) {
+ srcWord = *src32; // preload 1st word so we read ahead
+
+ for (; words4; words4--) {
dstWord = srcWord >> shiftValue;
srcWord = src32[1];
dstWord |= srcWord << lastShiftValue;
@@ -348,22 +344,29 @@ uint32 PspMemory::misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes,
dst32 += 4;
}
- uint32 words = (bytes & 0xF) >> 2;
+ uint32 words = (bytes & 0xF) >> 2; // now get remaining words
// we read one word ahead of what we write
// setup the first read
- if (words) {
- src32++; // we already loaded the value, so just increment
+
+ for (; words ;words--) {
+ dstWord = srcWord >> shiftValue;
+ srcWord = src32[1]; // we still go one ahead
+ src32++;
+ dstWord |= srcWord << lastShiftValue;
+ *dst32++ = dstWord;
+ }
+
+ uint32 bytesLeft = bytes & 3; // and remaining bytes
- while (words--) {
- dstWord = srcWord >> shiftValue;
- srcWord = *src32++;
- dstWord |= srcWord << lastShiftValue;
- *dst32++ = dstWord;
+ if (bytesLeft) {
+ byte *dst8 = (byte *)dst32;
+ byte *src8 = ((byte *)src32) + ((uint32)src & 0x3); // get exact location we should be at
+
+ for(; bytesLeft; bytesLeft--) {
+ *dst8++ = *src8++;
}
}
-
- return (byte *)dst32 - (byte *)origDst32;
}
// More challenging -- need to shift
diff --git a/backends/platform/psp/memory.h b/backends/platform/psp/memory.h
index c9b3d21cb6..793bc94888 100644
--- a/backends/platform/psp/memory.h
+++ b/backends/platform/psp/memory.h
@@ -52,7 +52,6 @@ private:
static void copy32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes);
static void swap32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes, PSPPixelFormat &format);
static void copy32Misaligned(uint32 *dst32, const byte *src, uint32 bytes, uint32 alignSrc);
- static uint32 misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, uint32 alignSrc, const uint32 shiftValue, const uint32 lastShiftValue);
static void swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format);
static void copy16(uint16 *dst, const uint16 *src, uint32 bytes);
diff --git a/backends/platform/psp/thread.cpp b/backends/platform/psp/thread.cpp
index c19ff5f9e3..916b1e553b 100644
--- a/backends/platform/psp/thread.cpp
+++ b/backends/platform/psp/thread.cpp
@@ -28,7 +28,50 @@
#include "backends/platform/psp/thread.h"
#include "backends/platform/psp/trace.h"
-// Class PspThread --------------------------------------------------
+// Class PspThreadable --------------------------------------------------
+// Inherit this to create C++ threads easily
+
+bool PspThreadable::threadCreateAndStart(const char *threadName, int priority, int stackSize, bool useVfpu /*= false*/) {
+ DEBUG_ENTER_FUNC();
+
+ if (_threadId != -1) {
+ PSP_ERROR("thread already created!\n");
+ return false;
+ }
+
+ _threadId = sceKernelCreateThread(threadName, __threadCallback, priority, stackSize, THREAD_ATTR_USER, 0); // add VFPU support
+
+ if (_threadId < 0) {
+ PSP_ERROR("failed to create %s thread. Error code %d\n", threadName, _threadId);
+ return false;
+ }
+
+ // We want to pass the pointer to this, but we'll have to take address of this so use a little trick
+ PspThreadable *_this = this;
+
+ if (sceKernelStartThread(_threadId, sizeof(uint32 *), &_this) < 0) {
+ PSP_ERROR("failed to start %s thread id[%d]\n", threadName, _threadId);
+ return false;
+ }
+
+ PSP_DEBUG_PRINT("Started %s thread with id[%x]\n", threadName, _threadId);
+
+ return true;
+}
+
+// Callback function to be called by PSP kernel
+int PspThreadable::__threadCallback(SceSize, void *__this) {
+ DEBUG_ENTER_FUNC();
+
+ PspThreadable *_this = *(PspThreadable **)__this; // Dereference the copied value which was 'this'
+
+ _this->threadFunction(); // call the virtual function
+
+ return 0;
+}
+
+// PspThread class
+// Utilities to access general thread functions
void PspThread::delayMillis(uint32 ms) {
sceKernelDelayThread(ms * 1000);
diff --git a/backends/platform/psp/thread.h b/backends/platform/psp/thread.h
index 27d53903d6..de1c10a2aa 100644
--- a/backends/platform/psp/thread.h
+++ b/backends/platform/psp/thread.h
@@ -26,11 +26,26 @@
#ifndef PSP_THREAD_H
#define PSP_THREAD_H
+#include <pspthreadman.h>
#include "common/scummsys.h"
+// class to inherit for creating threads
+class PspThreadable {
+protected:
+ int _threadId;
+ virtual void threadFunction() = 0; // this function will be called when the thread starts
+public:
+ PspThreadable() : _threadId(-1) {} // constructor
+ virtual ~PspThreadable() {} // destructor
+ static int __threadCallback(SceSize, void *__this); // used to get called by sceKernelStartThread() Don't override
+ bool threadCreateAndStart(const char *threadName, int priority, int stackSize, bool useVfpu = false);
+};
+
+// class for thread utils
class PspThread {
-public:
- static void delayMillis(uint32 ms);
+public:
+ // static functions
+ static void delayMillis(uint32 ms); // delay the current thread
static void delayMicros(uint32 us);
};
@@ -85,6 +100,7 @@ enum ThreadPriority {
};
enum StackSizes {
+ STACK_DEFAULT = 4 * 1024,
STACK_AUDIO_THREAD = 16 * 1024,
STACK_TIMER_THREAD = 32 * 1024,
STACK_DISPLAY_THREAD = 2 * 1024,