[Scummvm-cvs-logs] SF.net SVN: scummvm:[33183] scummvm/branches/gsoc2008-rtl

cpage88 at users.sourceforge.net cpage88 at users.sourceforge.net
Tue Jul 22 00:46:43 CEST 2008


Revision: 33183
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33183&view=rev
Author:   cpage88
Date:     2008-07-21 22:46:39 +0000 (Mon, 21 Jul 2008)

Log Message:
-----------
Merged revisions 33052-33053,33056-33058,33061-33064,33068,33070,33072,33075,33078-33079,33083,33086-33087,33089,33094-33096,33098-33099,33104,33108-33109,33114-33117,33120,33135-33146,33160,33162,33165,33167-33169 via svnmerge from 
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk

Modified Paths:
--------------
    scummvm/branches/gsoc2008-rtl/backends/midi/quicktime.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/Makefile.ps2
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/fileio.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/irxboot.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/systemps2.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/systemps2.h
    scummvm/branches/gsoc2008-rtl/backends/platform/sdl/sdl.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/sdl/sdl.h
    scummvm/branches/gsoc2008-rtl/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
    scummvm/branches/gsoc2008-rtl/backends/platform/symbian/src/SymbianOS.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/wince/missing/missing.cpp
    scummvm/branches/gsoc2008-rtl/base/game.cpp
    scummvm/branches/gsoc2008-rtl/base/game.h
    scummvm/branches/gsoc2008-rtl/base/internal_version.h
    scummvm/branches/gsoc2008-rtl/base/plugins.h
    scummvm/branches/gsoc2008-rtl/common/config-manager.cpp
    scummvm/branches/gsoc2008-rtl/common/file.cpp
    scummvm/branches/gsoc2008-rtl/common/str.cpp
    scummvm/branches/gsoc2008-rtl/common/str.h
    scummvm/branches/gsoc2008-rtl/common/stream.cpp
    scummvm/branches/gsoc2008-rtl/common/stream.h
    scummvm/branches/gsoc2008-rtl/configure
    scummvm/branches/gsoc2008-rtl/dists/redhat/scummvm.spec
    scummvm/branches/gsoc2008-rtl/dists/scummvm.rc
    scummvm/branches/gsoc2008-rtl/dists/slackware/scummvm.SlackBuild
    scummvm/branches/gsoc2008-rtl/engines/agos/agos.h
    scummvm/branches/gsoc2008-rtl/engines/agos/gfx.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/cine.h
    scummvm/branches/gsoc2008-rtl/engines/cine/gfx.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/prc.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/prc.h
    scummvm/branches/gsoc2008-rtl/engines/cine/script_fw.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/texte.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/texte.h
    scummvm/branches/gsoc2008-rtl/engines/cine/various.cpp
    scummvm/branches/gsoc2008-rtl/engines/kyra/kyra_v1.cpp
    scummvm/branches/gsoc2008-rtl/engines/kyra/sound_towns.cpp
    scummvm/branches/gsoc2008-rtl/engines/kyra/staticres.cpp
    scummvm/branches/gsoc2008-rtl/engines/lure/luredefs.h
    scummvm/branches/gsoc2008-rtl/engines/lure/res_struct.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/callables_ns.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/dialogue.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/exec_ns.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/gfxbase.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/graphics.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/graphics.h
    scummvm/branches/gsoc2008-rtl/engines/parallaction/input.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/input.h
    scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction.h
    scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction_br.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction_ns.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/walk.cpp
    scummvm/branches/gsoc2008-rtl/engines/queen/graphics.cpp
    scummvm/branches/gsoc2008-rtl/engines/queen/graphics.h
    scummvm/branches/gsoc2008-rtl/engines/queen/sound.cpp
    scummvm/branches/gsoc2008-rtl/engines/queen/sound.h
    scummvm/branches/gsoc2008-rtl/engines/scumm/detection.cpp
    scummvm/branches/gsoc2008-rtl/engines/scumm/dialogs.cpp
    scummvm/branches/gsoc2008-rtl/engines/scumm/dialogs.h
    scummvm/branches/gsoc2008-rtl/engines/scumm/imuse_digi/dimuse_sndmgr.cpp
    scummvm/branches/gsoc2008-rtl/engines/sword2/music.cpp
    scummvm/branches/gsoc2008-rtl/engines/sword2/sound.h
    scummvm/branches/gsoc2008-rtl/test/common/str.h

Added Paths:
-----------
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/elf/
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/iop/rpckbd/
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/iop/rpckbd/include/
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/iop/rpckbd/src/

Removed Paths:
-------------
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/iop/rpckbd/include/
    scummvm/branches/gsoc2008-rtl/backends/platform/ps2/iop/rpckbd/src/

Property Changed:
----------------
    scummvm/branches/gsoc2008-rtl/


Property changes on: scummvm/branches/gsoc2008-rtl
___________________________________________________________________
Modified: svnmerge-integrated
   - /scummvm/branches/gsoc2008-gui:1-31703 /scummvm/branches/gsoc2008-tfmx:1-31765 /scummvm/trunk:1-33050
   + /scummvm/branches/gsoc2008-gui:1-31703 /scummvm/branches/gsoc2008-rtl:1-32741 /scummvm/branches/gsoc2008-tfmx:1-31765

Modified: scummvm/branches/gsoc2008-rtl/backends/midi/quicktime.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/midi/quicktime.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/midi/quicktime.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -132,8 +132,7 @@
 	return MERR_DEVICE_NOT_AVAILABLE;
 }
 
-void MidiDriver_QT::close()
-{
+void MidiDriver_QT::close() {
 	MidiDriver_MPU401::close();
 	dispose();
 }
@@ -248,8 +247,7 @@
 	NASetController(qtNoteAllocator, qtNoteChannel[channel], kControllerPitchBend, theBend);
 }
 
-void MidiDriver_QT::dispose()
-{
+void MidiDriver_QT::dispose() {
 	for (int i = 0; i < 16; i++) {
 		if (qtNoteChannel[i] != 0)
 			NADisposeNoteChannel(qtNoteAllocator, qtNoteChannel[i]);

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/ps2/Makefile.ps2
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/ps2/Makefile.ps2	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/ps2/Makefile.ps2	2008-07-21 22:46:39 UTC (rev 33183)
@@ -19,16 +19,17 @@
 srcdir = ../../..
 VPATH = $(srcdir)
 INCDIR = ../../../
+DEPDIR = .deps
 
 DEFINES  = -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_MPEG2 -DUSE_ZLIB -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar
 
 # PS2SDK-Ports from ps2dev.org's SVN repository for libmad, zlib and ucl
-PS2SDK_PORTS = /home/robby/libStuffNew/ps2sdk-ports
+PS2SDK_PORTS = /mnt/winxp/scummvm/ports
 PS2SDK_PORTS_INCS = /ucl /zlib/include /libmad/ee/include
 PS2SDK_PORTS_LIBS = /ucl /zlib/lib /libmad/ee/lib
 
 # we also need SjPcm, Tremor and libmpeg2
-MORE_LIBS_DIR = /home/robby/libStuff
+MORE_LIBS_DIR = /mnt/winxp/scummvm/ports
 MORE_LIBS_INCS = /SjPcm/ee/src /mpeg2dec/include /tremor
 MORE_LIBS_LIBS = /SjPcm/ee/lib /mpeg2dec/libmpeg2 /tremor/tremor
 

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/ps2/fileio.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/ps2/fileio.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/ps2/fileio.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -340,8 +340,6 @@
 		assert(cacheListSema >= 0);
 	}
 
-	//printf("ps2_fopen: %s, %s\n", fname, mode);
-
 	if (((mode[0] != 'r') && (mode[0] != 'w')) || ((mode[1] != '\0') && (mode[1] != 'b'))) {
 		printf("unsupported mode \"%s\" for file \"%s\"\n", mode, fname);
 		return NULL;
@@ -363,6 +361,8 @@
 	} else {
 		// Regular access to one of the devices
 
+		printf("ps2_fopen = %s\n", fname); // romeo : temp
+
 		if (!rdOnly)
 			return NULL; // we only provide readaccess for cd,dvd,hdd,usb
 
@@ -378,19 +378,22 @@
 		}
 
 		int64 cacheId = -1;
-		if (rdOnly && tocManager.haveEntries())
+		if (tocManager.haveEntries())
 			cacheId = tocManager.fileExists(fname);
 
 		if (cacheId != 0) {
 			Ps2File *file = findInCache(cacheId);
-			if (file)
+			if (file) {
+				printf("  findInCache(%x)\n", cacheId); // romeo : temp
 				return (FILE*)file;
+			}
 
 			bool isAudioFile = strstr(fname, ".bun") || strstr(fname, ".BUN") || strstr(fname, ".Bun");
 			file = new Ps2ReadFile(cacheId, isAudioFile);
 
 			if (file->open(fname)) {
 				openFileCount++;
+				printf("  new cacheID = %x\n", cacheId); // romeo : temp
 				return (FILE*)file;
 			} else
 				delete file;
@@ -579,7 +582,7 @@
 	}
 	char readPath[256];
 	sprintf(readPath, "%s/", _root);
-	printf("readDir: %s\n", readPath);
+	printf("readDir: %s    (root: %s )\n", readPath, root);
 	readDir(readPath, &_rootNode, 0);
 }
 
@@ -587,28 +590,62 @@
 	if (level <= 2) { // we don't scan deeper than that
 		iox_dirent_t dirent;
 		int fd = fio.dopen(path);
+		TocNode *eNode = NULL; // = *node; // entry node
+		bool first = true;
+
+		printf("path=%s - level=%d fd=%d\n", path, level, fd); // romeo : temp
 		if (fd >= 0) {
-			while (fio.dread(fd, &dirent) > 0)
-				if (dirent.name[0] != '.') { // skip '.' and '..'
+			while (fio.dread(fd, &dirent) > 0) {
+				if (dirent.name[0] != '.') { // skip '.' & '..' - romeo : check
+				                             // --- do we have them on PS2?
 					*node = new TocNode;
+					if (first) {
+						eNode = *node;
+						first = false;
+					}
 					(*node)->sub = (*node)->next = NULL;
-
 					(*node)->nameLen = strlen(dirent.name);
 					memcpy((*node)->name, dirent.name, (*node)->nameLen + 1);
 
-					if (dirent.stat.mode & FIO_S_IFDIR) { // directory
+					if (dirent.stat.mode & FIO_S_IFDIR) {
 						(*node)->isDir = true;
-						char nextPath[256];
-						sprintf(nextPath, "%s%s/", path, dirent.name);
-						readDir(nextPath, &((*node)->sub), level + 1);
-					} else
+						printf("dirent.name = %s [DIR]\n", dirent.name);
+					}
+					else {
 						(*node)->isDir = false;
+						printf("dirent.name = %s\n", dirent.name);
+					}
+
 					node = &((*node)->next);
 				}
+			}
+
 			fio.dclose(fd);
-		} else
-			printf("Can't open path: %s\n", path);
+		}
+
+		TocNode *iNode = eNode;
+		char nextPath[256];
+
+		while (iNode) {
+			if (iNode->isDir == true) {
+				sprintf(nextPath, "%s%s/", path, iNode->name);
+				readDir(nextPath, &(iNode->sub), level + 1);
+			}
+			iNode = iNode->next;
+		}
+
 	}
+
+	/*
+		** Wizard of Oz' trick (to get all games running from USB on PS2):
+
+		1. Make a list of files / dirs in level #0 (dclose before continuing)
+
+		2. Go through the dirs : dopen / dread them / mark dirs / dclose
+
+		   It's a safe recursion, cause it recurses on 'isDir' nodes
+		   after dclosing the higher hierarchy
+	*/
 }
 
 int64 TocManager::fileExists(const char *name) {

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/ps2/irxboot.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/ps2/irxboot.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/ps2/irxboot.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -43,7 +43,7 @@
 	{ "PADMAN",  BIOS, NOTHING, NULL, 0 },
 	{ "LIBSD",   BIOS, NOTHING, NULL, 0 },
 
-	{ "IOMANX.IRX",   SYSTEM | NOT_HOST, NOTHING, NULL, 0 }, // already loaded by ps2link
+	{ "IOMANX.IRX",   SYSTEM /*| NOT_HOST*/, NOTHING, NULL, 0 }, // already loaded by ps2link
 	{ "FILEXIO.IRX",  SYSTEM, NOTHING, NULL, 0 },
 	{ "CODYVDFS.IRX", SYSTEM, NOTHING, NULL, 0 },
 	{ "SJPCM.IRX",    SYSTEM, NOTHING, NULL, 0 },

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/ps2/systemps2.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/ps2/systemps2.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/ps2/systemps2.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -54,9 +54,11 @@
 #include "graphics/surface.h"
 #include "graphics/font.h"
 #include "backends/timer/default/default-timer.h"
-#include "sound/mixer.h"
+#include "sound/mixer_intern.h"
 #include "common/events.h"
 #include "backends/platform/ps2/ps2debug.h"
+#include "backends/fs/ps2/ps2-fs-factory.h"
+
 // asm("mfc0	%0, $9\n" : "=r"(tickStart));
 
 extern void *_gp;
@@ -309,7 +311,9 @@
 void OSystem_PS2::init(void) {
 	sioprintf("Timer...\n");
 	_scummTimerManager = new DefaultTimerManager();
-	_scummMixer = new Audio::Mixer();
+	_scummMixer = new Audio::MixerImpl(this);
+	_scummMixer->setOutputRate(44100);
+	_scummMixer->setReady(true);
 	initTimer();
 
 	sioprintf("Starting SavefileManager\n");
@@ -410,7 +414,8 @@
 			// we have to produce more samples, call sound mixer
 			// the scratchpad at 0x70000000 is used as temporary soundbuffer
 			//_scummSoundProc(_scummSoundParam, (uint8*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
-			Audio::Mixer::mixCallback(_scummMixer, (byte*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
+			// Audio::Mixer::mixCallback(_scummMixer, (byte*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
+			_scummMixer->mixCallback((byte*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16));
 
 			// demux data into 2 buffers, L and R
 			 __asm__ (
@@ -534,10 +539,6 @@
 	return _scummTimerManager;
 }
 
-int OSystem_PS2::getOutputSampleRate(void) const {
-	return 48000;
-}
-
 Audio::Mixer *OSystem_PS2::getMixer() {
 	return _scummMixer;
 }
@@ -546,6 +547,10 @@
 	return _saveManager;
 }
 
+FilesystemFactory *OSystem_PS2::getFilesystemFactory() {
+	return &Ps2FilesystemFactory::instance();
+}
+
 void OSystem_PS2::setShakePos(int shakeOffset) {
 	_screen->setShakePos(shakeOffset);
 }

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/ps2/systemps2.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/ps2/systemps2.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/ps2/systemps2.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -33,6 +33,7 @@
 class Gs2dScreen;
 class Ps2Input;
 class Ps2SaveFileManager;
+// class Ps2FilesystemFactory;
 struct IrxReference;
 
 #define MAX_MUTEXES 16
@@ -48,7 +49,7 @@
 };
 
 namespace Audio {
-	class Mixer;
+	class MixerImpl;
 };
 
 class OSystem_PS2 : public OSystem {
@@ -87,7 +88,6 @@
 	virtual bool pollEvent(Common::Event &event);
 
 	virtual Audio::Mixer *getMixer();
-	virtual int  getOutputSampleRate(void) const;
 
 	virtual bool openCD(int drive);
 	virtual bool pollCD();
@@ -112,6 +112,7 @@
 	virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b);
 
 	virtual Common::SaveFileManager *getSavefileManager();
+	virtual FilesystemFactory *getFilesystemFactory();
 
 	virtual void getTimeAndDate(struct tm &t) const;
 
@@ -133,7 +134,7 @@
 	void readRtcTime(void);
 
 	DefaultTimerManager *_scummTimerManager;
-	Audio::Mixer *_scummMixer;
+	Audio::MixerImpl *_scummMixer;
 
 
 	bool _mouseVisible;

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/sdl/sdl.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/sdl/sdl.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/sdl/sdl.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -191,7 +191,7 @@
 
 OSystem_SDL::~OSystem_SDL() {
 	SDL_RemoveTimer(_timerID);
-	SDL_CloseAudio();
+	closeMixer();
 
 	free(_dirtyChecksums);
 	free(_currentPalette);
@@ -199,7 +199,6 @@
 	free(_mouseData);
 
 	delete _savefile;
-	delete _mixer;
 	delete _timer;
 }
 
@@ -306,7 +305,7 @@
 	SDL_ShowCursor(SDL_ENABLE);
 
 	SDL_RemoveTimer(_timerID);
-	SDL_CloseAudio();
+	closeMixer();
 
 	free(_dirtyChecksums);
 	free(_currentPalette);
@@ -314,7 +313,6 @@
 	free(_mouseData);
 
 	delete _savefile;
-	delete _mixer;
 	delete _timer;
 
 	SDL_Quit();
@@ -389,14 +387,110 @@
 #pragma mark --- Audio ---
 #pragma mark -
 
+#ifdef MIXER_DOUBLE_BUFFERING
+
+void OSystem_SDL::mixerProducerThread() {
+	byte nextSoundBuffer;
+
+	SDL_LockMutex(_soundMutex);
+	while (true) {
+		// Wait till we are allowed to produce data
+		SDL_CondWait(_soundCond, _soundMutex);
+
+		if (_soundThreadShouldQuit)
+			break;
+
+		// Generate samples and put them into the next buffer
+		nextSoundBuffer = _activeSoundBuf ^ 1;
+		_mixer->mixCallback(_soundBuffers[nextSoundBuffer], _soundBufSize);
+		
+		// Swap buffers
+		_activeSoundBuf = nextSoundBuffer;
+	}
+	SDL_UnlockMutex(_soundMutex);
+}
+
+int SDLCALL OSystem_SDL::mixerProducerThreadEntry(void *arg) {
+	OSystem_SDL *this_ = (OSystem_SDL *)arg;
+	assert(this_);
+	this_->mixerProducerThread();
+	return 0;
+}
+
+
+void OSystem_SDL::initThreadedMixer(Audio::MixerImpl *mixer, uint bufSize) {
+	_soundThreadIsRunning = false;
+	_soundThreadShouldQuit = false;
+
+	// Create mutex and condition variable
+	_soundMutex = SDL_CreateMutex();
+	_soundCond = SDL_CreateCond();
+
+	// Create two sound buffers
+	_activeSoundBuf = 0;
+	_soundBufSize = bufSize;
+	_soundBuffers[0] = (byte *)calloc(1, bufSize);
+	_soundBuffers[1] = (byte *)calloc(1, bufSize);
+
+	_soundThreadIsRunning = true;
+
+	// Finally start the thread
+	_soundThread = SDL_CreateThread(mixerProducerThreadEntry, this);
+}
+
+void OSystem_SDL::deinitThreadedMixer() {
+	// Kill thread?? _soundThread
+
+	if (_soundThreadIsRunning) {
+		// Signal the producer thread to end, and wait for it to actually finish.
+		_soundThreadShouldQuit = true;
+		SDL_CondBroadcast(_soundCond);
+		SDL_WaitThread(_soundThread, NULL);
+
+		// Kill the mutex & cond variables. 
+		// Attention: AT this point, the mixer callback must not be running
+		// anymore, else we will crash!
+		SDL_DestroyMutex(_soundMutex);
+		SDL_DestroyCond(_soundCond);
+
+		_soundThreadIsRunning = false;
+
+		free(_soundBuffers[0]);
+		free(_soundBuffers[1]);
+	}
+}
+
+
+void OSystem_SDL::mixCallback(void *arg, byte *samples, int len) {
+	OSystem_SDL *this_ = (OSystem_SDL *)arg;
+	assert(this_);
+	assert(this_->_mixer);
+
+	assert((int)this_->_soundBufSize == len);
+
+	// Lock mutex, to ensure our data is not overwritten by the producer thread
+	SDL_LockMutex(this_->_soundMutex);
+	
+	// Copy data from the current sound buffer
+	memcpy(samples, this_->_soundBuffers[this_->_activeSoundBuf], len);
+	
+	// Unlock mutex and wake up the produced thread
+	SDL_UnlockMutex(this_->_soundMutex);
+	SDL_CondSignal(this_->_soundCond);
+}
+
+#else
+
 void OSystem_SDL::mixCallback(void *sys, byte *samples, int len) {
 	OSystem_SDL *this_ = (OSystem_SDL *)sys;
 	assert(this_);
+	assert(this_->_mixer);
 
-	if (this_->_mixer)
-		this_->_mixer->mixCallback(samples, len);
+	this_->_mixer->mixCallback(samples, len);
 }
 
+#endif
+
 void OSystem_SDL::setupMixer() {
 	SDL_AudioSpec desired;
 	SDL_AudioSpec obtained;
@@ -443,10 +537,31 @@
 		// Tell the mixer that we are ready and start the sound processing
 		_mixer->setOutputRate(_samplesPerSec);
 		_mixer->setReady(true);
+
+#ifdef MIXER_DOUBLE_BUFFERING
+		initThreadedMixer(_mixer, obtained.samples * 4);
+#endif
+
+		// start the sound system
 		SDL_PauseAudio(0);
 	}
 }
 
+void OSystem_SDL::closeMixer() {
+	if (_mixer)
+		_mixer->setReady(false);
+
+	SDL_CloseAudio();
+
+	delete _mixer;
+	_mixer = 0;
+
+#ifdef MIXER_DOUBLE_BUFFERING
+	deinitThreadedMixer();
+#endif
+
+}
+
 Audio::Mixer *OSystem_SDL::getMixer() {
 	assert(_mixer);
 	return _mixer;

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/sdl/sdl.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/sdl/sdl.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/sdl/sdl.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -51,7 +51,16 @@
 #define USE_OSD	1
 #endif
 
+#if defined(MACOSX)
+// On Mac OS X, we need to double buffer the audio buffer, else anything
+// which produces sampled data with high latency (like the MT-32 emulator)
+// will sound terribly.
+// This could be enabled for more / most ports in the future, but needs some
+// testing.
+#define MIXER_DOUBLE_BUFFERING 1
+#endif
 
+
 enum {
 	GFX_NORMAL = 0,
 	GFX_DOUBLESIZE = 1,
@@ -137,6 +146,8 @@
 	virtual void setupMixer();
 	static void mixCallback(void *s, byte *samples, int len);
 
+	virtual void closeMixer();
+
 	virtual Audio::Mixer *getMixer();
 
 	// Poll CD status
@@ -369,7 +380,24 @@
 	 */
 	MutexRef _graphicsMutex;
 
+#ifdef MIXER_DOUBLE_BUFFERING
+	SDL_mutex *_soundMutex;
+	SDL_cond *_soundCond;
+	SDL_Thread *_soundThread;
+	bool _soundThreadIsRunning;
+	bool _soundThreadShouldQuit;
+	
+	byte _activeSoundBuf;
+	uint _soundBufSize;
+	byte *_soundBuffers[2];
 
+	void mixerProducerThread();
+	static int SDLCALL mixerProducerThreadEntry(void *arg);
+	void initThreadedMixer(Audio::MixerImpl *mixer, uint bufSize);
+	void deinitThreadedMixer();
+#endif
+
+
 	Common::SaveFileManager *_savefile;
 	Audio::MixerImpl *_mixer;
 
@@ -377,7 +405,7 @@
 	Common::TimerManager *_timer;
 
 
-
+protected:
 	void addDirtyRgnAuto(const byte *buf);
 	void makeChecksums(const byte *buf);
 

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl	2008-07-21 22:46:39 UTC (rev 33183)
@@ -226,28 +226,31 @@
 			$VariationSets{'ALL'}{'all'} = "$DefaultFeatures @WorkingEngines @EnablableSubEngines";
 	
 		# now one for each ready-for-release engine
-	
+		if (0)
+		{
 			foreach (@WorkingEngines)
 			{
 				$VariationSets{'ALL'}{$_} = "$DefaultFeatures $_";
 			}
 			# for scumm, we need to add 2 features:
-			$VariationSets{'ALL'}{'scumm'} .= " scumm_7_8 he";
-	
+			#$VariationSets{'ALL'}{'scumm'} .= " scumm_7_8 he";
+		}
+
 		# now one for each not-ready-for-release-or-testing engine
-	
+		if (0)
+		{
 			foreach (@TestingEngines)
 			{
 				$VariationSets{'ALL'}{"test_$_"} = "$DefaultFeatures $_";
 			}
-	
+		}
 		# below here you could specify weird & experimental combinations, non-ready engines
 	
 			# a small version of the saga engine, because it is so big (no tremor,mad,zlib)
-			$VariationSets{'ALL'}{'saga_mini'} = "saga";
+			#$VariationSets{'ALL'}{'saga_mini'} = "saga";
 		
 			# a smaller version of scumm without support for v7, v8 and HE games
-			$VariationSets{'ALL'}{'scumm_no78he'} = "$DefaultFeatures scumm";
+			#$VariationSets{'ALL'}{'scumm_no78he'} = "$DefaultFeatures scumm";
 	
 			# maybe you feel lucky and want to test the sword engines? :P
 			#$VariationSets{'S60v2'}{'test_sword'} = "$DefaultFeatures mpeg2 sword1 sword2";

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/symbian/src/SymbianOS.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/symbian/src/SymbianOS.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/symbian/src/SymbianOS.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -33,7 +33,7 @@
 #include "gui/Actions.h"
 #include "gui/Key.h"
 #include "gui/message.h"
-
+#include "sound/mixer_intern.h"
 #include "..\..\sdl\main.cpp"
 
 #ifdef SAMPLES_PER_SEC_8000 // the GreanSymbianMMP format cannot handle values for defines :(
@@ -42,10 +42,22 @@
   #define SAMPLES_PER_SEC 16000
 #endif
 
+#define KInputBufferLength 128
+// Symbian libc file functionality in order to provide shared file handles
+struct TSymbianFileEntry {
+	RFile iFileHandle;
+	char iInputBuffer[KInputBufferLength];
+	TInt iInputBufferLen;
+	TInt iInputPos;
+};
 
+#define FILE void
+
 ////////// extern "C" ///////////////////////////////////////////////////
 namespace Symbian {
 
+
+
 // Show a simple Symbian Info win with Msg & exit
 void FatalError(const char *msg) {
 	TPtrC8 msgPtr((const TUint8 *)msg);
@@ -246,9 +258,9 @@
 	if (!this_->_mixer)
 		return;
 
-#ifdef S60
+#if defined (S60) && !defined(S60V3)
 	// If not stereo then we need to downmix
-	if (_channels != 2) {
+	if (this_->_mixer->_channels != 2) {
 		this_->_mixer->mixCallback(_stereo_mix_buffer, len * 2);
 
 		int16 *bitmixDst = (int16 *)samples;
@@ -443,15 +455,9 @@
 	}
 }
 
-// Symbian libc file functionality in order to provide shared file handles
-struct TSymbianFileEntry {
-	RFile iFileHandle;
-};
-
-#define FILE void
-
 FILE*	symbian_fopen(const char* name, const char* mode) {
 	TSymbianFileEntry* fileEntry = new TSymbianFileEntry;
+	fileEntry->iInputPos = KErrNotFound;
 
 	if (fileEntry != NULL) {
 		TInt modeLen = strlen(mode);
@@ -509,16 +515,79 @@
 }
 
 size_t symbian_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
-	TPtr8 pointer( (unsigned char*) ptr, size*numItems);
+	TSymbianFileEntry* entry = ((TSymbianFileEntry*)(handle));
+	TUint32 totsize = size*numItems;
+	TPtr8 pointer ( (unsigned char*) ptr, totsize);
 
-	((TSymbianFileEntry*)(handle))->iFileHandle.Read(pointer);
+	// Nothing cached and we want to load at least KInputBufferLength bytes
+	if(totsize >= KInputBufferLength) {	
+		TUint32 totLength = 0;
+		if(entry->iInputPos != KErrNotFound)
+		{
+			TPtr8 cacheBuffer( (unsigned char*) entry->iInputBuffer+entry->iInputPos, entry->iInputBufferLen - entry->iInputPos, KInputBufferLength);
+			pointer.Append(cacheBuffer);
+			entry->iInputPos = KErrNotFound;
+			totLength+=pointer.Length();
+			pointer.Set(totLength+(unsigned char*) ptr, 0, totsize-totLength);
+		}
 
+		entry->iFileHandle.Read(pointer);
+		totLength+=pointer.Length();
+
+		pointer.Set((unsigned char*) ptr, totLength, totsize);
+
+	}
+	else {
+		// Nothing in buffer	
+		if(entry->iInputPos == KErrNotFound) {
+			TPtr8 cacheBuffer( (unsigned char*) entry->iInputBuffer, KInputBufferLength);
+			entry->iFileHandle.Read(cacheBuffer);
+
+			if(cacheBuffer.Length() >= totsize) {
+				pointer.Copy(cacheBuffer.Left(totsize));
+				entry->iInputPos = totsize;
+				entry->iInputBufferLen = cacheBuffer.Length();
+			}
+			else {
+				pointer.Copy(cacheBuffer);
+				entry->iInputPos = KErrNotFound;
+			}
+
+		}
+		else {
+			TPtr8 cacheBuffer( (unsigned char*) entry->iInputBuffer, entry->iInputBufferLen, KInputBufferLength);
+
+			if(entry->iInputPos+totsize < entry->iInputBufferLen) {
+				pointer.Copy(cacheBuffer.Mid(entry->iInputPos, totsize));
+				entry->iInputPos+=totsize;
+			}
+			else {
+			
+			pointer.Copy(cacheBuffer.Mid(entry->iInputPos, entry->iInputBufferLen-entry->iInputPos));
+			cacheBuffer.SetLength(0);
+			entry->iFileHandle.Read(cacheBuffer);
+
+			if(cacheBuffer.Length() >= totsize-pointer.Length()) {
+					TUint32 restSize = totsize-pointer.Length();
+					pointer.Append(cacheBuffer.Left(restSize));
+					entry->iInputPos = restSize;
+					entry->iInputBufferLen = cacheBuffer.Length();
+				}
+				else {
+					pointer.Append(cacheBuffer);
+					entry->iInputPos = KErrNotFound;
+				}
+			}
+		}
+	}	
+
 	return pointer.Length()/size;
 }
 
 size_t symbian_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) {
 	TPtrC8 pointer( (unsigned char*) ptr, size*numItems);
 
+	((TSymbianFileEntry*)(handle))->iInputPos = KErrNotFound;
 	if (((TSymbianFileEntry*)(handle))->iFileHandle.Write(pointer) == KErrNone) {
 		return numItems;
 	}
@@ -528,12 +597,18 @@
 
 bool symbian_feof(FILE* handle) {
 	TInt pos = 0;
-	if (((TSymbianFileEntry*)(handle))->iFileHandle.Seek(ESeekCurrent, pos) == KErrNone) {
+	TSymbianFileEntry* entry = ((TSymbianFileEntry*)(handle));
 
+	if (entry->iFileHandle.Seek(ESeekCurrent, pos) == KErrNone) {
+
 		TInt size = 0;
-		if (((TSymbianFileEntry*)(handle))->iFileHandle.Size(size) == KErrNone) {
-			if (pos == size)
+		if (entry->iFileHandle.Size(size) == KErrNone) {
+			if(entry->iInputPos == KErrNotFound && pos == size) 			
 				return true;
+
+			if(entry->iInputPos != KErrNotFound && pos == size && entry->iInputPos == entry->iInputBufferLen)
+				return true;
+
 			return false;
 		}
 	}
@@ -549,6 +624,7 @@
 }
 
 int symbian_fseek(FILE* handle, long int offset, int whence) {
+
 	TSeek seekMode = ESeekStart;
 	TInt pos = offset;
 
@@ -564,6 +640,8 @@
 		break;
 
 	}
+	
+	((TSymbianFileEntry*)(handle))->iInputPos = KErrNotFound;
 
 	return ((TSymbianFileEntry*)(handle))->iFileHandle.Seek(seekMode, pos);
 }

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wince/missing/missing.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wince/missing/missing.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wince/missing/missing.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -1,9 +1,35 @@
-/* MISSING.C
-   Implementation for standard and semi-standard C library calls missing in WinCE
-   environment.
-   by Vasyl Tsvirkunov
-*/
+/* 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$
+ *
+ */
+
+/* Original code:
+ * Implementation for standard and semi-standard C library calls missing in WinCE
+ * environment.
+ * by Vasyl Tsvirkunov
+ */
+
+
 #include <windows.h>
 #include <tchar.h>
 #include <string.h>
@@ -17,19 +43,8 @@
 #include "time.h"
 #include "dirent.h"
 
-/* forward declaration */
-
-#if _WIN32_WCE < 300
-
-#define _STDAFX_H
-#include "portdefs.h"
-
-#else
-
 char *strdup(const char *strSource);
 
-#endif
-
 #ifdef __GNUC__
 #define EXT_C extern "C"
 #else
@@ -40,19 +55,27 @@
 
 void *bsearch(const void *key, const void *base, size_t nmemb,
 			  size_t size, int (*compar)(const void *, const void *)) {
-	size_t i;
+	// Perform binary search
+	size_t lo = 0;
+	size_t hi = nmemb;
+	while (lo < hi) {
+		size_t mid = (lo + hi) / 2;
+		const void *p = ((const char *)base) + mid * size;
+		int tmp = (*compar)(key, p);
+		if (tmp < 0)
+			hi = mid;
+		else if (tmp > 0)
+			lo = mid + 1;
+		else
+			return (void *)p;
+	}
 
-	for (i=0; i<nmemb; i++)
-		if (compar(key, (void*)((size_t)base + size * i)) == 0)
-			return (void*)((size_t)base + size * i);
 	return NULL;
 }
 
 static WIN32_FIND_DATA wfd;
 
-/* Very limited implementation of stat. Used by UI.C, MEMORY-P.C (latter is not critical) */
-int stat(const char *fname, struct stat *ss)
-{
+int stat(const char *fname, struct stat *ss) {
 	TCHAR fnameUnc[MAX_PATH+1];
 	HANDLE handle;
 	int len;
@@ -63,8 +86,7 @@
 	/* Special case (dummy on WinCE) */
 	len = strlen(fname);
 	if (len >= 2 && fname[len-1] == '.' && fname[len-2] == '.' &&
-		(len == 2 || fname[len-3] == '\\'))
-	{
+		(len == 2 || fname[len-3] == '\\')) {
 		/* That's everything implemented so far */
 		memset(ss, 0, sizeof(struct stat));
 		ss->st_size = 1024;
@@ -74,6 +96,7 @@
 
 	MultiByteToWideChar(CP_ACP, 0, fname, -1, fnameUnc, MAX_PATH);
 	handle = FindFirstFile(fnameUnc, &wfd);
+	FindClose(handle);
 	if (handle == INVALID_HANDLE_VALUE)
 		return -1;
 	else
@@ -83,20 +106,16 @@
 		ss->st_size = wfd.nFileSizeLow;
 		if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
 			ss->st_mode |= S_IFDIR;
-
-		FindClose(handle);
 	}
 	return 0;
 }
 
 char cwd[MAX_PATH+1] = "";
-EXT_C char *getcwd(char *buffer, int maxlen)
-{
+EXT_C char *getcwd(char *buffer, int maxlen) {
 	TCHAR fileUnc[MAX_PATH+1];
 	char* plast;
 
-	if (cwd[0] == 0)
-	{
+	if (cwd[0] == 0) {
 		GetModuleFileName(NULL, fileUnc, MAX_PATH);
 		WideCharToMultiByte(CP_ACP, 0, fileUnc, -1, cwd, MAX_PATH, NULL, NULL);
 		plast = strrchr(cwd, '\\');
@@ -114,8 +133,7 @@
 #ifdef __GNUC__
 #undef GetCurrentDirectory
 #endif
-EXT_C void GetCurrentDirectory(int len, char *buf)
-{
+EXT_C void GetCurrentDirectory(int len, char *buf) {
 	getcwd(buf,len);
 };
 
@@ -125,26 +143,22 @@
 than current folder (concept not implemented in CE).
 */
 #undef fopen
-EXT_C FILE *wce_fopen(const char* fname, const char* fmode)
-{
+EXT_C FILE *wce_fopen(const char* fname, const char* fmode) {
 	char fullname[MAX_PATH+1];
 
 	if (!fname || fname[0] == '\0')
 		return NULL;
-	if (fname[0] != '\\' && fname[0] != '/')
-	{
+	if (fname[0] != '\\' && fname[0] != '/') {
 		getcwd(fullname, MAX_PATH);
 		strncat(fullname, "\\", MAX_PATH-strlen(fullname)-1);
 		strncat(fullname, fname, MAX_PATH-strlen(fullname)-strlen(fname));
 		return fopen(fullname, fmode);
-	}
-	else
+	} else
 		return fopen(fname, fmode);
 }
 
 /* Remove file by name */
-int remove(const char* path)
-{
+int remove(const char* path) {
 	TCHAR pathUnc[MAX_PATH+1];
 	MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
 	return !DeleteFile(pathUnc);
@@ -158,14 +172,22 @@
 
 	WIN32_FIND_DATA ffd;
 	HANDLE h=FindFirstFile(fname, &ffd);
+	FindClose(h);
 
 	if (h == INVALID_HANDLE_VALUE)
 		return -1;  //Can't find file
-	FindClose(h);
 
-	if (ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
-		return 0; //Always return success if target is directory and exists
+	if (ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) {
+		// WORKAROUND: WinCE (or the emulator) sometimes returns bogus direcotry
+		// hits for files that don't exist. Checking for the same fname twice
+		// seems to weed out those false positives.
+		HANDLE h=FindFirstFile(fname, &ffd);
+		FindClose(h);
+		if (h == INVALID_HANDLE_VALUE)
+			return -1;  //Can't find file
 
+		return 0; //Always return success if target is directory and exists
+	}
 	switch (mode) {
 		case 00: //Check existence
 			return 0;
@@ -183,8 +205,7 @@
 #ifndef __GNUC__
 
 /* Limited dirent implementation. Used by UI.C and DEVICES.C */
-DIR* opendir(const char* fname)
-{
+DIR* opendir(const char* fname) {
 	DIR* pdir;
 	char fnameMask[MAX_PATH+1];
 	TCHAR fnameUnc[MAX_PATH+1];
@@ -209,13 +230,10 @@
 	strcpy(pdir->dd_name, fname); /* it has exactly enough space for fname and nul char */
 
 	MultiByteToWideChar(CP_ACP, 0, fnameMask, -1, fnameUnc, MAX_PATH);
-	if ((pdir->dd_handle = (long)FindFirstFile(fnameUnc, &wfd)) == (long)INVALID_HANDLE_VALUE)
-	{
+	if ((pdir->dd_handle = (long)FindFirstFile(fnameUnc, &wfd)) == (long)INVALID_HANDLE_VALUE) {
 		free(pdir);
 		return NULL;
-	}
-	else
-	{
+	} else {
 		WideCharToMultiByte(CP_ACP, 0, wfd.cFileName, -1, nameFound, MAX_PATH, NULL, NULL);
 
 		pdir->dd_dir.d_name = strdup(nameFound);
@@ -224,34 +242,25 @@
 	return pdir;
 }
 
-struct dirent*	readdir(DIR* dir)
-{
+struct dirent* readdir(DIR* dir) {
 	char nameFound[MAX_PATH+1];
 	static struct dirent dummy;
 
-	if (dir->dd_stat == 0)
-	{
+	if (dir->dd_stat == 0) {
 		dummy.d_name = ".";
 		dummy.d_namlen = 1;
 		dir->dd_stat ++;
 		return &dummy;
-	}
-	else if (dir->dd_stat == 1)
-	{
+	} else if (dir->dd_stat == 1) {
 		dummy.d_name = "..";
 		dummy.d_namlen = 2;
 		dir->dd_stat ++;
 		return &dummy;
-	}
-	else if (dir->dd_stat == 2)
-	{
+	} else if (dir->dd_stat == 2) {
 		dir->dd_stat++;
 		return &dir->dd_dir;
-	}
-	else
-	{
-		if (FindNextFile((HANDLE)dir->dd_handle, &wfd) == 0)
-		{
+	} else {
+		if (FindNextFile((HANDLE)dir->dd_handle, &wfd) == 0) {
 			dir->dd_stat = -1;
 			return NULL;
 		}
@@ -283,12 +292,6 @@
 	return 1;
 }
 
-/* in our case unlink is the same as remove */
-int unlink(const char* path)
-{
-	return remove(path);
-}
-
 /* Make directory, Unix style */
 void mkdir(char* dirname, int mode)
 {
@@ -299,10 +302,8 @@
 	if (*path == '/')
 		*path = '\\';
 	/* Run through the string and attempt creating all subdirs on the path */
-	for (ptr = path+1; *ptr; ptr ++)
-	{
-		if (*ptr == '\\' || *ptr == '/')
-		{
+	for (ptr = path+1; *ptr; ptr ++) {
+		if (*ptr == '\\' || *ptr == '/') {
 			*ptr = 0;
 			MultiByteToWideChar(CP_ACP, 0, path, -1, pathUnc, MAX_PATH);
 			CreateDirectory(pathUnc, 0);
@@ -313,374 +314,41 @@
 	CreateDirectory(pathUnc, 0);
 }
 
-/* Used in DEVICES.C and UI.C for some purpose. Not critical in this port */
-int system(const char* path) { return 0; }
-
-#if 0
-
-char *tmpnam(char *string)
-{
-	TCHAR pTemp[MAX_PATH+1];
-	static char buffer[MAX_PATH+1];
-	GetTempFileName(TEXT("."), TEXT("A8_"), 0, pTemp);
-	WideCharToMultiByte(CP_ACP, 0, pTemp, -1, buffer, MAX_PATH, NULL, NULL);
-
-	if (string)
-	{
-		strcpy(string, buffer);
-		return string;
-	}
-	else
-		return buffer;
-}
-
-FILE *tmpfile()
-{
-	TCHAR pTemp[MAX_PATH+1];
-	if (!GetTempFileName(TEXT("."), TEXT("A8_"), 0, pTemp))
-		return _wfopen(pTemp, TEXT("w+b"));
-	else
-		return 0;
-}
-
-#endif
-
-void rewind(FILE *stream)
-{
-	fseek(stream, 0, SEEK_SET);
-}
-
-
-#if _WIN32_WCE < 300
-
-int isalnum(int c) {
-	return ((c >= 'A' && c <= 'Z') ||
-			(c >= 'a' && c <= 'z') ||
-			(c >= '0' && c <= '9'));
-}
-
-char *_strdup(const char *strSource)
-#else
 char *strdup(const char *strSource)
-#endif
 {
 	char* buffer;
-	buffer = (char*)malloc(strlen(strSource)+1);
+	size_z len = strlen(strSource)+1;
+	buffer = (char*)malloc(len);
 	if (buffer)
-		strcpy(buffer, strSource);
+		memcpy(buffer, strSource, len);
 	return buffer;
 }
 
-/* Very limited implementation of sys/time.h */
-void usleep(long usec)
-{
-	long msec = usec/1000;
-	if (msec <= 0)
-		Sleep(0);
-	else
-		Sleep(msec);
-}
-
-/* This may provide for better sync mechanism */
-unsigned int clock()
-{
-	return GetTickCount();
-}
-
-/* And why do people use this? */
-#if _WIN32_WCE >= 300
-void abort()
-{
-	exit(1);
-}
-#endif
-
-/*
-IMHO, no project should use this one, it is not portable at all. This implementation
-at least allows some projects to work.
-*/
-char* getenv(char* name)
-{
-	static char buffer[MAX_PATH+1];
-	if (strcmp(name, "HOME") == 0 || strcmp(name, "HOMEDIR") == 0)
-	{
-		getcwd(buffer, MAX_PATH);
-		return buffer;
-	}
-	else
-		return "";
-}
-
-#if _WIN32_WCE < 300 || defined(_TEST_HPC_STDIO)
-
-void *calloc(size_t n, size_t s) {
-	void *result = malloc(n * s);
-	if (result)
-		memset(result, 0, n * s);
-
-	return result;
-}
-
-char *strpbrk(const char *s, const char *accept) {
-	int i;
-
-	if (!s || !accept)
-		return NULL;
-
-	for (i=0; i<strlen(s); i++) {
-		int j;
-		for (j=0; j<strlen(accept); j++)
-			if (s[i] == accept[j])
-				return (char*)&s[i];
-	}
-
-	return NULL;
-}
-
-#ifndef _TEST_HPC_STDIO
-
-int isdigit(int c) {
-	return (c >='0' && c <= '9');
-}
-
-int isprint(int c) {
-	return (c >= ' ' && c <= '~');
-}
-
-int isspace(int c) {
-	return (c == ' ');
-}
-
-#endif
-
-#ifndef WIN32_PLATFORM_HPCPRO
-
-
-int printf(const char *format, ...) {
-	// useless anyway :)
-	return 0;
-}
-
-FILE *fopen(const char *path, const char *mode) {
-	TCHAR tempo[MAX_PATH];
-	HANDLE result;
-	bool writeAccess = (mode[0] == 'W' || mode[0] == 'w');
-
-	MultiByteToWideChar(CP_ACP, 0, path, strlen(path) + 1, tempo, sizeof(tempo));
-
-	result = CreateFile(tempo, ( writeAccess ? GENERIC_WRITE : GENERIC_READ), 0, NULL, (writeAccess ? CREATE_ALWAYS : OPEN_EXISTING), FILE_ATTRIBUTE_NORMAL, NULL);
-	if (result == INVALID_HANDLE_VALUE)
-		return NULL;
-	else
-		return (FILE*)result;
-}
-
-FILE * _wfopen(const TCHAR *path, const TCHAR *mode) {
-	HANDLE result;
-	bool writeAccess = (mode[0] == 'W' || mode[0] == 'w');
-	result = CreateFile(path, ( writeAccess ? GENERIC_WRITE : GENERIC_READ), 0, NULL, (writeAccess ? CREATE_ALWAYS : OPEN_EXISTING), FILE_ATTRIBUTE_NORMAL, NULL);
-	if (result == INVALID_HANDLE_VALUE)
-		return NULL;
-	else
-		return (FILE*)result;
-}
-
-FILE *_wfreopen(const TCHAR *path, const TCHAR *mode, FILE *stream) {
-	fclose(stream);
-	stream = _wfopen(path, mode);
-	return stream;
-}
-
-int fclose(FILE *stream) {
-	CloseHandle((HANDLE)stream);
-	return 1;
-}
-
-int fseek(FILE *stream, long offset, int whence) {
-	SetFilePointer((HANDLE)stream, offset, NULL, (whence == SEEK_CUR ? FILE_CURRENT : whence == SEEK_END ? FILE_END : FILE_BEGIN));
-	return 0;
-}
-
-long ftell(FILE *stream) {
-	return (SetFilePointer((HANDLE)stream, 0, NULL, FILE_CURRENT));
-}
-
-size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
-	DWORD sizeWritten;
-
-	WriteFile((HANDLE)stream, ptr, size * nmemb, &sizeWritten, NULL);
-
-	if (size != 0)
-		return sizeWritten / size;
-	else
-		return 0;
-}
-
-size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
-	DWORD sizeRead;
-
-	ReadFile((HANDLE)stream, ptr, size * nmemb, &sizeRead, NULL);
-
-	if (size != 0)
-		return sizeRead / size;
-	else
-		return 0;
-}
-
-int fgetc(FILE *stream) {
-	unsigned char c;
-	if (fread(&c, 1, 1, stream) != 1)
-		return -1;
-	else
-		return c;
-}
-
-char *fgets(char *s, int size, FILE *stream) {
-	int i = 0;
-	char tempo[1];
-
-	memset(s, 0, size);
-	while (fread(tempo, 1, 1, stream)) {
-		//if (tempo[0] == '\r')
-		//	break;
-		if (tempo[0] == '\r')
-			continue;
-		s[i++] = tempo[0];
-		if (tempo[0] == '\n')
-			break;
-		if (i == size)
-			break;
-	}
-	if (!i)
-		return NULL;
-	else
-		return s;
-}
-
-int feof(FILE *stream) {
-	DWORD fileSize;
-	DWORD filePos;
-	fileSize = GetFileSize((HANDLE)stream, NULL);
-	filePos = SetFilePointer((HANDLE)stream, 0, 0, FILE_CURRENT);
-	return (filePos == 0xFFFFFFFF || filePos > (fileSize - 1));
-}
-
-int ferror(FILE *stream) {
-	return 0; // FIXME !
-}
-
-int fprintf(FILE *stream, const char *format, ...) {
-	char buf[1024];
-	va_list va;
-
-	va_start(va, format);
-	vsnprintf(buf, 1024, format, va);
-	va_end(va);
-
-	if (buf[strlen(buf) - 1] == '\n') {
-		int i = strlen(buf) - 1;
-		buf[i] = '\r';
-		buf[i + 1] = '\n';
-		buf[i + 2] = 0;
-	}
-
-	return fwrite(buf, 1, strlen(buf), stream);
-}
-
-FILE* _getstdfilex(int) {
-	return NULL;
-}
-
-void clearerr(FILE *stream) {
-}
-
-int fflush(FILE *stream) {
-	return 0;
-}
-
-#endif
-
-int stricmp( const char *string1, const char *string2 ) {
-	char src[4096];
-	char dest[4096];
-	int i;
-
-	for (i=0; i<strlen(string1); i++)
-		if (string1[i] >= 'A' && string1[i] <= 'Z')
-			src[i] = string1[i] + 32;
-		else
-			src[i] = string1[i];
-	src[i] = 0;
-
-	for (i=0; i<strlen(string2); i++)
-		if (string2[i] >= 'A' && string2[i] <= 'Z')
-			dest[i] = string2[i] + 32;
-		else
-			dest[i] = string2[i];
-	dest[i] = 0;
-
-	return strcmp(src, dest);
-}
-
-char *strrchr(const char *s, int c) {
-	int i;
-
-	for (i = strlen(s) - 1; i > 0; i--)
-		if (s[i] == c)
-			return (char*)(s + i);
-
-	return NULL;
-}
-
-long int strtol(const char *nptr, char **endptr, int base) {
-	// not correct but that's all we are using
-
-	long int result;
-	sscanf(nptr, "%ld", &result);
-	return result;
-}
-
-
-#endif
-
-
 // gcc build only functions follow
 #else // defined(__GNUC__)
 
 #ifndef __MINGW32CE__
-int islower(int c)
-{
+int islower(int c) {
 	return (c>='a' && c<='z');
 }
 
-int isspace(int c)
-{
+int isspace(int c) {
 	return (c==' ' || c=='\f' || c=='\n' || c=='\r' || c=='\t' || c=='\v');
 }
 
-int isalpha(int c)
-{
-	return (islower(c) || (c>='A' && c<='Z'));
+int isalpha(int c) {
+	return ((c>='a' && c<='z') || (c>='A' && c<='Z'));
 }
 
-int isalnum(int c)
-{
-	return (isalpha(c) || (c>='0' && c<='9'));
+int isalnum(int c) {
+	return ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9'));
 }
 
-int isprint(int c)
-{
-	static char punct[] = "!\"#%&'();<=>?[\\]*+,-./:^_{|}~";
-	int i = 0, flag = 0;
-	while ((punct[i] != 0) && (flag = (punct[i] != c)))
-		i++;
-	return (isalnum(c) || flag);
+int isprint(int c) {
+	//static const char punct[] = "!\"#%&'();<=>?[\\]*+,-./:^_{|}~";
+	//return (isalnum(c) || strchr(punct, c));
+	return (32 <= c && c <= 126);	// based on BSD manpage
 }
-
-extern "C" int atexit(void (*function)(void))
-{
-	return 0;
-}
 #endif
 
 #endif

Modified: scummvm/branches/gsoc2008-rtl/base/game.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/base/game.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/base/game.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -32,10 +32,10 @@
 	const PlainGameDescriptor *g = list;
 	while (g->gameid) {
 		if (0 == scumm_stricmp(gameid, g->gameid))
-			break;
+			return g;
 		g++;
 	}
-	return g;
+	return 0;
 }
 
 void GameDescriptor::updateDesc(const char *extra) {

Modified: scummvm/branches/gsoc2008-rtl/base/game.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/base/game.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/base/game.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -48,7 +48,7 @@
 /**
  * Given a list of PlainGameDescriptors, returns the first PlainGameDescriptor
  * matching the given gameid. If not match is found return 0.
- * The end of the list marked by a PlainGameDescriptor with gameid equal to 0.
+ * The end of the list must marked by a PlainGameDescriptor with gameid equal to 0.
  */
 const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list);
 

Modified: scummvm/branches/gsoc2008-rtl/base/internal_version.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/base/internal_version.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/base/internal_version.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -1 +1 @@
-#define SCUMMVM_VERSION "0.12.0svn"
+#define SCUMMVM_VERSION "0.13.0svn"

Modified: scummvm/branches/gsoc2008-rtl/base/plugins.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/base/plugins.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/base/plugins.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -81,17 +81,11 @@
 #define STATIC_PLUGIN 1
 #define DYNAMIC_PLUGIN 2
 
-// Note: The spaces around ENABLE_##ID have been added on purpose for
-// MSVC. For some reason, MSVC tries to add the parenthesis after
-// ENABLE_##ID to the check, thus making it false all the time.
-// Please do NOT remove them, otherwise no engine plugins will be
-// registered under MSVC
-
 #define PLUGIN_ENABLED_STATIC(ID) \
-	(defined( ENABLE_##ID ) && !PLUGIN_ENABLED_DYNAMIC(ID))
+	(ENABLE_##ID && !PLUGIN_ENABLED_DYNAMIC(ID))
 
 #define PLUGIN_ENABLED_DYNAMIC(ID) \
-	(defined( ENABLE_##ID ) && (ENABLE_##ID == DYNAMIC_PLUGIN) && defined(DYNAMIC_MODULES))
+	(ENABLE_##ID && (ENABLE_##ID == DYNAMIC_PLUGIN) && DYNAMIC_MODULES)
 
 /**
  * REGISTER_PLUGIN_STATIC is a convenience macro which is used to declare

Modified: scummvm/branches/gsoc2008-rtl/common/config-manager.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/common/config-manager.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/common/config-manager.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -176,7 +176,6 @@
 	if (!cfg_file.open(filename)) {
 		printf("Creating configuration file: %s\n", filename.c_str());
 	} else {
-		char buf[MAXLINELEN];
 		String domain;
 		String comment;
 		int lineno = 0;
@@ -184,20 +183,28 @@
 		// TODO: Detect if a domain occurs multiple times (or likewise, if
 		// a key occurs multiple times inside one domain).
 
-		while (!cfg_file.eof()) {
+		while (!cfg_file.eof() && !cfg_file.ioFailed()) {
 			lineno++;
-			if (!cfg_file.readLine(buf, MAXLINELEN))
-				break;
 
-			if (buf[0] == '#') {
+			// Read a line
+			String line;
+			while (line.lastChar() != '\n') {
+				char buf[MAXLINELEN];
+				if (!cfg_file.readLine_NEW(buf, MAXLINELEN))
+					break;
+				line += buf;
+			}
+
+			if (line.size() == 0) {
+				// Do nothing
+			} else if (line[0] == '#') {
 				// Accumulate comments here. Once we encounter either the start
 				// of a new domain, or a key-value-pair, we associate the value
 				// of the 'comment' variable with that entity.
-				comment += buf;
-				comment += '\n';
-			} else if (buf[0] == '[') {
+				comment += line;
+			} else if (line[0] == '[') {
 				// It's a new domain which begins here.
-				char *p = buf + 1;
+				const char *p = line.c_str() + 1;
 				// Get the domain name, and check whether it's valid (that
 				// is, verify that it only consists of alphanumerics,
 				// dashes and underscores).
@@ -209,8 +216,8 @@
 					error("Config file buggy: missing ] in line %d", lineno);
 					break;
 				case ']':
-					*p = 0;
-					domain = buf + 1;
+					domain = String(line.c_str() + 1, p - (line.c_str() + 1));
+					//domain = String(line.c_str() + 1, p);	// TODO: Pending Common::String changes
 					break;
 				default:
 					error("Config file buggy: Invalid character '%c' occured in domain name in line %d", *p, lineno);
@@ -226,10 +233,14 @@
 
 				_domainSaveOrder.push_back(domain);
 			} else {
-				// Skip leading & trailing whitespaces
-				char *t = rtrim(ltrim(buf));
+				// This line should be a line with a 'key=value' pair, or an empty one.
+				
+				// Skip leading whitespaces
+				const char *t = line.c_str();
+				while (isspace(*t))
+					t++;
 
-				// Skip empty lines
+				// Skip empty lines / lines with only whitespace
 				if (*t == 0)
 					continue;
 
@@ -238,13 +249,30 @@
 					error("Config file buggy: Key/value pair found outside a domain in line %d", lineno);
 				}
 
-				// Split string at '=' into 'key' and 'value'.
-				char *p = strchr(t, '=');
+				// Split string at '=' into 'key' and 'value'. First, find the "=" delimeter.
+				const char *p = strchr(t, '=');
 				if (!p)
 					error("Config file buggy: Junk found in line line %d: '%s'", lineno, t);
-				*p = 0;
-				String key = rtrim(t);
-				String value = ltrim(p + 1);
+
+				// Trim spaces before the '=' to obtain the key
+				const char *p2 = p;
+				while (p2 > t && isspace(*(p2-1)))
+					p2--;
+				String key(t, p2 - t);
+				
+				// Skip spaces after the '='
+				t = p + 1;
+				while (isspace(*t))
+					t++;
+
+				// Trim trailing spaces
+				p2 = t + strlen(t);
+				while (p2 > t && isspace(*(p2-1)))
+					p2--;
+
+				String value(t, p2 - t);
+
+				// Finally, store the key/value pair in the active domain
 				set(key, value, domain);
 
 				// Store comment

Modified: scummvm/branches/gsoc2008-rtl/common/file.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/common/file.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/common/file.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -452,10 +452,12 @@
 }
 
 bool File::ioFailed() const {
+	// TODO/FIXME: Just use ferror() here?
 	return _ioFailed != 0;
 }
 
 void File::clearIOFailed() {
+	// TODO/FIXME: Just use clearerr() here?
 	_ioFailed = false;
 }
 

Modified: scummvm/branches/gsoc2008-rtl/common/str.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/common/str.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/common/str.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -43,32 +43,43 @@
 	return ((len + 32 - 1) & ~0x1F) - 1;
 }
 
-String::String(const char *str, uint32 len)
-: _len(0), _str(_storage) {
+String::String(const char *str) : _len(0), _str(_storage) {
+	if (str == 0) {
+		_storage[0] = 0;
+		_len = 0;
+	} else
+		initWithCStr(str, strlen(str));
+}
 
+String::String(const char *str, uint32 len) : _len(0), _str(_storage) {
+	initWithCStr(str, len);
+}
+
+String::String(const char *beginP, const char *endP) : _len(0), _str(_storage) {
+	assert(endP >= beginP);
+	initWithCStr(beginP, endP - beginP);
+}
+
+void String::initWithCStr(const char *str, uint32 len) {
+	assert(str);
+
 	// Init _storage member explicitly (ie. without calling its constructor)
 	// for GCC 2.95.x compatibility (see also tracker item #1602879).
 	_storage[0] = 0;
 
-	if (str && *str) {
-		const uint32 tmp = strlen(str);
-		assert(len <= tmp);
-		if (len <= 0)
-			len = tmp;
-		_len = len;
+	_len = len;
 
-		if (len >= _builtinCapacity) {
-			// Not enough internal storage, so allocate more
-			_extern._capacity = computeCapacity(len);
-			_extern._refCount = 0;
-			_str = (char *)malloc(_extern._capacity+1);
-			assert(_str != 0);
-		}
+	if (len >= _builtinCapacity) {
+		// Not enough internal storage, so allocate more
+		_extern._capacity = computeCapacity(len);
+		_extern._refCount = 0;
+		_str = (char *)malloc(_extern._capacity+1);
+		assert(_str != 0);
+	}
 
-		// Copy the string into the storage area
-		memcpy(_str, str, len);
-		_str[len] = 0;
-	}
+	// Copy the string into the storage area
+	memmove(_str, str, len);
+	_str[len] = 0;
 }
 
 String::String(const String &str)
@@ -91,6 +102,8 @@
 	_storage[0] = c;
 	_storage[1] = 0;
 
+	// TODO/FIXME: There is no reason for the following check -- we *do*
+	// allow strings to contain 0 bytes!
 	_len = (c == 0) ? 0 : 1;
 }
 
@@ -130,11 +143,14 @@
 	uint32 len = strlen(str);
 	ensureCapacity(len, false);
 	_len = len;
-	memcpy(_str, str, len + 1);
+	memmove(_str, str, len + 1);
 	return *this;
 }
 
 String &String::operator  =(const String &str) {
+	if (&str == this)
+		return *this;
+
 	if (str.isStorageIntern()) {
 		decRefCount(_extern._refCount);
 		_len = str._len;

Modified: scummvm/branches/gsoc2008-rtl/common/str.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/common/str.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/common/str.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -96,10 +96,24 @@
 	static const char *emptyString;
 #endif
 
+	/** Construct a new empty string. */
 	String() : _len(0), _str(_storage) { _storage[0] = 0; }
-	String(const char *str, uint32 len = 0);
+
+	/** Construct a new string from the given NULL-terminated C string. */
+	String(const char *str);
+
+	/** Construct a new string containing exactly len characters read from address str. */
+	String(const char *str, uint32 len);
+	
+	/** Construct a new string containing the characters between beginP (including) and endP (excluding). */
+	String(const char *beginP, const char *endP);
+	
+	/** Construct a copy of the given string. */
 	String(const String &str);
+	
+	/** Construct a string consisting of the given character. */
 	String(char c);
+
 	~String();
 
 	String &operator  =(const char *str);
@@ -162,7 +176,7 @@
 
 	void toLowercase();
 	void toUppercase();
-
+	
 	uint hash() const;
 
 public:
@@ -189,6 +203,7 @@
 	void ensureCapacity(uint32 new_len, bool keep_old);
 	void incRefCount() const;
 	void decRefCount(int *oldRefCount);
+	void initWithCStr(const char *str, uint32 len);
 };
 
 // Append two strings to form a new (temp) string

Modified: scummvm/branches/gsoc2008-rtl/common/stream.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/common/stream.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/common/stream.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -148,6 +148,61 @@
 	return buf;
 }
 
+char *SeekableReadStream::readLine_NEW(char *buf, size_t bufSize) {
+	assert(buf != 0 && bufSize > 1);
+	char *p = buf;
+	size_t len = 0;
+	char c = 0;
+
+	// If end-of-file occurs before any characters are read, return NULL
+	// and the buffer contents remain unchanged. 
+	if (eos() || ioFailed()) {
+		return 0;
+	}
+
+	// Loop as long as the stream has not ended, there is still free
+	// space in the buffer, and the line has not ended
+	while (!eos() && len + 1 < bufSize && c != LF) {
+		c = readByte();
+		
+		// If end-of-file occurs before any characters are read, return
+		// NULL and the buffer contents remain unchanged. If an error
+		/// occurs, return NULL and the buffer contents are indeterminate.
+		if (ioFailed() || (len == 0 && eos()))
+			return 0;
+
+		// Check for CR or CR/LF
+		// * DOS and Windows use CRLF line breaks
+		// * Unix and OS X use LF line breaks
+		// * Macintosh before OS X used CR line breaks
+		if (c == CR) {
+			// Look at the next char -- is it LF? If not, seek back
+			c = readByte();
+			if (c != LF && !eos())
+				seek(-1, SEEK_CUR);
+			// Treat CR & CR/LF as plain LF
+			c = LF;
+		}
+		
+		*p++ = c;
+		len++;
+	}
+
+	// FIXME:
+	// This should fix a bug while using readLine with Common::File
+	// it seems that it sets the eos flag after an invalid read
+	// and at the same time the ioFailed flag
+	// the config file parser fails out of that reason for the new themes
+	if (eos()) {
+		clearIOFailed();
+	}
+
+	// We always terminate the buffer if no error occured
+	*p = 0;
+	return buf;
+}
+
+
 uint32 SubReadStream::read(void *dataPtr, uint32 dataSize) {
 	dataSize = MIN(dataSize, _end - _pos);
 

Modified: scummvm/branches/gsoc2008-rtl/common/stream.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/common/stream.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/common/stream.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -304,13 +304,40 @@
 	 * Read one line of text from a CR or CR/LF terminated plain text file.
 	 * This method is a rough analog of the (f)gets function.
 	 *
+	 * @bug A main difference (and flaw) in this function is that there is no
+	 * way to detect that a line exceeeds the length of the buffer.
+	 * Code which needs this should use the new readLine_NEW() method instead.
+	 *
 	 * @param buf	the buffer to store into
 	 * @param bufSize	the size of the buffer
 	 * @return a pointer to the read string, or NULL if an error occurred
+	 *
 	 * @note The line terminator (CR or CR/LF) is stripped and not inserted
 	 *       into the buffer.
 	 */
 	virtual char *readLine(char *buf, size_t bufSize);
+
+	/**
+	 * Reads at most one less than the number of characters specified
+	 * by bufSize from the and stores them in the string buf. Reading
+	 * stops when the end of a line is reached (CR, CR/LF or LF), at
+	 * end-of-file or error.  The newline, if any, is retained (CR and
+	 * CR/LF are translated to LF = 0xA = '\n').  If any characters are
+	 * read and there is no error, a `\0' character is appended to end
+	 * the string.
+	 *
+	 * Upon successful completion, return a pointer to the string. If
+	 * end-of-file occurs before any characters are read, returns NULL
+	 * and the buffer contents remain unchanged.  If an error occurs,
+	 * returns NULL and the buffer contents are indeterminate.
+	 * This method does not distinguish between end-of-file and error;
+	 * callers muse use ioFailed() or eos() to determine which occurred.
+	 *
+	 * @param buf	the buffer to store into
+	 * @param bufSize	the size of the buffer
+	 * @return a pointer to the read string, or NULL if an error occurred
+	 */
+	virtual char *readLine_NEW(char *s, size_t bufSize);
 };
 
 /**

Modified: scummvm/branches/gsoc2008-rtl/configure
===================================================================
--- scummvm/branches/gsoc2008-rtl/configure	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/configure	2008-07-21 22:46:39 UTC (rev 33183)
@@ -129,10 +129,10 @@
 if type mktemp > /dev/null 2>&1 ; then
 	TMPO=`mktemp /tmp/scummvm-conf.XXXXXXXXXX`
 else
-	TMPO=${_srcdir}/scummvm-conf
+	TMPO=scummvm-conf
 fi
 TMPC=${TMPO}.cpp
-TMPLOG=${_srcdir}/config.log
+TMPLOG=config.log
 
 # For cross compiling
 _host=""

Modified: scummvm/branches/gsoc2008-rtl/dists/redhat/scummvm.spec
===================================================================
--- scummvm/branches/gsoc2008-rtl/dists/redhat/scummvm.spec	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/dists/redhat/scummvm.spec	2008-07-21 22:46:39 UTC (rev 33183)
@@ -7,7 +7,7 @@
 #   Prologue information
 #------------------------------------------------------------------------------
 Name		: scummvm
-Version		: 0.12.0svn
+Version		: 0.13.0svn
 Release		: 1
 Summary		: Graphic adventure game interpreter
 Group		: Interpreters

Modified: scummvm/branches/gsoc2008-rtl/dists/scummvm.rc
===================================================================
--- scummvm/branches/gsoc2008-rtl/dists/scummvm.rc	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/dists/scummvm.rc	2008-07-21 22:46:39 UTC (rev 33183)
@@ -7,8 +7,8 @@
 #endif
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,12,0,0
- PRODUCTVERSION 0,12,0,0
+ FILEVERSION 0,13,0,0
+ PRODUCTVERSION 0,13,0,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -25,13 +25,13 @@
         BEGIN
             VALUE "Comments", "Look! A three headed monkey (TM)! .. Nice use of the TM!\0"
             VALUE "FileDescription", "http://www.scummvm.org/\0"
-            VALUE "FileVersion", "0.12.0svn\0"
+            VALUE "FileVersion", "0.13.0svn\0"
             VALUE "InternalName", "scummvm\0"
             VALUE "LegalCopyright", "Copyright \xA9 2001-2007 The ScummVM Team\0"
             VALUE "LegalTrademarks", "'SCUMM', and all SCUMM games are a TM of LucasArts. Simon The Sorcerer is a TM of AdventureSoft. Beneath a Steel Sky and Broken Sword are a TM of Revolution. Flight of the Amazon Queen is a TM of John Passfield and Steve Stamatiadis. \0"
             VALUE "OriginalFilename", "scummvm.exe\0"
             VALUE "ProductName", "ScummVM\0"
-            VALUE "ProductVersion", "0.12.0svn\0"
+            VALUE "ProductVersion", "0.13.0svn\0"
         END
     END
     BLOCK "VarFileInfo"

Modified: scummvm/branches/gsoc2008-rtl/dists/slackware/scummvm.SlackBuild
===================================================================
--- scummvm/branches/gsoc2008-rtl/dists/slackware/scummvm.SlackBuild	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/dists/slackware/scummvm.SlackBuild	2008-07-21 22:46:39 UTC (rev 33183)
@@ -8,7 +8,7 @@
 fi
 PKG=$TMP/package-scummvm
 
-VERSION=0.12.0svn
+VERSION=0.13.0svn
 ARCH=i486
 BUILD=1
 

Modified: scummvm/branches/gsoc2008-rtl/engines/agos/agos.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/agos/agos.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/agos/agos.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -1076,6 +1076,8 @@
 	virtual void drawImage(VC10_state *state);
 	void drawBackGroundImage(VC10_state *state);
 	void drawVertImage(VC10_state *state);
+	void drawVertImageCompressed(VC10_state *state);
+	void drawVertImageUncompressed(VC10_state *state);
 
 	void setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height);
 

Modified: scummvm/branches/gsoc2008-rtl/engines/agos/gfx.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/agos/gfx.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/agos/gfx.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -744,10 +744,6 @@
 }
 
 void AGOSEngine::drawBackGroundImage(VC10_state *state) {
-	const byte *src;
-	byte *dst;
-	uint h, i;
-
 	state->width = _screenWidth;
 	if (_window3Flag == 1) {
 		state->width = 0;
@@ -755,15 +751,19 @@
 		state->y_skip = 0;
 	}
 
-	src = state->srcPtr + (state->width * state->y_skip) + (state->x_skip * 8);
-	dst = state->surf_addr;
+	const byte* src = state->srcPtr + (state->width * state->y_skip) + (state->x_skip * 8);
+	byte* dst = state->surf_addr;
 
 	state->draw_width *= 2;
 
-	h = state->draw_height;
+	uint h = state->draw_height;
+	const uint w = state->draw_width;
+	const byte paletteMod = state->paletteMod;
 	do {
-		for (i = 0; i != state->draw_width; i++)
-			dst[i] = src[i] + state->paletteMod;
+		for (uint i = 0; i != w; i+=2) {
+			dst[i] = src[i] + paletteMod;
+			dst[i+1] = src[i+1] + paletteMod;
+		}
 		dst += state->surf_pitch;
 		src += state->width;
 	} while (--h);
@@ -771,63 +771,86 @@
 
 void AGOSEngine::drawVertImage(VC10_state *state) {
 	if (state->flags & kDFCompressed) {
-		uint w, h;
-		byte *src, *dst, *dstPtr;
+		drawVertImageCompressed(state);
+	} else {
+		drawVertImageUncompressed(state);
+	}
+}
 
-		state->x_skip *= 4;				/* reached */
+void AGOSEngine::drawVertImageUncompressed(VC10_state *state) {
+	assert ((state->flags & kDFCompressed) == 0) ;
 
-		state->dl = state->width;
-		state->dh = state->height;
+	const byte *src;
+	byte *dst;
+	uint count;
 
-		vc10_skip_cols(state);
+	src = state->srcPtr + (state->width * state->y_skip) * 8;
+	dst = state->surf_addr;
+	state->x_skip *= 4;
 
-		dstPtr = state->surf_addr;
-		if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
-			dstPtr += vcReadVar(252);
+	do {
+		for (count = 0; count != state->draw_width; count++) {
+			byte color;
+			color = (src[count + state->x_skip] / 16) + state->paletteMod;
+			if ((state->flags & kDFNonTrans) || color)
+				dst[count * 2] = color | state->palette;
+			color = (src[count + state->x_skip] & 15) + state->paletteMod;
+			if ((state->flags & kDFNonTrans) || color)
+				dst[count * 2 + 1] = color | state->palette;
 		}
-		w = 0;
-		do {
-			byte color;
+		dst += state->surf_pitch;
+		src += state->width * 8;
+	} while (--state->draw_height);
+}
 
-			src = vc10_depackColumn(state);
-			dst = dstPtr;
+void AGOSEngine::drawVertImageCompressed(VC10_state *state) {
+	assert (state->flags & kDFCompressed) ;
+	uint w, h;
 
-			h = 0;
+	state->x_skip *= 4;				/* reached */
+
+	state->dl = state->width;
+	state->dh = state->height;
+
+	vc10_skip_cols(state);
+
+	byte *dstPtr = state->surf_addr;
+	if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
+		dstPtr += vcReadVar(252);
+	}
+	w = 0;
+	do {
+		byte color;
+
+		const byte *src = vc10_depackColumn(state);
+		byte *dst = dstPtr;
+
+		h = 0;
+		if (state->flags & kDFNonTrans)  {
 			do {
-				color = (*src / 16);
-				if ((state->flags & kDFNonTrans) || color != 0)
+				byte colors = *src;
+				color = (colors / 16);
+				dst[0] = color | state->palette;
+				color = (colors & 15);
+				dst[1] = color | state->palette;
+				dst += state->surf_pitch;
+				src++;
+			} while (++h != state->draw_height);
+		} else {
+			do {
+				byte colors = *src;
+				color = (colors / 16);
+				if (color != 0)
 					dst[0] = color | state->palette;
-				color = (*src & 15);
-				if ((state->flags & kDFNonTrans) || color != 0)
+				color = (colors & 15);
+				if (color != 0)
 					dst[1] = color | state->palette;
 				dst += state->surf_pitch;
 				src++;
 			} while (++h != state->draw_height);
-			dstPtr += 2;
-		} while (++w != state->draw_width);
-	} else {
-		const byte *src;
-		byte *dst;
-		uint count;
-
-		src = state->srcPtr + (state->width * state->y_skip) * 8;
-		dst = state->surf_addr;
-		state->x_skip *= 4;
-
-		do {
-			for (count = 0; count != state->draw_width; count++) {
-				byte color;
-				color = (src[count + state->x_skip] / 16) + state->paletteMod;
-				if ((state->flags & kDFNonTrans) || color)
-					dst[count * 2] = color | state->palette;
-				color = (src[count + state->x_skip] & 15) + state->paletteMod;
-				if ((state->flags & kDFNonTrans) || color)
-					dst[count * 2 + 1] = color | state->palette;
-			}
-			dst += state->surf_pitch;
-			src += state->width * 8;
-		} while (--state->draw_height);
-	}
+		}
+		dstPtr += 2;
+	} while (++w != state->draw_width);
 }
 
 void AGOSEngine::drawImage(VC10_state *state) {

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/cine.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/cine.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/cine.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -94,6 +94,7 @@
 
 	Common::StringList _volumeResourceFiles;
 	StringPtrHashMap _volumeEntriesMap;
+	TextHandler _textHandler;
 
 private:
 	void initialize(void);
@@ -107,6 +108,7 @@
 extern CineEngine *g_cine;
 
 #define BOOT_PRC_NAME "AUTO00.PRC"
+#define COPY_PROT_FAIL_PRC_NAME "L201.ANI"
 
 enum {
 	VAR_MOUSE_X_MODE = 253,

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/gfx.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/gfx.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/gfx.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -337,7 +337,7 @@
 		x += 5;
 	} else if ((width = fontParamTable[(unsigned char)character].characterWidth)) {
 		idx = fontParamTable[(unsigned char)character].characterIdx;
-		drawSpriteRaw(textTable[idx][0], textTable[idx][1], 16, 8, _backBuffer, x, y);
+		drawSpriteRaw(g_cine->_textHandler.textTable[idx][0], g_cine->_textHandler.textTable[idx][1], 16, 8, _backBuffer, x, y);
 		x += width + 1;
 	}
 
@@ -938,7 +938,7 @@
 		x += 5;
 	} else if ((width = fontParamTable[(unsigned char)character].characterWidth)) {
 		idx = fontParamTable[(unsigned char)character].characterIdx;
-		drawSpriteRaw2(textTable[idx][0], 0, 16, 8, _backBuffer, x, y);
+		drawSpriteRaw2(g_cine->_textHandler.textTable[idx][0], 0, 16, 8, _backBuffer, x, y);
 		x += width + 1;
 	}
 

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/prc.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/prc.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/prc.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -41,8 +41,9 @@
 
 /*! \todo Is script size of 0 valid?
  * \todo Fix script dump code
+ * @return Was the loading successful?
  */
-void loadPrc(const char *pPrcName) {
+bool loadPrc(const char *pPrcName) {
 	byte i;
 	uint16 numScripts;
 	byte *scriptPtr, *dataPtr;
@@ -53,11 +54,11 @@
 	scriptTable.clear();
 
 	// This is copy protection. Used to hang the machine
-	if (!scumm_stricmp(pPrcName, "L201.ANI")) {
+	if (!scumm_stricmp(pPrcName, COPY_PROT_FAIL_PRC_NAME)) {
 		Common::Event event;
 		event.type = Common::EVENT_RTL;
 		g_system->getEventManager()->pushEvent(event);
-		return;
+		return false;
 	}
 
 	checkDataDisk(-1);
@@ -110,6 +111,8 @@
 		}
 	}
 #endif
+
+	return true;
 }
 
 } // End of namespace Cine

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/prc.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/prc.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/prc.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -31,7 +31,7 @@
 extern ScriptList globalScripts;
 extern ScriptList objectScripts;
 
-void loadPrc(const char *pPrcName);
+bool loadPrc(const char *pPrcName);
 
 } // End of namespace Cine
 

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/script_fw.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/script_fw.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/script_fw.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -1019,6 +1019,20 @@
 }
 
 int FWScript::o1_compareVar() {
+	// WORKAROUND: A workaround for a script bug in script file CODE2.PRC
+	// in at least some of the Amiga and Atari ST versions of Future Wars.
+	// Fixes bug #2016647 (FW: crash with italian amiga version). A local
+	// variable 251 is compared against value 0 although it's quite apparent
+	// from the context in the script that instead global variable 251 should
+	// be compared against value 0. So looks like someone made a typo when
+	// making the scripts. Therefore we change that particular comparison
+	// from using the local variable 251 to using the global variable 251.
+	if (g_cine->getGameType() == Cine::GType_FW && scumm_stricmp(currentPrcName, "CODE2.PRC") == 0 &&
+		(g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) &&
+		_script.getByte(_pos) == 251 && _script.getByte(_pos + 1) == 0 && _script.getWord(_pos + 2) == 0) {
+		return o1_compareGlobalVar();
+	}
+
 	byte varIdx = getNextByte();
 	byte varType = getNextByte();
 

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/texte.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/texte.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/texte.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -31,8 +31,6 @@
 
 byte *textDataPtr;
 
-byte textTable[256][2][16 * 8];
-
 const char **failureMessages;
 const CommandeType *defaultActionCommand;
 const CommandeType *systemMenu;
@@ -77,14 +75,14 @@
 		loadRelatedPalette(pFileName);
 
 		for (i = 0; i < numCharacters; i++) {
-			gfxConvertSpriteToRaw(textTable[i][0], tempBuffer, 16, 8);
-			generateMask(textTable[i][0], textTable[i][1], 16 * 8, 0);
+			gfxConvertSpriteToRaw(g_cine->_textHandler.textTable[i][0], tempBuffer, 16, 8);
+			generateMask(g_cine->_textHandler.textTable[i][0], g_cine->_textHandler.textTable[i][1], 16 * 8, 0);
 			tempBuffer += dataSize;
 		}
 	} else {
 		for (i = 0; i < 90; i++) {
-			gfxConvertSpriteToRaw(textTable[i][0], tempBuffer, 8, 8);
-			generateMask(textTable[i][0], textTable[i][1], 8 * 8, 0);
+			gfxConvertSpriteToRaw(g_cine->_textHandler.textTable[i][0], tempBuffer, 8, 8);
+			generateMask(g_cine->_textHandler.textTable[i][0], g_cine->_textHandler.textTable[i][1], 8 * 8, 0);
 			tempBuffer += 0x40;
 		}
 	}

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/texte.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/texte.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/texte.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -34,8 +34,11 @@
 typedef char CommandeType[20];
 
 extern byte *textDataPtr;
-extern byte textTable[256][2][16 * 8];
 
+struct TextHandler {
+	byte textTable[256][2][16 * 8];
+};
+
 extern const char **failureMessages;
 extern const CommandeType *defaultActionCommand;
 extern const CommandeType *systemMenu;

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/various.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/various.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/various.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -464,17 +464,26 @@
 
 	broken = brokenSave(*fHandle);
 
+	// At savefile position 0x0000:
 	currentDisk = fHandle->readUint16BE();
 
+	// At 0x0002:
 	fHandle->read(currentPartName, 13);
+	// At 0x000F:
 	fHandle->read(currentDatName, 13);
 
+	// At 0x001C:
 	saveVar2 = fHandle->readSint16BE();
 
+	// At 0x001E:
 	fHandle->read(currentPrcName, 13);
+	// At 0x002B:
 	fHandle->read(currentRelName, 13);
+	// At 0x0038:
 	fHandle->read(currentMsgName, 13);
+	// At 0x0045:
 	fHandle->read(bgName, 13);
+	// At 0x0052:
 	fHandle->read(currentCtName, 13);
 
 	checkDataDisk(currentDisk);
@@ -499,52 +508,84 @@
 		loadCtFW(currentCtName);
 	}
 
+	// At 0x005F:
 	fHandle->readUint16BE();
+	// At 0x0061:
 	fHandle->readUint16BE();
 
+	// At 0x0063:
 	for (i = 0; i < 255; i++) {
+		// At 0x0063 + i * 32 + 0:
 		objectTable[i].x = fHandle->readSint16BE();
+		// At 0x0063 + i * 32 + 2:
 		objectTable[i].y = fHandle->readSint16BE();
+		// At 0x0063 + i * 32 + 4:
 		objectTable[i].mask = fHandle->readUint16BE();
+		// At 0x0063 + i * 32 + 6:
 		objectTable[i].frame = fHandle->readSint16BE();
+		// At 0x0063 + i * 32 + 8:
 		objectTable[i].costume = fHandle->readSint16BE();
+		// At 0x0063 + i * 32 + 10:
 		fHandle->read(objectTable[i].name, 20);
+		// At 0x0063 + i * 32 + 30:
 		objectTable[i].part = fHandle->readUint16BE();
 	}
 
+	// At 0x2043 (i.e. 0x0063 + 255 * 32):
 	renderer->restorePalette(*fHandle);
 
+	// At 0x2083 (i.e. 0x2043 + 16 * 2 * 2):
 	globalVars.load(*fHandle, NUM_MAX_VAR - 1);
 
+	// At 0x2281 (i.e. 0x2083 + 255 * 2):
 	for (i = 0; i < 16; i++) {
+		// At 0x2281 + i * 2:
 		zoneData[i] = fHandle->readUint16BE();
 	}
 
+	// At 0x22A1 (i.e. 0x2281 + 16 * 2):
 	for (i = 0; i < 4; i++) {
+		// At 0x22A1 + i * 2:
 		commandVar3[i] = fHandle->readUint16BE();
 	}
 
+	// At 0x22A9 (i.e. 0x22A1 + 4 * 2):
 	fHandle->read(commandBuffer, 0x50);
 	renderer->setCommand(commandBuffer);
 
+	// At 0x22F9 (i.e. 0x22A9 + 0x50):
 	renderer->_cmdY = fHandle->readUint16BE();
 
+	// At 0x22FB:
 	bgVar0 = fHandle->readUint16BE();
+	// At 0x22FD:
 	allowPlayerInput = fHandle->readUint16BE();
+	// At 0x22FF:
 	playerCommand = fHandle->readSint16BE();
+	// At 0x2301:
 	commandVar1 = fHandle->readSint16BE();
+	// At 0x2303:
 	isDrawCommandEnabled = fHandle->readUint16BE();
+	// At 0x2305:
 	var5 = fHandle->readUint16BE();
+	// At 0x2307:
 	var4 = fHandle->readUint16BE();
+	// At 0x2309:
 	var3 = fHandle->readUint16BE();
+	// At 0x230B:
 	var2 = fHandle->readUint16BE();
+	// At 0x230D:
 	commandVar2 = fHandle->readSint16BE();
 
+	// At 0x230F:
 	renderer->_messageBg = fHandle->readUint16BE();
 
+	// At 0x2311:
 	fHandle->readUint16BE();
+	// At 0x2313:
 	fHandle->readUint16BE();
 
+	// At 0x2315:
 	loadResourcesFromSave(*fHandle, broken);
 
 	// TODO: handle screen params (really required ?)
@@ -1516,12 +1557,22 @@
 
 void checkForPendingDataLoad(void) {
 	if (newPrcName[0] != 0) {
-		loadPrc(newPrcName);
+		bool loadPrcOk = loadPrc(newPrcName);
 
 		strcpy(currentPrcName, newPrcName);
 		strcpy(newPrcName, "");
 
-		addScriptToList0(1);
+		// Check that the loading of the script file was successful before
+		// trying to add script 1 from it to the global scripts list. This
+		// fixes a crash when failing copy protection in Amiga or Atari ST
+		// versions of Future Wars.
+		if (loadPrcOk) {
+			addScriptToList0(1);
+		} else if (scumm_stricmp(currentPrcName, COPY_PROT_FAIL_PRC_NAME)) {
+			// We only show an error here for other files than the file that
+			// is loaded if copy protection fails (i.e. L201.ANI).
+			warning("checkForPendingDataLoad: loadPrc(%s) failed", currentPrcName);
+		}
 	}
 
 	if (newRelName[0] != 0) {

Modified: scummvm/branches/gsoc2008-rtl/engines/kyra/kyra_v1.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/kyra/kyra_v1.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/kyra/kyra_v1.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -112,7 +112,7 @@
 				_sound = new SoundTownsPC98_v2(this, _mixer);
 		} else if (_flags.platform == Common::kPlatformPC98) {
 			if (_flags.gameID == GI_KYRA1)
-				_sound = new SoundPC98(this, _mixer);
+				_sound = new SoundTowns/*SoundPC98*/(this, _mixer);
 			else
 				_sound = new SoundTownsPC98_v2(this, _mixer);
 		} else if (midiDriver == MD_ADLIB) {

Modified: scummvm/branches/gsoc2008-rtl/engines/kyra/sound_towns.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/kyra/sound_towns.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/kyra/sound_towns.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -2363,7 +2363,7 @@
 	_numSSG(type == OD_TOWNS ? 0 : 3), _hasADPCM(type == OD_TYPE86 ? true : false),
 	_numChan(type == OD_TYPE26 ? 3 : 6), _hasStereo(type == OD_TYPE26 ? false : true) {	
 	setTempo(84);
-	_baserate = (3579545.0 / (double)getRate()) / 144.0;
+	_baserate = (double)getRate() / 10368.0;
 }
 
 TownsPC98_OpnDriver::~TownsPC98_OpnDriver() {
@@ -3095,8 +3095,8 @@
 }
 
 bool SoundTownsPC98_v2::init() {
-	_driver = new TownsPC98_OpnDriver(_mixer, _vm->gameFlags().platform == Common::kPlatformPC98 ?
-		TownsPC98_OpnDriver::OD_TYPE86 : TownsPC98_OpnDriver::OD_TOWNS);
+	_driver = new TownsPC98_OpnDriver(_mixer, /*_vm->gameFlags().platform == Common::kPlatformPC98 ?
+		TownsPC98_OpnDriver::OD_TYPE86 :*/ TownsPC98_OpnDriver::OD_TOWNS);
 	_useFmSfx = _vm->gameFlags().platform == Common::kPlatformPC98 ? true : false;
 	_vm->checkCD();
 	// FIXME: While checking for 'track1.XXX(X)' looks like

Modified: scummvm/branches/gsoc2008-rtl/engines/kyra/staticres.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/kyra/staticres.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/kyra/staticres.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -1034,8 +1034,10 @@
 	}
 
 	// audio data tables
+#if 0
 	static const char *tIntro98[] = { "intro%d.dat" };
 	static const char *tIngame98[] = { "kyram%d.dat" };
+#endif
 
 	static const AudioDataStruct soundData_PC[] = {
 		{ _soundFilesIntro, _soundFilesIntroSize, 0, 0 },
@@ -1049,18 +1051,20 @@
 		{ 0, 0, 0, 0}
 	};
 
+#if 0
 	static const AudioDataStruct soundData_PC98[] = {
 		{ tIntro98, 1, 0, 0 },
 		{ tIngame98, 1, 0, 0 },
 		{ 0, 0, 0, 0}
 	};
+#endif
 
 	if (_flags.platform == Common::kPlatformPC)
 		_soundData = soundData_PC;
 	else if (_flags.platform == Common::kPlatformFMTowns)
 		_soundData = soundData_TOWNS;
 	else if (_flags.platform == Common::kPlatformPC98)
-		_soundData = soundData_PC98;
+		_soundData = soundData_TOWNS/*soundData_PC98*/;
 
 }
 
@@ -1259,9 +1263,11 @@
 	static const char *fmtMusicFileListFinale[] = { "finale%d.twn" };
 	static const char *fmtMusicFileListIngame[] = { "km%02d.twn" };
 
+#if 0
 	static const char *pc98MusicFileListIntro[] = { "intro%d.86" };
 	static const char *pc98MusicFileListFinale[] = { "finale%d.86" };
 	static const char *pc98MusicFileListIngame[] = { "km%02d.86" };
+#endif
 
 	static const AudioDataStruct soundData_PC[] = {
 		{ _musicFileListIntro, _musicFileListIntroSize, 0, 0 },
@@ -1275,18 +1281,20 @@
 		{ fmtMusicFileListFinale, 1, _cdaTrackTableFinale, _cdaTrackTableFinaleSize >> 1 }
 	};
 
+#if 0
 	static const AudioDataStruct soundData_PC98[] = {
 		{ pc98MusicFileListIntro, 1, 0, 0 },
 		{ pc98MusicFileListIngame, 1, 0, 0 },
 		{ pc98MusicFileListFinale, 1, 0, 0 }		
 	};
+#endif
 
 	if (_flags.platform == Common::kPlatformPC)
 		_soundData = soundData_PC;
 	else if (_flags.platform == Common::kPlatformFMTowns)
 		_soundData = soundData_TOWNS;
 	else if (_flags.platform == Common::kPlatformPC98)
-		_soundData = soundData_PC98;
+		_soundData = soundData_TOWNS/*soundData_PC98*/;
 
 	// setup sequence data
 	_sequences = _staticres->loadHofSequenceData(k2SeqplaySeqData, tmpSize);

Modified: scummvm/branches/gsoc2008-rtl/engines/lure/luredefs.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/lure/luredefs.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/lure/luredefs.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -36,7 +36,7 @@
 #define LURE_DAT_MAJOR 1
 #define LURE_DAT_MINOR 29
 #define LURE_MIN_SAVEGAME_MINOR 25
-#define LURE_SAVEGAME_MINOR 32
+#define LURE_SAVEGAME_MINOR 33
 
 #define LURE_DEBUG 1
 

Modified: scummvm/branches/gsoc2008-rtl/engines/lure/res_struct.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/lure/res_struct.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/lure/res_struct.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -456,6 +456,8 @@
 	stream->writeSint16LE(startY);
 	stream->writeUint16LE(roomNumber);
 	stream->writeByte(layer);
+	stream->writeUint16LE(walkX);
+	stream->writeUint16LE(walkY);
 
 	stream->writeUint16LE(width);
 	stream->writeUint16LE(height);
@@ -503,6 +505,10 @@
 	uint8 saveVersion = LureEngine::getReference().saveVersion();
 	if (saveVersion >= 29)
 		layer = stream->readByte();
+	if (saveVersion >= 33) {
+		walkX = stream->readUint16LE();
+		walkY = stream->readUint16LE();
+	}
 
 	width = stream->readUint16LE();
 	height = stream->readUint16LE();

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/callables_ns.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/callables_ns.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/callables_ns.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -424,6 +424,7 @@
 	}
 	_inTestResult = true;
 
+	_gfx->freeLabels();
 	_gfx->updateScreen();
 
 	_disk->selectArchive("disk1");

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/dialogue.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/dialogue.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/dialogue.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -42,13 +42,23 @@
 #define ANSWER_CHARACTER_X			10
 #define ANSWER_CHARACTER_Y			80
 
+
 class DialogueManager {
 
+	enum {
+		RUN_QUESTION,
+		RUN_ANSWER,
+		NEXT_QUESTION,
+		NEXT_ANSWER,
+		DIALOGUE_OVER
+	} _state;
+
 	Parallaction	*_vm;
-	SpeakData		*_data;
 	Dialogue		*_dialogue;
 
 	bool			_askPassword;
+	int				_passwordLen;
+	bool			_passwordChanged;
 
 	bool			isNpc;
 	GfxObj			*_questioner;
@@ -59,93 +69,70 @@
 	uint16			_visAnswers[5];
 	int			_numVisAnswers;
 
+	int			_answerId;
+
+	int		_selection, _oldSelection;
+
+	uint32			_mouseButtons;
+	Common::Point	_mousePos;
+	bool			_isKeyDown;
+	uint16			_downKey;
+
+
 public:
-	DialogueManager(Parallaction *vm, SpeakData *data) : _vm(vm), _data(data) {
-		_dialogue = _data->_dialogue;
-		isNpc = scumm_stricmp(_data->_name, "yourself") && _data->_name[0] != '\0';
-		_questioner = isNpc ? _vm->_disk->loadTalk(_data->_name) : _vm->_char._talk;
-		_answerer = _vm->_char._talk;
-	}
+	DialogueManager(Parallaction *vm, ZonePtr z);
+	~DialogueManager();
 
-	~DialogueManager() {
-		if (isNpc) {
-			delete _questioner;
-		}
+	bool isOver() {
+		return _state == DIALOGUE_OVER;
 	}
-
 	void run();
 
+	ZonePtr			_z;
+	CommandList *_cmdList;
+
 protected:
-	void displayQuestion();
+	bool displayQuestion();
 	bool displayAnswers();
 	bool displayAnswer(uint16 i);
 
-	uint16 getAnswer();
-	int16 selectAnswer();
-	uint16 askPassword();
+	int16 selectAnswer1();
+	int16 selectAnswerN();
+	int16 askPassword();
 	int16 getHoverAnswer(int16 x, int16 y);
 
+	void runQuestion();
+	void runAnswer();
+	void nextQuestion();
+	void nextAnswer();
+
+	bool checkPassword();
+	void resetPassword();
+	void accumPassword(uint16 ascii);
 };
 
-uint16 DialogueManager::askPassword() {
-	debugC(3, kDebugExec, "checkDialoguePassword()");
+DialogueManager::DialogueManager(Parallaction *vm, ZonePtr z) : _vm(vm), _z(z) {
+	_dialogue = _z->u.speak->_dialogue;
+	isNpc = scumm_stricmp(_z->u.speak->_name, "yourself") && _z->u.speak->_name[0] != '\0';
+	_questioner = isNpc ? _vm->_disk->loadTalk(_z->u.speak->_name) : _vm->_char._talk;
+	_answerer = _vm->_char._talk;
 
-	uint16 passwordLen = 0;
-	_password[0] = '\0';
+	_askPassword = false;
+	_q = _dialogue->_questions[0];
 
-	_vm->_balloonMan->setDialogueBalloon(_q->_answers[0]->_text, 1, 3);
-	int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
-	_vm->_gfx->setItemFrame(id, 0);
+	_cmdList = 0;
+	_answerId = 0;
 
-	Common::Event e;
-	bool changed = true;	// force first refresh
+	_state = displayQuestion() ? RUN_QUESTION : NEXT_ANSWER;
+}
 
-	while (true) {
-		e.kbd.ascii = 0;
-
-		if (g_system->getEventManager()->pollEvent(e)) {
-			if ((e.type == Common::EVENT_KEYDOWN) && isdigit(e.kbd.ascii)) {
-				_password[passwordLen] = e.kbd.ascii;
-				passwordLen++;
-				_password[passwordLen] = '\0';
-				changed = true;
-			}
-		}
-
-		if (changed) {
-			_vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 3);
-			_vm->_gfx->updateScreen();
-			changed = false;
-		}
-
-		if ((passwordLen == MAX_PASSWORD_LENGTH) || (e.kbd.ascii == Common::KEYCODE_RETURN)) {
-
-			if ((!scumm_stricmp(_vm->_char.getBaseName(), _doughName) && !scumm_strnicmp(_password, "1732461", 7)) ||
-			   (!scumm_stricmp(_vm->_char.getBaseName(), _donnaName) && !scumm_strnicmp(_password, "1622", 4)) ||
-			   (!scumm_stricmp(_vm->_char.getBaseName(), _dinoName) && !scumm_strnicmp(_password, "179", 3))) {
-
-				break;
-
-			} else {
-				passwordLen = 0;
-				_password[0] = '\0';
-				changed = true;
-			}
-
-		}
-
-		g_system->delayMillis(20);
-
+DialogueManager::~DialogueManager() {
+	if (isNpc) {
+		delete _questioner;
 	}
-
-	_vm->hideDialogueStuff();
-
-	return 0;
-
+	_z = nullZonePtr;
 }
 
-
-
 bool DialogueManager::displayAnswer(uint16 i) {
 
 	Answer *a = _q->_answers[i];
@@ -161,7 +148,7 @@
 		assert(id >= 0);
 		_visAnswers[id] = i;
 
-		_askPassword = (strstr(a->_text, "%p") != NULL);
+		_askPassword = (strstr(a->_text, "%P") != NULL);
 		_numVisAnswers++;
 
 		return true;
@@ -178,135 +165,245 @@
 		displayAnswer(i);
 	}
 
+	if (_askPassword) {
+		resetPassword();
+//		_vm->_balloonMan->setDialogueBalloon(_q->_answers[0]->_text, 1, 3);
+		int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
+		_vm->_gfx->setItemFrame(id, 0);
+	} else
+	if (_numVisAnswers == 1) {
+		int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
+		_vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF);
+		_vm->_balloonMan->setBalloonText(0, _q->_answers[_visAnswers[0]]->_text, 0);
+	} else
+	if (_numVisAnswers > 1) {
+		int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
+		_vm->_gfx->setItemFrame(id, _q->_answers[_visAnswers[0]]->_mood & 0xF);
+		_oldSelection = -1;
+		_selection = 0;
+	}
+
 	return _numVisAnswers > 0;
 }
 
-void DialogueManager::displayQuestion() {
+bool DialogueManager::displayQuestion() {
+	if (!scumm_stricmp(_q->_text, "NULL")) return false;
 
-	if (!scumm_stricmp(_q->_text, "NULL")) return;
-
 	_vm->_balloonMan->setSingleBalloon(_q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, _q->_mood & 0x10, 0);
 	int id = _vm->_gfx->setItem(_questioner, QUESTION_CHARACTER_X, QUESTION_CHARACTER_Y);
 	_vm->_gfx->setItemFrame(id, _q->_mood & 0xF);
 
-	_vm->_gfx->updateScreen();
-	_vm->_input->waitUntilLeftClick();
-	_vm->hideDialogueStuff();
+	return true;
+}
 
-	return;
+
+bool DialogueManager::checkPassword() {
+	return ((!scumm_stricmp(_vm->_char.getBaseName(), _doughName) && !scumm_strnicmp(_password, "1732461", 7)) ||
+		   (!scumm_stricmp(_vm->_char.getBaseName(), _donnaName) && !scumm_strnicmp(_password, "1622", 4)) ||
+		   (!scumm_stricmp(_vm->_char.getBaseName(), _dinoName) && !scumm_strnicmp(_password, "179", 3)));
 }
 
-uint16 DialogueManager::getAnswer() {
+void DialogueManager::resetPassword() {
+	_passwordLen = 0;
+	_password[0] = '\0';
+	_passwordChanged = true;
+}
 
-	uint16 answer = 0;
+void DialogueManager::accumPassword(uint16 ascii) {
+	if (!isdigit(ascii)) {
+		return;
+	}
 
-	if (_askPassword == false) {
-		answer = selectAnswer();
-	} else {
-		answer = askPassword();
+	_password[_passwordLen] = ascii;
+	_passwordLen++;
+	_password[_passwordLen] = '\0';
+	_passwordChanged = true;
+}
+
+int16 DialogueManager::askPassword() {
+
+	if (_isKeyDown) {
+		accumPassword(_downKey);
 	}
 
-	debugC(3, kDebugExec, "runDialogue: user selected answer #%i", answer);
+	if (_passwordChanged) {
+		_vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 3);
+		_passwordChanged = false;
+	}
 
-	return answer;
+	if ((_passwordLen == MAX_PASSWORD_LENGTH) || ((_isKeyDown) && (_downKey == Common::KEYCODE_RETURN))) {
+		if (checkPassword()) {
+			return 0;
+		} else {
+			resetPassword();
+		}
+	}
+
+	return -1;
 }
 
-void DialogueManager::run() {
+int16 DialogueManager::selectAnswer1() {
 
-	_askPassword = false;
-	CommandList *cmdlist = NULL;
+	if (_mouseButtons == kMouseLeftUp) {
+		return 0;
+	}
 
-	_q = _dialogue->_questions[0];
-	int16 answer;
+	return -1;
+}
 
-	while (_q) {
+int16 DialogueManager::selectAnswerN() {
 
-		answer = 0;
+	_selection = _vm->_balloonMan->hitTestDialogueBalloon(_mousePos.x, _mousePos.y);
 
-		displayQuestion();
+	if (_selection != _oldSelection) {
+		if (_oldSelection != -1) {
+			_vm->_balloonMan->setBalloonText(_oldSelection, _q->_answers[_visAnswers[_oldSelection]]->_text, 3);
+		}
 
 		if (_vm->quit())
-			return;
+			return -1;
 
-		if (_q->_answers[0] == NULL) break;
+		if (_selection != -1) {
+			_vm->_balloonMan->setBalloonText(_selection, _q->_answers[_visAnswers[_selection]]->_text, 0);
+			_vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[_selection]]->_mood & 0xF);
+		}
+	}
 
-		if (scumm_stricmp(_q->_answers[0]->_text, "NULL")) {
-			if (!displayAnswers()) break;
-			answer = getAnswer();
+	_oldSelection = _selection;
 
-			if (_vm->quit())
-				return;
+	if ((_mouseButtons == kMouseLeftUp) && (_selection != -1)) {
+		return _visAnswers[_selection];
+	}
 
-			cmdlist = &_q->_answers[answer]->_commands;
-		}
+	return -1;
+}
 
-		_q = _q->_answers[answer]->_following._question;
+void DialogueManager::runQuestion() {
+	debugC(9, kDebugDialogue, "runQuestion\n");
+
+	if (_mouseButtons == kMouseLeftUp) {
+		_vm->hideDialogueStuff();
+		_state = NEXT_ANSWER;
 	}
 
-	if (cmdlist)
-		_vm->_cmdExec->run(*cmdlist);
+}
 
+
+void DialogueManager::nextAnswer() {
+	debugC(9, kDebugDialogue, "nextAnswer\n");
+
+	if (_q->_answers[0] == NULL) {
+		_state = DIALOGUE_OVER;
+		return;
+	}
+
+	if (!scumm_stricmp(_q->_answers[0]->_text, "NULL")) {
+		_answerId = 0;
+		_state = NEXT_QUESTION;
+		return;
+	}
+
+	_state = displayAnswers() ? RUN_ANSWER : DIALOGUE_OVER;
 }
 
-int16 DialogueManager::selectAnswer() {
+void DialogueManager::runAnswer() {
+	debugC(9, kDebugDialogue, "runAnswer\n");
 
-	int16 numAvailableAnswers = _numVisAnswers;
+	if (_askPassword) {
+		_answerId = askPassword();
+	} else
+	if (_numVisAnswers == 1) {
+		_answerId = selectAnswer1();
+	} else {
+		_answerId = selectAnswerN();
+	}
 
-	int id = _vm->_gfx->setItem(_answerer, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y);
-	_vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF);
-
-	if (numAvailableAnswers == 1) {
-		_vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 0);
-		_vm->_input->waitUntilLeftClick();
+	if (_answerId != -1) {
+		_cmdList = &_q->_answers[_answerId]->_commands;
 		_vm->hideDialogueStuff();
-		return 0;
+		_state = NEXT_QUESTION;
 	}
+}
 
-	int oldSelection = -1;
-	int selection = 0;
+void DialogueManager::nextQuestion() {
+	debugC(9, kDebugDialogue, "nextQuestion\n");
 
-	uint32 event;
-	Common::Point p;
-	while (!_vm->quit()) {
-	
-		_vm->_input->readInput();
-		_vm->_input->getCursorPos(p);
-		event = _vm->_input->getLastButtonEvent();
-		selection = _vm->_balloonMan->hitTestDialogueBalloon(p.x, p.y);
+	_q = _q->_answers[_answerId]->_following._question;
+	if (_q == 0) {
+		_state = DIALOGUE_OVER;
+	} else {
+		_state = displayQuestion() ? RUN_QUESTION : NEXT_ANSWER;
+	}
+}
 
-		if (selection != oldSelection) {
-			if (oldSelection != -1) {
-				_vm->_balloonMan->setBalloonText(oldSelection, _q->_answers[_visAnswers[oldSelection]]->_text, 3);
-			}
+void DialogueManager::run() {
 
-			if (selection != -1) {
-				_vm->_balloonMan->setBalloonText(selection, _q->_answers[_visAnswers[selection]]->_text, 0);
-				_vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[selection]]->_mood & 0xF);
-			}
-		}
+	// cache event data
+	_mouseButtons = _vm->_input->getLastButtonEvent();
+	_vm->_input->getCursorPos(_mousePos);
+	_isKeyDown = _vm->_input->getLastKeyDown(_downKey);
 
-		if ((selection != -1) && (event == kMouseLeftUp)) {
-			break;
+	switch (_state) {
+	case RUN_QUESTION:
+		runQuestion();
+		break;
+
+	case NEXT_ANSWER:
+		nextAnswer();
+		break;
+
+	case NEXT_QUESTION:
+		nextQuestion();
+		break;
+
+	case RUN_ANSWER:
+		runAnswer();
+		break;
+
+	case DIALOGUE_OVER:
+		if (_cmdList) {
+			_vm->_cmdExec->run(*_cmdList);
 		}
+		break;
 
-		_vm->_gfx->updateScreen();
-		g_system->delayMillis(20);
+	default:
+		error("unknown state in DialogueManager");
 
-		oldSelection = selection;
 	}
 
-	_vm->hideDialogueStuff();
+}
 
-	return _visAnswers[selection];
+void Parallaction::enterDialogueMode(ZonePtr z) {
+	debugC(1, kDebugDialogue, "Parallaction::enterDialogueMode(%s)", z->u.speak->_name);
+	_dialogueMan = new DialogueManager(this, z);
+	_input->_inputMode = Input::kInputModeDialogue;
 }
 
+void Parallaction::exitDialogueMode() {
+	debugC(1, kDebugDialogue, "Parallaction::exitDialogueMode()");
+	_input->_inputMode = Input::kInputModeGame;
 
-void Parallaction::runDialogue(SpeakData *data) {
-	debugC(1, kDebugExec, "runDialogue: starting dialogue '%s'", data->_name);
+	// The current instance of _dialogueMan must be destroyed before the zone commands
+	// are executed, because they may create another instance of _dialogueMan that
+	// overwrite the current one. This would cause headaches (and it did, actually).
+	ZonePtr z = _dialogueMan->_z;
+	delete _dialogueMan;
+	_dialogueMan = 0;
 
-	DialogueManager man(this, data);
-	man.run();
+	_cmdExec->run(z->_commands, z);
+}
 
+void Parallaction::runDialogueFrame() {
+	if (_input->_inputMode != Input::kInputModeDialogue) {
+		return;
+	}
+
+	_dialogueMan->run();
+
+	if (_dialogueMan->isOver()) {
+		exitDialogueMode();
+	}
+
 	return;
 }
 

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/exec_ns.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/exec_ns.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/exec_ns.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -224,7 +224,11 @@
 
 
 DECLARE_COMMAND_OPCODE(speak) {
-	_vm->_activeZone = _ctxt.cmd->u._zone;
+	if ((_ctxt.cmd->u._zone->_type & 0xFFFF) == kZoneSpeak) {
+		_vm->enterDialogueMode(_ctxt.cmd->u._zone);
+	} else {
+		_vm->_activeZone = _ctxt.cmd->u._zone;
+	}
 }
 
 
@@ -322,6 +326,7 @@
 
 
 void Parallaction_ns::drawAnimations() {
+	debugC(9, kDebugExec, "Parallaction_ns::drawAnimations()\n");
 
 	uint16 layer = 0;
 
@@ -362,6 +367,8 @@
 		}
 	}
 
+	debugC(9, kDebugExec, "Parallaction_ns::drawAnimations done()\n");
+
 	return;
 }
 
@@ -417,7 +424,6 @@
 	return;
 }
 
-
 void CommandExec::run(CommandList& list, ZonePtr z) {
 	if (list.size() == 0) {
 		debugC(3, kDebugExec, "runCommands: nothing to do");
@@ -542,11 +548,8 @@
 		break;
 
 	case kZoneSpeak:
-		runDialogue(z->u.speak);
-		if (_vm->quit())
-			return 0;
-		break;
-
+		enterDialogueMode(z);
+		return 0;
 	}
 
 	debugC(3, kDebugExec, "runZone completed");

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/gfxbase.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/gfxbase.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/gfxbase.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -267,9 +267,6 @@
 }
 
 
-// this is the maximum size of an unpacked frame in BRA
-byte _unpackedBitmap[640*401];
-
 #if 0
 void Gfx::unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, byte transparentColor) {
 

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/graphics.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/graphics.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/graphics.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -33,6 +33,11 @@
 
 namespace Parallaction {
 
+// this is the size of the receiving buffer for unpacked frames,
+// since BRA uses some insanely big animations.
+#define MAXIMUM_UNPACKED_BITMAP_SIZE	640*401
+
+
 void Gfx::registerVar(const Common::String &name, int32 initialValue) {
 	if (_vars.contains(name)) {
 		warning("Variable '%s' already registered, ignoring initial value.\n", name.c_str());
@@ -752,6 +757,9 @@
 	_halfbrite = false;
 	_hbCircleRadius = 0;
 
+	_unpackedBitmap = new byte[MAXIMUM_UNPACKED_BITMAP_SIZE];
+	assert(_unpackedBitmap);
+
 	registerVar("background_mode", 1);
 	_varBackgroundMode = 1;
 
@@ -769,6 +777,8 @@
 	freeBackground();
 	freeLabels();
 
+	delete []_unpackedBitmap;
+
 	return;
 }
 

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/graphics.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/graphics.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/graphics.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -547,6 +547,8 @@
 	uint				_screenX;		// scrolling position
 	uint				_screenY;
 
+	byte				*_unpackedBitmap;
+
 protected:
 	Parallaction*		_vm;
 	bool				_halfbrite;

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/input.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/input.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/input.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -42,12 +42,14 @@
 	uint16 KeyDown = 0;
 
 	_mouseButtons = kMouseNone;
+	_lastKeyDownAscii = -1;
 
 	Common::EventManager *eventMan = _vm->_system->getEventManager();
 	while (eventMan->pollEvent(e)) {
 
 		switch (e.type) {
 		case Common::EVENT_KEYDOWN:
+			_lastKeyDownAscii = e.kbd.ascii;
 			if (e.kbd.flags == Common::KBD_CTRL && e.kbd.keycode == 'd')
 				_vm->_debugger->attach();
 			if (_vm->getFeatures() & GF_DEMO) break;
@@ -97,6 +99,11 @@
 
 }
 
+bool Input::getLastKeyDown(uint16 &ascii) {
+	ascii = _lastKeyDownAscii;
+	return (_lastKeyDownAscii != -1);
+}
+
 // FIXME: see comment for readInput()
 void Input::waitForButtonEvent(uint32 buttonEventMask, int32 timeout) {
 
@@ -192,11 +199,38 @@
 	case kInputModeGame:
 		updateGameInput();
 		break;
+
+	case kInputModeDialogue:
+		readInput();
+		break;
 	}
 
 	return &_inputData;
 }
 
+void Input::trackMouse(ZonePtr z) {
+	if ((z != _hoverZone) && (_hoverZone)) {
+		stopHovering();
+		return;
+	}
+
+	if (!z) {
+		return;
+	}
+
+	if ((!_hoverZone) && ((z->_flags & kFlagsNoName) == 0)) {
+		_hoverZone = z;
+		_vm->_gfx->showFloatingLabel(_hoverZone->_label);
+		return;
+	}
+}
+
+void Input::stopHovering() {
+	_hoverZone = nullZonePtr;
+	_vm->_gfx->hideFloatingLabel();
+}
+
+
 bool Input::translateGameInput() {
 
 	if ((_engineFlags & kEnginePauseJobs) || (_engineFlags & kEngineInventory)) {
@@ -231,24 +265,11 @@
 		return true;
 	}
 
-	if ((z != _hoverZone) && (_hoverZone)) {
-		_hoverZone = nullZonePtr;
-		_inputData._event = kEvExitZone;
-		return true;
-	}
+	trackMouse(z);
+ 	if (!z) {
+ 		return true;
+ 	}
 
-	if (!z) {
-		_inputData._event = kEvNone;
-		return true;
-	}
-
-	if ((!_hoverZone) && ((z->_flags & kFlagsNoName) == 0)) {
-		_hoverZone = z;
-		_inputData._event = kEvEnterZone;
-		_inputData._label = z->_label;
-		return true;
-	}
-
 	if ((_mouseButtons == kMouseLeftUp) && ((_activeItem._id != 0) || ((z->_type & 0xFFFF) == kZoneCommand))) {
 
 		_inputData._zone = z;

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/input.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/input.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/input.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -66,6 +66,7 @@
 
 	Common::Point	_mousePos;
 	uint16	_mouseButtons;
+	int32	_lastKeyDownAscii;
 
 	bool		_mouseHidden;
 	ZonePtr			_hoverZone;
@@ -73,7 +74,8 @@
 public:
 	enum {
 		kInputModeGame = 0,
-		kInputModeComment = 1
+		kInputModeComment = 1,
+		kInputModeDialogue = 2
 	};
 
 
@@ -99,14 +101,13 @@
 
 	uint16	readInput();
 	InputData* 	updateInput();
+	void	trackMouse(ZonePtr z);
 	void 	waitUntilLeftClick();
 	void	waitForButtonEvent(uint32 buttonEventMask, int32 timeout = -1);
 	uint32	getLastButtonEvent() { return _mouseButtons; }
+	bool  	getLastKeyDown(uint16 &ascii);
 
-	void stopHovering() {
-		_hoverZone = nullZonePtr;
-	}
-
+	void stopHovering();
 };
 
 } // namespace Parallaction

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -164,7 +164,12 @@
 }
 
 
+void Parallaction::hideDialogueStuff() {
+	_gfx->freeItems();
+	_balloonMan->freeBalloons();
+}
 
+
 void Parallaction::freeCharacter() {
 	debugC(1, kDebugExec, "freeCharacter()");
 
@@ -297,16 +302,6 @@
 void Parallaction::processInput(InputData *data) {
 
 	switch (data->_event) {
-	case kEvEnterZone:
-		debugC(2, kDebugInput, "processInput: kEvEnterZone");
-		_gfx->showFloatingLabel(data->_label);
-		break;
-
-	case kEvExitZone:
-		debugC(2, kDebugInput, "processInput: kEvExitZone");
-		_gfx->hideFloatingLabel();
-		break;
-
 	case kEvAction:
 		debugC(2, kDebugInput, "processInput: kEvAction");
 		_input->stopHovering();
@@ -317,7 +312,6 @@
 
 	case kEvOpenInventory:
 		_input->stopHovering();
-		_gfx->hideFloatingLabel();
 		if (hitZone(kZoneYou, data->_mousePos.x, data->_mousePos.y) == 0) {
 			setArrowCursor();
 		}
@@ -367,25 +361,29 @@
 void Parallaction::runGame() {
 
 	InputData *data = _input->updateInput();
-	if (data->_event != kEvNone) {
-		processInput(data);
-	}
-
 	if (_vm->quit())
 		return;
 
-	runPendingZones();
+	if (_input->_inputMode == Input::kInputModeDialogue) {
+		runDialogueFrame();
+	} else {
+		if (data->_event != kEvNone) {
+			processInput(data);
+		}
 
-	if (_vm->quit())
-		return;
+		if (_vm->quit())
+			return;
 
-	if (_engineFlags & kEngineChangeLocation) {
-		changeLocation(_location._name);
-	}
+		runPendingZones();
 
 	if (_vm->quit())
 		return;
 
+		if (_engineFlags & kEngineChangeLocation) {
+			changeLocation(_location._name);
+		}
+	}
+
 	_gfx->beginFrame();
 
 	if (_input->_inputMode == Input::kInputModeGame) {
@@ -400,7 +398,6 @@
 
 	// change this to endFrame?
 	updateView();
-
 }
 
 
@@ -668,6 +665,7 @@
 }
 
 void Parallaction::scheduleLocationSwitch(const char *location) {
+	debugC(9, kDebugExec, "scheduleLocationSwitch(%s)\n", location);
 	strcpy(_location._name, location);
 	_engineFlags |= kEngineChangeLocation;
 }

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction.h	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction.h	2008-07-21 22:46:39 UTC (rev 33183)
@@ -113,8 +113,6 @@
 
 enum {
 	kEvNone			= 0,
-	kEvEnterZone		= 1,
-	kEvExitZone		= 2,
 	kEvAction		= 3,
 	kEvOpenInventory	= 4,
 	kEvCloseInventory	= 5,
@@ -164,6 +162,7 @@
 class Gfx;
 class SoundMan;
 class Input;
+class DialogueManager;
 
 struct Location {
 
@@ -281,8 +280,6 @@
 	uint16		runZone(ZonePtr z);
 	void		freeZones();
 
-	void		runDialogue(SpeakData*);
-
 	AnimationPtr findAnimation(const char *name);
 	void		freeAnimations();
 
@@ -425,10 +422,11 @@
 
 	void setupBalloonManager();
 
-	void hideDialogueStuff() {
-		_gfx->freeItems();
-		_balloonMan->freeBalloons();
-	}
+	void hideDialogueStuff();
+	DialogueManager	*_dialogueMan;
+	void enterDialogueMode(ZonePtr z);
+	void exitDialogueMode();
+	void runDialogueFrame();
 
 };
 

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction_br.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction_br.cpp	2008-07-21 21:23:23 UTC (rev 33182)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction_br.cpp	2008-07-21 22:46:39 UTC (rev 33183)
@@ -212,13 +212,21 @@
 	if (_activeZone) {
 		z = _activeZone;	// speak Zone or sound
 		_activeZone = nullZonePtr;
-		runZone(z);			// FIXME: BRA doesn't handle sound yet
+		if ((z->_type & 0xFFFF) == kZoneSpeak) {
+			enterDialogueMode(z);
+		} else {
+			runZone(z);			// FIXME: BRA doesn't handle sound yet
+		}
 	}
 
 	if (_activeZone2) {
 		z = _activeZone2;	// speak Zone or sound
 		_activeZone2 = nullZonePtr;
-		runZone(z);
+		if ((z->_type & 0xFFFF) == kZoneSpeak) {
+			enterDialogueMode(z);
+		} else {
+			runZone(z);			// FIXME: BRA doesn't handle sound yet
+		}
 	}
 }
 

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/parallaction_ns.cpp

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list