[Scummvm-cvs-logs] SF.net SVN: scummvm: [32982] scummvm/branches/gsoc2008-tfmx

marwanhilmi at users.sourceforge.net marwanhilmi at users.sourceforge.net
Thu Jul 10 01:59:05 CEST 2008


Revision: 32982
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32982&view=rev
Author:   marwanhilmi
Date:     2008-07-09 16:59:05 -0700 (Wed, 09 Jul 2008)

Log Message:
-----------
Merged from trunk via svnmerge.

Modified Paths:
--------------
    scummvm/branches/gsoc2008-tfmx/NEWS
    scummvm/branches/gsoc2008-tfmx/backends/platform/dc/Makefile
    scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/dsmain.cpp
    scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/dsmain.h
    scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/osystem_ds.cpp
    scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/osystem_ds.h
    scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/wordcompletion.cpp
    scummvm/branches/gsoc2008-tfmx/backends/platform/psp/Makefile
    scummvm/branches/gsoc2008-tfmx/backends/platform/psp/osys_psp.cpp
    scummvm/branches/gsoc2008-tfmx/backends/platform/psp/osys_psp.h
    scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem.cpp
    scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem.h
    scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem_sfx.cpp
    scummvm/branches/gsoc2008-tfmx/backends/saves/default/default-saves.cpp
    scummvm/branches/gsoc2008-tfmx/configure
    scummvm/branches/gsoc2008-tfmx/dists/msvc7/parallaction.vcproj
    scummvm/branches/gsoc2008-tfmx/dists/msvc71/parallaction.vcproj
    scummvm/branches/gsoc2008-tfmx/dists/msvc8/parallaction.vcproj
    scummvm/branches/gsoc2008-tfmx/dists/msvc9/parallaction.vcproj
    scummvm/branches/gsoc2008-tfmx/engines/cine/gfx.cpp
    scummvm/branches/gsoc2008-tfmx/engines/gob/detection.cpp
    scummvm/branches/gsoc2008-tfmx/engines/gob/goblin_v2.cpp
    scummvm/branches/gsoc2008-tfmx/engines/gob/inter.cpp
    scummvm/branches/gsoc2008-tfmx/engines/kyra/detection.cpp
    scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_mr.cpp
    scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_mr.h
    scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_v1.cpp
    scummvm/branches/gsoc2008-tfmx/engines/kyra/sequences_lok.cpp
    scummvm/branches/gsoc2008-tfmx/engines/kyra/sound.cpp
    scummvm/branches/gsoc2008-tfmx/engines/kyra/sound_lok.cpp
    scummvm/branches/gsoc2008-tfmx/engines/kyra/staticres.cpp
    scummvm/branches/gsoc2008-tfmx/engines/m4/converse.cpp
    scummvm/branches/gsoc2008-tfmx/engines/m4/globals.cpp
    scummvm/branches/gsoc2008-tfmx/engines/m4/globals.h
    scummvm/branches/gsoc2008-tfmx/engines/m4/resource.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/callables_ns.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/dialogue.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk.h
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk_br.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk_ns.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/exec_br.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/exec_ns.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/gfxbase.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/graphics.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/graphics.h
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/gui_br.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/input.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/module.mk
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/objects.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction.h
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction_br.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction_ns.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/parser_br.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/parser_ns.cpp
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/sound.cpp
    scummvm/branches/gsoc2008-tfmx/engines/scumm/imuse_digi/dimuse_track.h
    scummvm/branches/gsoc2008-tfmx/sound/midiparser_smf.cpp
    scummvm/branches/gsoc2008-tfmx/sound/midiparser_xmidi.cpp

Added Paths:
-----------
    scummvm/branches/gsoc2008-tfmx/engines/parallaction/balloons.cpp

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


Property changes on: scummvm/branches/gsoc2008-tfmx
___________________________________________________________________
Name: svnmerge-integrated
   - /scummvm/trunk:1-32878
   + /scummvm/trunk:1-32981

Modified: scummvm/branches/gsoc2008-tfmx/NEWS
===================================================================
--- scummvm/branches/gsoc2008-tfmx/NEWS	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/NEWS	2008-07-09 23:59:05 UTC (rev 32982)
@@ -16,6 +16,7 @@
    - Added CAMD MIDI driver for AmigaOS4.
    - Revived the PS2 port (was already in 0.11.1 but was forgotten in the
      release notes).
+   - Plugged numerous memory leaks in all engines (part of GSoC'08 task)
 
  AGOS:
    - Fixed palette issues in Amiga versions of Simon the Sorcerer 1.

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/dc/Makefile
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/dc/Makefile	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/dc/Makefile	2008-07-09 23:59:05 UTC (rev 32982)
@@ -33,8 +33,33 @@
 DEFINES += -DDYNAMIC_MODULES
 PRE_OBJS_FLAGS = -Wl,--whole-archive
 POST_OBJS_FLAGS = -Wl,--no-whole-archive
+ENABLED=DYNAMIC_PLUGIN
+else
+ENABLED=STATIC_PLUGIN
 endif
 
+ENABLE_SCUMM = $(ENABLED)
+ENABLE_SCUMM_7_8 = $(ENABLED)
+ENABLE_HE = $(ENABLED)
+ENABLE_AGI = $(ENABLED)
+ENABLE_AGOS = $(ENABLED)
+ENABLE_CINE = $(ENABLED)
+ENABLE_CRUISE = $(ENABLED)
+ENABLE_DRASCULA = $(ENABLED)
+ENABLE_GOB = $(ENABLED)
+ENABLE_IGOR = $(ENABLED)
+ENABLE_KYRA = $(ENABLED)
+ENABLE_LURE = $(ENABLED)
+ENABLE_M4 = $(ENABLED)
+ENABLE_MADE = $(ENABLED)
+ENABLE_PARALLACTION = $(ENABLED)
+ENABLE_QUEEN = $(ENABLED)
+ENABLE_SAGA = $(ENABLED)
+ENABLE_SKY = $(ENABLED)
+ENABLE_SWORD1 = $(ENABLED)
+ENABLE_SWORD2 = $(ENABLED)
+ENABLE_TOUCHE = $(ENABLED)
+
 OBJS :=	dcmain.o time.o display.o audio.o input.o selector.o icon.o \
 	label.o vmsave.o softkbd.o dcloader.o cache.o dc-fs.o
 

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/dsmain.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/dsmain.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/dsmain.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -168,7 +168,7 @@
 u8 gameID;
 
 bool snapToBorder = false;
-bool consoleEnable = false;
+bool consoleEnable = true;
 bool gameScreenSwap = false;
 bool isCpuScalerEnabled();
 //#define HEAVY_LOGGING
@@ -899,12 +899,6 @@
 		return BG_GFX + 0x10000;		// 16bit qty!
 }
 
-void setSoundProc(OSystem_DS::SoundProc proc, void* param) {
-//	consolePrintf("Set sound callback");
-	soundCallback = proc;
-	soundParam = param;
-}
-
 // The sound system in ScummVM seems to always return stereo interleaved samples.
 // Here, I'm treating an 11Khz stereo stream as a 22Khz mono stream, which works sorta ok, but is
 // a horrible bodge.  Any advice on how to change the engine to output mono would be greatly
@@ -914,7 +908,8 @@
 	consolePrintf("doSoundCallback...");
 	#endif
 
-	if (soundCallback) {
+	if (OSystem_DS::instance())
+	if (OSystem_DS::instance()->getMixerImpl()) {
 		lastCallbackFrame = frameCount;
 		
 		for (int r = IPC->playingSection; r < IPC->playingSection + 4; r++) {
@@ -923,7 +918,7 @@
 			if (IPC->fillNeeded[chunk]) {
 				IPC->fillNeeded[chunk] = false;
 				DC_FlushAll();
-				soundCallback(soundParam, (byte *) (soundBuffer + ((bufferSamples >> 2) * chunk)), bufferSamples >> 1);
+				OSystem_DS::instance()->getMixerImpl()->mixCallback((byte *) (soundBuffer + ((bufferSamples >> 2) * chunk)), bufferSamples >> 1);
 				IPC->fillNeeded[chunk] = false;
 				DC_FlushAll();
 			}

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/dsmain.h
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/dsmain.h	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/dsmain.h	2008-07-09 23:59:05 UTC (rev 32982)
@@ -88,7 +88,6 @@
 void 	doTimerCallback();												// Call callback function if required
 
 // Sound
-void 	setSoundProc(OSystem_DS::SoundProc proc, void* param);			// Setup a callback function for sound
 void 	doSoundCallback();												// Call function if sound buffers need more data
 void 	playSound(const void* data, u32 length, bool loop, bool adpcm = false, int rate = 22050);		// Start a sound
 void 	stopSound(int channel);

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/osystem_ds.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/osystem_ds.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/osystem_ds.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -67,10 +67,12 @@
 	ConfMan.setInt("autosave_period", 0);
 	ConfMan.setBool("FM_medium_quality", true);
 
-	_mixer = new DSAudioMixer;
-	_timer = new DSTimerManager;
-	DS::setSoundProc(Audio::Mixer::mixCallback, _mixer);
-    DS::setTimerCallback(&OSystem_DS::timerHandler, 10);
+	_mixer = new DSAudioMixer(this);
+	_timer = new DSTimerManager();
+    	DS::setTimerCallback(&OSystem_DS::timerHandler, 10);
+
+	_mixer->setOutputRate(11025 /*DS::getSoundFrequency()*/);
+	_mixer->setReady(true);
     
 	OSystem::initBackend();
 }
@@ -139,7 +141,7 @@
 		green >>= 3;
 		blue >>= 3;
 		
-//		if (r != 255)
+		if (r != 255)
 		{		
 			BG_PALETTE[r] = red | (green << 5) | (blue << 10);
 			if (!DS::getKeyboardEnable()) {

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/osystem_ds.h
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/osystem_ds.h	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/osystem_ds.h	2008-07-09 23:59:05 UTC (rev 32982)
@@ -30,10 +30,13 @@
 #include "gbampsave.h"
 #include "backends/saves/default/default-saves.h"
 #include "backends/timer/default/default-timer.h"
-#include "sound/mixer.h"
+#include "sound/mixer_intern.h"
 #include "graphics/surface.h"
 
-class DSAudioMixer : public Audio::Mixer {	
+class DSAudioMixer : public Audio::MixerImpl {	
+
+public:
+	DSAudioMixer(OSystem* system) : Audio::MixerImpl(system) { }
 };
 
 class DSTimerManager : public DefaultTimerManager {	
@@ -62,7 +65,7 @@
 	Graphics::Surface* createTempFrameBuffer();
 
 public:
-	typedef void (*SoundProc)(void *param, byte *buf, int len);
+	typedef void (*SoundProc)(byte *buf, int len);
 	typedef int  (*TimerProc)(int interval);
 
 	OSystem_DS();
@@ -146,6 +149,8 @@
 	virtual void unlockScreen();
 	
 	virtual Audio::Mixer* getMixer() { return _mixer; }
+	Audio::MixerImpl* getMixerImpl() { return _mixer; }
+
 	virtual Common::TimerManager* getTimerManager() { return _timer; }
 	static int timerHandler(int t);
 

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/wordcompletion.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/wordcompletion.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/ds/arm9/source/wordcompletion.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -1,6 +1,6 @@
 #include "wordcompletion.h"
-#include "engines/agi/agi.h"
 #include "osystem_ds.h"
+#include "engines/agi/agi.h"	// Caution for #define for NUM_CHANNELS, causes problems in mixer_intern.h
 
 #ifdef ENABLE_AGI
 

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/psp/Makefile
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/psp/Makefile	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/psp/Makefile	2008-07-09 23:59:05 UTC (rev 32982)
@@ -2,10 +2,36 @@
 # $URL$
 # $Id$
 
+ENABLED=STATIC_PLUGIN
+
 #control build
 DISABLE_SCALERS = true
 DISABLE_HQ_SCALERS = true
 
+ENABLE_SCUMM = $(ENABLED)
+ENABLE_SCUMM_7_8 = $(ENABLED)
+#ENABLE_HE = $(ENABLED)
+ENABLE_AGI = $(ENABLED)
+ENABLE_AGOS = $(ENABLED)
+#ENABLE_CINE = $(ENABLED)
+#ENABLE_CRUISE = $(ENABLED)
+ENABLE_DRASCULA = $(ENABLED)
+ENABLE_GOB = $(ENABLED)
+#ENABLE_IGOR = $(ENABLED)
+ENABLE_KYRA = $(ENABLED)
+ENABLE_LURE = $(ENABLED)
+#ENABLE_M4 = $(ENABLED)
+#ENABLE_MADE = $(ENABLED)
+#ENABLE_PARALLACTION = $(ENABLED)
+#ENABLE_QUEEN = $(ENABLED)
+#ENABLE_SAGA = $(ENABLED)
+ENABLE_SKY = $(ENABLED)
+ENABLE_SWORD1 = $(ENABLED)
+ENABLE_SWORD2 = $(ENABLED)
+#ENABLE_TINSEL = $(ENABLED)
+#ENABLE_TOUCHE = $(ENABLED)
+
+
 srcdir = ../../..
 VPATH = $(srcdir)
 HAVE_GCC3 = false
@@ -63,6 +89,8 @@
 	kbd_l_c.o \
 	trace.o
 
+DEPDIR = .deps
+
 include $(srcdir)/Makefile.common
 
 PSP_EBOOT_SFO = param.sfo

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/psp/osys_psp.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/psp/osys_psp.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/psp/osys_psp.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -72,7 +72,7 @@
 };
 
 
-OSystem_PSP::OSystem_PSP() : _screenWidth(0), _screenHeight(0), _overlayWidth(0), _overlayHeight(0), _offscreen(0), _overlayBuffer(0), _overlayVisible(false), _shakePos(0), _mouseBuf(0), _prevButtons(0), _lastPadCheck(0), _padAccel(0) {
+OSystem_PSP::OSystem_PSP() : _screenWidth(0), _screenHeight(0), _overlayWidth(0), _overlayHeight(0), _offscreen(0), _overlayBuffer(0), _overlayVisible(false), _shakePos(0), _mouseBuf(0), _prevButtons(0), _lastPadCheck(0), _padAccel(0), _mixer(0) {
 
 	memset(_palette, 0, sizeof(_palette));
 
@@ -99,11 +99,11 @@
 
 void OSystem_PSP::initBackend() {
 	_savefile = new DefaultSaveFileManager();
-	_mixer = new Audio::MixerImpl(this);
 	_timer = new DefaultTimerManager();
-	setSoundCallback(Audio::Mixer::mixCallback, _mixer);
 	setTimerCallback(&timer_handler, 10);
 
+	setupMixer();
+
 	OSystem::initBackend();
 }
 
@@ -586,7 +586,15 @@
 	SDL_DestroyMutex((SDL_mutex *)mutex);
 }
 
-bool OSystem_PSP::setSoundCallback(SoundProc proc, void *param) {
+void OSystem_PSP::mixCallback(void *sys, byte *samples, int len) {
+	OSystem_PSP *this_ = (OSystem_PSP *)sys;
+	assert(this_);
+
+	if (this_->_mixer)
+		this_->_mixer->mixCallback(samples, len);
+}
+
+void OSystem_PSP::setupMixer(void) {
 	SDL_AudioSpec desired;
 	SDL_AudioSpec obtained;
 
@@ -613,23 +621,31 @@
 	desired.format = AUDIO_S16SYS;
 	desired.channels = 2;
 	desired.samples = samples;
-	desired.callback = proc;
-	desired.userdata = param;
+	desired.callback = mixCallback;
+	desired.userdata = this;
+
+	assert(!_mixer);
+	_mixer = new Audio::MixerImpl(this);
+	assert(_mixer);
+
 	if (SDL_OpenAudio(&desired, &obtained) != 0) {
-		return false;
+		warning("Could not open audio: %s", SDL_GetError());
+		_samplesPerSec = 0;
+		_mixer->setReady(false);
+	} else {
+		// Note: This should be the obtained output rate, but it seems that at
+		// least on some platforms SDL will lie and claim it did get the rate
+		// even if it didn't. Probably only happens for "weird" rates, though.
+		_samplesPerSec = obtained.freq;
+		
+		// Tell the mixer that we are ready and start the sound processing
+		_mixer->setOutputRate(_samplesPerSec);
+		_mixer->setReady(true);
+
+		SDL_PauseAudio(0);
 	}
-	// Note: This should be the obtained output rate, but it seems that at
-	// least on some platforms SDL will lie and claim it did get the rate
-	// even if it didn't. Probably only happens for "weird" rates, though.
-	_samplesPerSec = obtained.freq;
-	SDL_PauseAudio(0);
-	return true;
 }
 
-int OSystem_PSP::getOutputSampleRate() const {
-	return _samplesPerSec;
-}
-
 void OSystem_PSP::quit() {
 	SDL_CloseAudio();
 	SDL_Quit();

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/psp/osys_psp.h
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/psp/osys_psp.h	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/psp/osys_psp.h	2008-07-09 23:59:05 UTC (rev 32982)
@@ -26,6 +26,7 @@
 #include "common/scummsys.h"
 #include "common/system.h"
 #include "graphics/surface.h"
+#include "sound/mixer_intern.h"
 #include "backends/fs/psp/psp-fs-factory.h"
 
 
@@ -71,7 +72,7 @@
 	SceCtrlData pad;
 
 	Common::SaveFileManager *_savefile;
-	Audio::Mixer *_mixer;
+	Audio::MixerImpl *_mixer;
 	Common::TimerManager *_timer;
 
 public:
@@ -129,9 +130,8 @@
 	virtual void unlockMutex(MutexRef mutex);
 	virtual void deleteMutex(MutexRef mutex);
 
-	typedef void (*SoundProc)(void *param, byte *buf, int len);
-	virtual bool setSoundCallback(SoundProc proc, void *param);
-	virtual int getOutputSampleRate() const;
+	static void mixCallback(void *sys, byte *samples, int len);
+	virtual void setupMixer(void);
 
 	Common::SaveFileManager *getSavefileManager() { return _savefile; }
 	Audio::Mixer *getMixer() { return _mixer; }

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -91,7 +91,7 @@
 	_startup_time = gettime();
 
 	_savefile = new DefaultSaveFileManager();
-	_mixer = new Audio::Mixer();
+	_mixer = new Audio::MixerImpl(this);
 	_timer = new DefaultTimerManager();
 
 	initGfx();

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem.h
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem.h	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem.h	2008-07-09 23:59:05 UTC (rev 32982)
@@ -31,7 +31,7 @@
 #include "backends/saves/default/default-saves.h"
 #include "backends/timer/default/default-timer.h"
 #include "graphics/surface.h"
-#include "sound/mixer.h"
+#include "sound/mixer_intern.h"
 
 #include <gctypes.h>
 #include <gccore.h>
@@ -96,7 +96,7 @@
 
 protected:
 	Common::SaveFileManager *_savefile;
-	Audio::Mixer *_mixer;
+	Audio::MixerImpl *_mixer;
 	DefaultTimerManager *_timer;
 
 public:
@@ -159,7 +159,6 @@
 	virtual void deleteMutex(MutexRef mutex);
 
 	typedef void (*SoundProc)(void *param, byte *buf, int len);
-	virtual int getOutputSampleRate() const;
 
 	virtual void quit();
 

Modified: scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem_sfx.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem_sfx.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/platform/wii/osystem_sfx.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -36,9 +36,6 @@
 static u8 sb = 0;
 static u8 *sound_buffer[2];
 
-static OSystem_Wii::SoundProc sound_proc = NULL;
-static void *proc_param = NULL;
-
 static void audio_switch_buffers() {
 	AUDIO_StopDMA();
 	AUDIO_InitDMA((u32) sound_buffer[sb], SFX_THREAD_FRAG_SIZE);
@@ -48,6 +45,7 @@
 }
 
 static void * sfx_thread_func(void *arg) {
+	Audio::MixerImpl *mixer = (Audio::MixerImpl *) arg;
 	u8 next_sb;
 
 	while (true) {
@@ -57,7 +55,7 @@
 			break;
 
 		next_sb = sb ^ 1;
-		sound_proc(proc_param, sound_buffer[next_sb], SFX_THREAD_FRAG_SIZE);
+		mixer->mixCallback(sound_buffer[next_sb], SFX_THREAD_FRAG_SIZE);
 		DCFlushRange(sound_buffer[next_sb], SFX_THREAD_FRAG_SIZE);
 
 		sb = next_sb;
@@ -75,7 +73,7 @@
 
 	LWP_InitQueue(&sfx_queue);
 
-	s32 res = LWP_CreateThread(&sfx_thread, sfx_thread_func, NULL, sfx_stack,
+	s32 res = LWP_CreateThread(&sfx_thread, sfx_thread_func, _mixer, sfx_stack,
 								SFX_THREAD_STACKSIZE, SFX_THREAD_PRIO);
 
 	if (res) {
@@ -95,9 +93,7 @@
 	DCFlushRange(sound_buffer[0], SFX_THREAD_FRAG_SIZE);
 	DCFlushRange(sound_buffer[1], SFX_THREAD_FRAG_SIZE);
 
-	sound_proc = Audio::Mixer::mixCallback;
-	proc_param = _mixer;
-
+	_mixer->setOutputRate(48000);
 	_mixer->setReady(true);
 
 	AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ);
@@ -127,7 +123,3 @@
 	}
 }
 
-int OSystem_Wii::getOutputSampleRate() const {
-	return 48000;
-}
-

Modified: scummvm/branches/gsoc2008-tfmx/backends/saves/default/default-saves.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/backends/saves/default/default-saves.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/backends/saves/default/default-saves.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -120,7 +120,7 @@
 	Common::StringList results;
 	Common::String search(pattern);
 
-	if (savePath.lookupFile(savefiles, search, false, true)) {
+	if (savePath.lookupFile(savefiles, search, false, true, 0)) {
 		for (FSList::const_iterator file = savefiles.begin(); file != savefiles.end(); ++file) {
 			results.push_back(file->getName());
 		}

Modified: scummvm/branches/gsoc2008-tfmx/configure
===================================================================
--- scummvm/branches/gsoc2008-tfmx/configure	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/configure	2008-07-09 23:59:05 UTC (rev 32982)
@@ -741,6 +741,10 @@
 	--enable-release)
 		DEBFLAGS="-O2 -Wuninitialized"
 		;;
+	--enable-profiling)
+		CXXFLAGS="$CXXFLAGS -pg"
+		LDFLAGS="$LDFLAGS -pg"
+		;;
 	--with-sdl-prefix=*)
 		arg=`echo $ac_option | cut -d '=' -f 2`
 		_sdlpath="$arg:$arg/bin"

Modified: scummvm/branches/gsoc2008-tfmx/dists/msvc7/parallaction.vcproj
===================================================================
--- scummvm/branches/gsoc2008-tfmx/dists/msvc7/parallaction.vcproj	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/dists/msvc7/parallaction.vcproj	2008-07-09 23:59:05 UTC (rev 32982)
@@ -97,6 +97,9 @@
 	</Configurations>
 	<Files>
 		<File
+			RelativePath="..\..\engines\parallaction\balloons.cpp">
+		</File>
+		<File
 			RelativePath="..\..\engines\parallaction\callables_br.cpp">
 		</File>
 		<File

Modified: scummvm/branches/gsoc2008-tfmx/dists/msvc71/parallaction.vcproj
===================================================================
--- scummvm/branches/gsoc2008-tfmx/dists/msvc71/parallaction.vcproj	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/dists/msvc71/parallaction.vcproj	2008-07-09 23:59:05 UTC (rev 32982)
@@ -111,6 +111,9 @@
 	</References>
 	<Files>
 		<File
+			RelativePath="..\..\engines\parallaction\balloons.cpp">
+		</File>
+		<File
 			RelativePath="..\..\engines\parallaction\callables_br.cpp">
 		</File>
 		<File

Modified: scummvm/branches/gsoc2008-tfmx/dists/msvc8/parallaction.vcproj
===================================================================
--- scummvm/branches/gsoc2008-tfmx/dists/msvc8/parallaction.vcproj	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/dists/msvc8/parallaction.vcproj	2008-07-09 23:59:05 UTC (rev 32982)
@@ -161,6 +161,10 @@
 	</References>
 	<Files>
 		<File
+			RelativePath="..\..\engines\parallaction\balloons.cpp"
+			>
+		</File>
+		<File
 			RelativePath="..\..\engines\parallaction\callables_br.cpp"
 			>
 		</File>

Modified: scummvm/branches/gsoc2008-tfmx/dists/msvc9/parallaction.vcproj
===================================================================
--- scummvm/branches/gsoc2008-tfmx/dists/msvc9/parallaction.vcproj	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/dists/msvc9/parallaction.vcproj	2008-07-09 23:59:05 UTC (rev 32982)
@@ -162,6 +162,10 @@
 	</References>
 	<Files>
 		<File
+			RelativePath="..\..\engines\parallaction\balloons.cpp"
+			>
+		</File>
+		<File
 			RelativePath="..\..\engines\parallaction\callables_br.cpp"
 			>
 		</File>

Modified: scummvm/branches/gsoc2008-tfmx/engines/cine/gfx.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/cine/gfx.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/cine/gfx.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -969,6 +969,7 @@
 
 /*! \brief Draw one overlay
  * \param it Overlay info
+ * \todo Add handling of type 22 overlays
  */
 void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
 	int len;
@@ -979,6 +980,9 @@
 	switch (it->type) {
 	// color sprite
 	case 0:
+		if (objectTable[it->objIdx].frame < 0) {
+			break;
+		}
 		sprite = animDataTable + objectTable[it->objIdx].frame;
 		len = sprite->_realWidth * sprite->_height;
 		mask = new byte[len];
@@ -988,6 +992,13 @@
 		delete[] mask;
 		break;
 
+	// bitmap
+	case 4:
+		if (objectTable[it->objIdx].frame >= 0) {
+			FWRenderer::renderOverlay(it);
+		}
+		break;
+
 	// masked background
 	case 20:
 		assert(it->objIdx < NUM_MAX_OBJECT);

Modified: scummvm/branches/gsoc2008-tfmx/engines/gob/detection.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/gob/detection.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/gob/detection.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -277,6 +277,19 @@
 		kFeaturesNone,
 		"intro"
 	},
+	{ // Supplied by raina in the forums
+		{
+			"gob1",
+			"",
+			AD_ENTRY1s("intro.stk", "6d837c6380d8f4d984c9f6cc0026df4f", 192712),
+			EN_ANY,
+			kPlatformMacintosh,
+			Common::ADGF_NO_FLAGS
+		},
+		kGameTypeGob1,
+		kFeaturesNone,
+		"intro"
+	},
 	{ // Supplied by paul66 in bug report #1652352
 		{
 			"gob1",

Modified: scummvm/branches/gsoc2008-tfmx/engines/gob/goblin_v2.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/gob/goblin_v2.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/gob/goblin_v2.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -88,7 +88,7 @@
 				(_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (y + 1) / 2;
 		*obj->pPosX = x * _vm->_map->_tilesWidth;
 	} else {
-		if (obj->goblinStates[state] != 0) {
+		if ((obj->goblinStates != 0) && (obj->goblinStates[state] != 0)) {
 			layer = obj->goblinStates[state][0].layer;
 			animation = obj->goblinStates[state][0].animation;
 			objAnim->state = state;

Modified: scummvm/branches/gsoc2008-tfmx/engines/gob/inter.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/gob/inter.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/gob/inter.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -212,25 +212,35 @@
 			break;
 
 		// WORKAROUND:
-		// The EGA version of gob1 doesn't add a delay after showing
+		// The EGA and Mac versions of gob1 doesn't add a delay after showing
 		// images between levels. We manually add it here.
-		if ((_vm->getGameType() == kGameTypeGob1) && _vm->isEGA()) {
+		if ((_vm->getGameType() == kGameTypeGob1) &&
+		   (_vm->isEGA() || (_vm->getPlatform() == Common::kPlatformMacintosh))) {
+
 			int addr = _vm->_global->_inter_execPtr-_vm->_game->_totFileData;
-			if ((startaddr == 0x18B4 && addr == 0x1A7F && // Zombie
+
+			if ((startaddr == 0x18B4 && addr == 0x1A7F && // Zombie, EGA
 				 !strncmp(_vm->_game->_curTotFile, "avt005.tot", 10)) ||
+			  (startaddr == 0x188D && addr == 0x1A58 && // Zombie, Mac
+				 !strncmp(_vm->_game->_curTotFile, "avt005.tot", 10)) ||
 				(startaddr == 0x1299 && addr == 0x139A && // Dungeon
 				 !strncmp(_vm->_game->_curTotFile, "avt006.tot", 10)) ||
-				(startaddr == 0x11C0 && addr == 0x12C9 && // Cauldron
+				(startaddr == 0x11C0 && addr == 0x12C9 && // Cauldron, EGA
 				 !strncmp(_vm->_game->_curTotFile, "avt012.tot", 10)) ||
+				(startaddr == 0x11C8 && addr == 0x1341 && // Cauldron, Mac
+				 !strncmp(_vm->_game->_curTotFile, "avt012.tot", 10)) ||
 				(startaddr == 0x09F2 && addr == 0x0AF3 && // Statue
 				 !strncmp(_vm->_game->_curTotFile, "avt016.tot", 10)) ||
 				(startaddr == 0x0B92 && addr == 0x0C93 && // Castle
 				 !strncmp(_vm->_game->_curTotFile, "avt019.tot", 10)) ||
-				(startaddr == 0x17D9 && addr == 0x18DA && // Finale
+				(startaddr == 0x17D9 && addr == 0x18DA && // Finale, EGA
+				 !strncmp(_vm->_game->_curTotFile, "avt022.tot", 10)) ||
+				(startaddr == 0x17E9 && addr == 0x19A8 && // Finale, Mac
 				 !strncmp(_vm->_game->_curTotFile, "avt022.tot", 10))) {
 
 				_vm->_util->longDelay(5000);
 			}
+
 		} // End of workaround
 
 		cmd = *_vm->_global->_inter_execPtr;

Modified: scummvm/branches/gsoc2008-tfmx/engines/kyra/detection.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/kyra/detection.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/kyra/detection.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -654,6 +654,52 @@
 		KYRA3_CD_FAN_FLAGS(Common::ES_ESP, Common::EN_ANY)
 	},
 
+	// Itlian fan translation, see fr#2003504 "KYRA: add support for Italian version of Kyrandia 2&3"
+	{
+		{
+			"kyra3",
+			0,
+			{
+				{ "ONETIME.PAK", 0, "ee2d4d056a5de5333a3c6bda055b3cb4", -1 },
+				{ "AUD.PAK", 0, 0, -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::EN_ANY,
+			Common::kPlatformPC,
+			Common::ADGF_DROPLANGUAGE
+		},
+		KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
+	},
+	{
+		{
+			"kyra3",
+			0,
+			{
+				{ "ONETIME.PAK", 0, "ee2d4d056a5de5333a3c6bda055b3cb4", -1 },
+				{ "AUD.PAK", 0, 0, -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::DE_DEU,
+			Common::kPlatformPC,
+			Common::ADGF_DROPLANGUAGE
+		},
+		KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
+	},
+	{
+		{
+			"kyra3",
+			0,
+			{
+				{ "ONETIME.PAK", 0, "ee2d4d056a5de5333a3c6bda055b3cb4", -1 },
+				{ "AUD.PAK", 0, 0, -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::IT_ITA,
+			Common::kPlatformPC,
+			Common::ADGF_DROPLANGUAGE
+		},
+		KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
+	},
 	{ AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0) }
 };
 

Modified: scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_mr.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_mr.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_mr.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -343,6 +343,14 @@
 		0x80, 0xFF
 	};
 
+	if (_flags.lang == Common::ES_ESP) {
+		for (int i = 0; i < 4; ++i)
+			data.strings[i] = _mainMenuSpanishFan[i];
+	} else if (_flags.lang == Common::IT_ITA) {
+		for (int i = 0; i < 4; ++i)
+			data.strings[i] = _mainMenuItalianFan[i];
+	}
+
 	MainMenu::Animation anim;
 	anim.anim = _menuAnim;
 	anim.startFrame = 29;

Modified: scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_mr.h
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_mr.h	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_mr.h	2008-07-09 23:59:05 UTC (rev 32982)
@@ -184,9 +184,12 @@
 
 private:
 	// main menu
-	const char *const *_mainMenuStrings;
+	const char * const *_mainMenuStrings;
 	int _mainMenuStringsSize;
 
+	static const char * const _mainMenuSpanishFan[];
+	static const char * const _mainMenuItalianFan[];
+
 	// animator
 	uint8 *_gamePlayBuffer;
 	void restorePage3();

Modified: scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_v1.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_v1.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/kyra/kyra_v1.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -247,8 +247,14 @@
 void KyraEngine_v1::registerDefaultSettings() {
 	if (_flags.gameID != GI_KYRA3)
 		ConfMan.registerDefault("cdaudio", (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98));
-	if (_flags.fanLang != Common::UNK_LANG)
-		ConfMan.registerDefault("subtitles", true);
+	if (_flags.fanLang != Common::UNK_LANG) {
+		// HACK/WORKAROUND: Since we can't use registerDefault here to overwrite
+		// the global subtitles settings, we're using this hack to enable subtitles
+		// for fan translations
+		const Common::ConfigManager::Domain *cur = ConfMan.getActiveDomain();
+		if (!cur || (cur && cur->get("subtitles").empty()))
+			ConfMan.setBool("subtitles", true);
+	}
 }
 
 void KyraEngine_v1::readSettings() {

Modified: scummvm/branches/gsoc2008-tfmx/engines/kyra/sequences_lok.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/kyra/sequences_lok.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/kyra/sequences_lok.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -1083,7 +1083,7 @@
 	_screen->_charWidth = -1;
 
 	// we only need this for the fm-towns version
-	if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)
+	if (_flags.platform == Common::kPlatformFMTowns && _configMusic == 1)
 		snd_playWanderScoreViaMap(53, 1);
 
 	uint8 *buffer = 0;

Modified: scummvm/branches/gsoc2008-tfmx/engines/kyra/sound.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/kyra/sound.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/kyra/sound.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -249,21 +249,6 @@
 }
 
 void SoundMidiPC::send(uint32 b) {
-	// HACK: For Kyrandia, we make the simplifying assumption that a song
-	// either loops in its entirety, or not at all. So if we see a FOR_LOOP
-	// controller event, we turn on looping even if there isn't any
-	// corresponding NEXT_BREAK event.
-	//
-	// This is a gross over-simplification of how XMIDI handles loops. If
-	// anyone feels like doing a proper implementation, please refer to
-	// the Exult project, and do it in midiparser_xmidi.cpp
-
-	if ((b & 0xFFF0) == 0x74B0 && _eventFromMusic) {
-		debugC(9, kDebugLevelMain | kDebugLevelSound, "SoundMidiPC: Looping song");
-		_musicParser->property(MidiParser::mpAutoLoop, true);
-		return;
-	}
-
 	if (_passThrough) {
 		if ((b & 0xFFF0) == 0x007BB0)
 			return;

Modified: scummvm/branches/gsoc2008-tfmx/engines/kyra/sound_lok.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/kyra/sound_lok.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/kyra/sound_lok.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -49,20 +49,23 @@
 		} else if (command >= 35 && command <= 38) {
 			snd_playSoundEffect(command-20);
 		} else if (command >= 2) {
-			if (_lastMusicCommand != command) {
+			if (_lastMusicCommand != command)
 				// the original does -2 here we handle this inside _sound->playTrack()
 				_sound->playTrack(command);
-			}
 		} else {
 			_sound->haltTrack();
 		}
+		_lastMusicCommand = command;
 	} else if (_flags.platform == Common::kPlatformPC98) {
-		if (command == 1)
+		if (command == 1) {
 			_sound->beginFadeOut();
-		else if (command >= 2)
-			_sound->playTrack(command);	
-		else
+		} else if (command >= 2) {
+			if (_lastMusicCommand != command)
+				_sound->playTrack(command);
+		} else {
 			_sound->haltTrack();
+		}
+		_lastMusicCommand = command;
 	} else {
 		KyraEngine_v1::snd_playWanderScoreViaMap(command, restart);
 	}

Modified: scummvm/branches/gsoc2008-tfmx/engines/kyra/staticres.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/kyra/staticres.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/kyra/staticres.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -1976,12 +1976,26 @@
 	"TRE",
 	"TRF",
 	"TRG"/*,
-	"TRI",		Italian and Spanish were never included
-	"TRS"*/
+	"TRI",		Italian and Spanish were never included, the supported fan translations are using
+	"TRS"		English/French extensions thus overwriting these languages */		
 };
 
 const int KyraEngine_MR::_languageExtensionSize = ARRAYSIZE(KyraEngine_MR::_languageExtension);
 
+const char * const KyraEngine_MR::_mainMenuSpanishFan[] = {
+	"Nueva Partida",
+	"Ver Intro",
+	"Restaurar",
+	"Finalizar"
+};
+
+const char * const KyraEngine_MR::_mainMenuItalianFan[] = {
+	"Nuova Partita",
+	"Introduzione",
+	"Carica una partita",
+	"Esci dal gioco"
+};
+
 const KyraEngine_MR::ShapeDesc KyraEngine_MR::_shapeDescs[] = {
 	{ 57, 91, -31, -82 },
 	{ 57, 91, -31, -82 },

Modified: scummvm/branches/gsoc2008-tfmx/engines/m4/converse.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/m4/converse.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/m4/converse.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -380,7 +380,7 @@
 	uint32 size;
 	uint32 chunk;
 	uint32 data = 0;
-	uint32 i;
+	uint32 i = 0;
 	ConvEntry* curEntry = NULL;
 	ConvEntry* replyEntry = NULL;
 	int32 currentWeightedEntry = -1;

Modified: scummvm/branches/gsoc2008-tfmx/engines/m4/globals.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/m4/globals.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/m4/globals.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -75,7 +75,7 @@
 
 bool Kernel::handleTrigger(int32 triggerNum) {
 
-	printf("betweenRooms = %d; triggerNum = %08X\n", betweenRooms, triggerNum);
+	printf("betweenRooms = %d; triggerNum = %08X\n", betweenRooms, (uint)triggerNum);
 
 	if (betweenRooms)
 		return true;
@@ -271,11 +271,13 @@
 }
 
 Globals::~Globals() {
-	for(uint32 i = 0; i < _madsVocab.size(); i++)
+	uint32 i;
+
+	for(i = 0; i < _madsVocab.size(); i++)
 		free(_madsVocab[i]);
 	_madsVocab.clear();
 
-	for(uint32 i = 0; i < _madsQuotes.size(); i++)
+	for(i = 0; i < _madsQuotes.size(); i++)
 		free(_madsQuotes[i]);
 	_madsQuotes.clear();
 
@@ -351,7 +353,7 @@
 	_vm->res()->toss("messages.dat");
 }
 
-char* Globals::loadMessage(uint32 index) {
+char* Globals::loadMessage(uint index) {
 	if (index > _madsMessages.size() - 1) {
 		warning("Invalid message index: %i", index);
 		return NULL;

Modified: scummvm/branches/gsoc2008-tfmx/engines/m4/globals.h
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/m4/globals.h	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/m4/globals.h	2008-07-09 23:59:05 UTC (rev 32982)
@@ -177,7 +177,7 @@
 
 	void loadMadsMessagesInfo();
 	uint32 getMessagesSize() { return _madsMessages.size(); }
-	char* loadMessage(uint32 index);
+	char* loadMessage(uint index);
 };
 
 #define PLAYER_FIELD_LENGTH 40

Modified: scummvm/branches/gsoc2008-tfmx/engines/m4/resource.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/m4/resource.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/m4/resource.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -310,7 +310,7 @@
 
 Common::SeekableReadStream *MADSResourceManager::loadResource(const char *resourceName, bool loadFlag) {
 	Common::File hagFile;
-	uint32 offset, size;
+	uint32 offset = 0, size = 0;
 
 	// If the first character is a '@' then look for an external file
 	

Copied: scummvm/branches/gsoc2008-tfmx/engines/parallaction/balloons.cpp (from rev 32978, scummvm/trunk/engines/parallaction/balloons.cpp)
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/balloons.cpp	                        (rev 0)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/balloons.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -0,0 +1,456 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "parallaction/graphics.h"
+#include "parallaction/parallaction.h"
+
+namespace Parallaction {
+
+
+#define	BALLOON_TRANSPARENT_COLOR_NS 2
+#define BALLOON_TRANSPARENT_COLOR_BR 0
+
+#define BALLOON_TAIL_WIDTH	12
+#define BALLOON_TAIL_HEIGHT	10
+
+
+byte _resBalloonTail[2][BALLOON_TAIL_WIDTH*BALLOON_TAIL_HEIGHT] = {
+	{
+	  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02,
+	  0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02,
+	  0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
+	  0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
+	  0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
+	  0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02,
+	  0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
+	  0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	  0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	  0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	},
+	{
+	  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02,
+	  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02,
+	  0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
+	  0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
+	  0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+	  0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
+	  0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02,
+	  0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
+	  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02,
+	  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02
+	}
+};
+
+class BalloonManager_ns : public BalloonManager {
+
+	static int16 _dialogueBalloonX[5];
+
+	struct Balloon {
+		Common::Rect outerBox;
+		Common::Rect innerBox;
+		Graphics::Surface *surface;
+		GfxObj	*obj;
+	} _intBalloons[5];
+
+	uint	_numBalloons;
+
+	void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth);
+	int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness);
+	Balloon *getBalloon(uint id);
+
+	Gfx *_gfx;
+
+public:
+	BalloonManager_ns(Gfx *gfx);
+	~BalloonManager_ns();
+
+	void freeBalloons();
+	int setLocationBalloon(char *text, bool endGame);
+	int setDialogueBalloon(char *text, uint16 winding, byte textColor);
+	int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor);
+	void setBalloonText(uint id, char *text, byte textColor);
+	int hitTestDialogueBalloon(int x, int y);
+};
+
+int16 BalloonManager_ns::_dialogueBalloonX[5] = { 80, 120, 150, 150, 150 };
+
+BalloonManager_ns::BalloonManager_ns(Gfx *gfx) : _numBalloons(0), _gfx(gfx) {
+
+}
+
+BalloonManager_ns::~BalloonManager_ns() {
+
+}
+
+
+BalloonManager_ns::Balloon* BalloonManager_ns::getBalloon(uint id) {
+	assert(id < _numBalloons);
+	return &_intBalloons[id];
+}
+
+int BalloonManager_ns::createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness) {
+	assert(_numBalloons < 5);
+
+	int id = _numBalloons;
+
+	Balloon *balloon = &_intBalloons[id];
+
+	int16 real_h = (winding == -1) ? h : h + 9;
+	balloon->surface = new Graphics::Surface;
+	balloon->surface->create(w, real_h, 1);
+	balloon->surface->fillRect(Common::Rect(w, real_h), BALLOON_TRANSPARENT_COLOR_NS);
+
+	Common::Rect r(w, h);
+	balloon->surface->fillRect(r, 0);
+	balloon->outerBox = r;
+
+	r.grow(-borderThickness);
+	balloon->surface->fillRect(r, 1);
+	balloon->innerBox = r;
+
+	if (winding != -1) {
+		// draws tail
+		// TODO: this bitmap tail should only be used for Dos games. Amiga should use a polygon fill.
+		winding = (winding == 0 ? 1 : 0);
+		Common::Rect s(BALLOON_TAIL_WIDTH, BALLOON_TAIL_HEIGHT);
+		s.moveTo(r.width()/2 - 5, r.bottom - 1);
+		_gfx->blt(s, _resBalloonTail[winding], balloon->surface, LAYER_FOREGROUND, BALLOON_TRANSPARENT_COLOR_NS);
+	}
+
+	_numBalloons++;
+
+	return id;
+}
+
+
+int BalloonManager_ns::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) {
+
+	int16 w, h;
+
+	_gfx->getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
+
+	int id = createBalloon(w+5, h, winding, 1);
+	Balloon *balloon = &_intBalloons[id];
+
+	_gfx->drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+
+	// TODO: extract some text to make a name for obj
+	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
+	balloon->obj->x = x;
+	balloon->obj->y = y;
+	balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_NS;
+
+	return id;
+}
+
+int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, byte textColor) {
+
+	int16 w, h;
+
+	_gfx->getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
+
+	int id = createBalloon(w+5, h, winding, 1);
+	Balloon *balloon = &_intBalloons[id];
+
+	_gfx->drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+
+	// TODO: extract some text to make a name for obj
+	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
+	balloon->obj->x = _dialogueBalloonX[id];
+	balloon->obj->y = 10;
+	balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_NS;
+
+	if (id > 0) {
+		balloon->obj->y += _intBalloons[id - 1].obj->y + _intBalloons[id - 1].outerBox.height();
+	}
+
+
+	return id;
+}
+
+void BalloonManager_ns::setBalloonText(uint id, char *text, byte textColor) {
+	Balloon *balloon = getBalloon(id);
+	balloon->surface->fillRect(balloon->innerBox, 1);
+	_gfx->drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+}
+
+
+int BalloonManager_ns::setLocationBalloon(char *text, bool endGame) {
+
+	int16 w, h;
+
+	_gfx->getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
+
+	int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR_NS);
+	Balloon *balloon = &_intBalloons[id];
+	_gfx->drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH);
+
+	// TODO: extract some text to make a name for obj
+	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
+	balloon->obj->x = 5;
+	balloon->obj->y = 5;
+	balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_NS;
+
+	return id;
+}
+
+int BalloonManager_ns::hitTestDialogueBalloon(int x, int y) {
+
+	Common::Point p;
+
+	for (uint i = 0; i < _numBalloons; i++) {
+		p.x = x - _intBalloons[i].obj->x;
+		p.y = y - _intBalloons[i].obj->y;
+
+		if (_intBalloons[i].innerBox.contains(p))
+			return i;
+	}
+
+	return -1;
+}
+
+void BalloonManager_ns::freeBalloons() {
+	_gfx->destroyBalloons();
+
+	for (uint i = 0; i < _numBalloons; i++) {
+		_intBalloons[i].obj = 0;
+		_intBalloons[i].surface = 0;	// no need to delete surface, since it is done by destroyBalloons
+	}
+
+	_numBalloons = 0;
+}
+
+
+
+
+
+
+
+
+class BalloonManager_br : public BalloonManager {
+
+	struct Balloon {
+		Common::Rect box;
+		Graphics::Surface *surface;
+		GfxObj	*obj;
+	} _intBalloons[3];
+
+	uint	_numBalloons;
+
+	Frames *_leftBalloon;
+	Frames *_rightBalloon;
+	Disk *_disk;
+	Gfx *_gfx;
+
+	void cacheAnims();
+	void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth);
+	int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness);
+	Balloon *getBalloon(uint id);
+	Graphics::Surface *expandBalloon(Frames *data, int frameNum);
+
+
+public:
+	BalloonManager_br(Disk *disk, Gfx *gfx);
+	~BalloonManager_br();
+
+	void freeBalloons();
+	int setLocationBalloon(char *text, bool endGame);
+	int setDialogueBalloon(char *text, uint16 winding, byte textColor);
+	int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor);
+	void setBalloonText(uint id, char *text, byte textColor);
+	int hitTestDialogueBalloon(int x, int y);
+};
+
+
+
+BalloonManager_br::Balloon* BalloonManager_br::getBalloon(uint id) {
+	assert(id < _numBalloons);
+	return &_intBalloons[id];
+}
+
+Graphics::Surface *BalloonManager_br::expandBalloon(Frames *data, int frameNum) {
+
+	Common::Rect rect;
+	data->getRect(frameNum, rect);
+
+	rect.translate(-rect.left, -rect.top);
+
+	Graphics::Surface *surf = new Graphics::Surface;
+	surf->create(rect.width(), rect.height(), 1);
+
+	_gfx->unpackBlt(rect, data->getData(frameNum), data->getRawSize(frameNum), surf, 0, BALLOON_TRANSPARENT_COLOR_BR);
+
+	return surf;
+}
+
+int BalloonManager_br::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) {
+	cacheAnims();
+
+	int id = _numBalloons;
+	Frames *src = 0;
+	int srcFrame = 0;
+
+	Balloon *balloon = &_intBalloons[id];
+
+	if (winding == 0) {
+		src = _leftBalloon;
+		srcFrame = 0;
+	} else
+	if (winding == 1) {
+		src = _rightBalloon;
+		srcFrame = 0;
+	}
+
+	assert(src);
+
+	balloon->surface = expandBalloon(src, srcFrame);
+	src->getRect(srcFrame, balloon->box);
+
+//	drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+
+	// TODO: extract some text to make a name for obj
+	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
+	balloon->obj->x = x;
+	balloon->obj->y = y;
+	balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_BR;
+
+	_numBalloons++;
+
+	return id;
+}
+
+int BalloonManager_br::setDialogueBalloon(char *text, uint16 winding, byte textColor) {
+	cacheAnims();
+
+	int id = _numBalloons;
+	Frames *src = 0;
+	int srcFrame = 0;
+
+	Balloon *balloon = &_intBalloons[id];
+
+	if (winding == 0) {
+		src = _leftBalloon;
+		srcFrame = id;
+	} else
+	if (winding == 1) {
+		src = _rightBalloon;
+		srcFrame = 0;
+	}
+
+	assert(src);
+
+	balloon->surface = expandBalloon(src, srcFrame);
+	src->getRect(srcFrame, balloon->box);
+
+//	drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+
+	// TODO: extract some text to make a name for obj
+	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
+	balloon->obj->x = 0;
+	balloon->obj->y = 10;
+	balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_BR;
+
+	if (id > 0) {
+		balloon->obj->y += _intBalloons[id - 1].obj->y + _intBalloons[id - 1].box.height();
+	}
+
+	_numBalloons++;
+
+	return id;
+}
+
+void BalloonManager_br::setBalloonText(uint id, char *text, byte textColor) { }
+
+int BalloonManager_br::setLocationBalloon(char *text, bool endGame) {
+/*
+	int16 w, h;
+
+	getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
+
+	int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR);
+	Balloon *balloon = &_intBalloons[id];
+	drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH);
+
+	// TODO: extract some text to make a name for obj
+	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
+	balloon->obj->x = 5;
+	balloon->obj->y = 5;
+*/
+	return 0;
+}
+
+int BalloonManager_br::hitTestDialogueBalloon(int x, int y) {
+
+	Common::Point p;
+
+	for (uint i = 0; i < _numBalloons; i++) {
+		p.x = x - _intBalloons[i].obj->x;
+		p.y = y - _intBalloons[i].obj->y;
+
+		if (_intBalloons[i].box.contains(p))
+			return i;
+	}
+
+	return -1;
+}
+
+void BalloonManager_br::freeBalloons() {
+	_gfx->destroyBalloons();
+
+	for (uint i = 0; i < _numBalloons; i++) {
+		_intBalloons[i].obj = 0;
+		_intBalloons[i].surface = 0;	// no need to delete surface, since it is done by destroyBalloons
+	}
+
+	_numBalloons = 0;
+}
+
+void BalloonManager_br::cacheAnims() {
+	if (!_leftBalloon) {
+		_leftBalloon = _disk->loadFrames("fumetto.ani");
+		_rightBalloon = _disk->loadFrames("fumdx.ani");
+	}
+}
+
+BalloonManager_br::BalloonManager_br(Disk *disk, Gfx *gfx) : _numBalloons(0), _disk(disk), _gfx(gfx), _leftBalloon(0), _rightBalloon(0) {
+}
+
+BalloonManager_br::~BalloonManager_br() {
+	delete _leftBalloon;
+	delete _rightBalloon;
+}
+
+void Parallaction::setupBalloonManager() {
+	if (_vm->getGameType() == GType_Nippon) {
+		_balloonMan = new BalloonManager_ns(_vm->_gfx);
+	} else
+	if (_vm->getGameType() == GType_BRA) {
+		_balloonMan = new BalloonManager_br(_vm->_disk, _vm->_gfx);
+	} else {
+		error("Unknown game type");
+	}
+}
+
+} // namespace Parallaction

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/callables_ns.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/callables_ns.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/callables_ns.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -341,7 +341,7 @@
 	}
 
 	_input->waitUntilLeftClick();
-	_gfx->freeBalloons();
+	_balloonMan->freeBalloons();
 
 	return;
 }

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/dialogue.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/dialogue.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/dialogue.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -93,7 +93,7 @@
 	uint16 passwordLen = 0;
 	_password[0] = '\0';
 
-	_vm->_gfx->setDialogueBalloon(_q->_answers[0]->_text, 1, 3);
+	_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);
 
@@ -118,7 +118,7 @@
 		}
 
 		if (changed) {
-			_vm->_gfx->setBalloonText(0, _q->_answers[0]->_text, 3);
+			_vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 3);
 			_vm->_gfx->updateScreen();
 			changed = false;
 		}
@@ -143,7 +143,7 @@
 
 	}
 
-	_vm->_gfx->hideDialogueStuff();
+	_vm->hideDialogueStuff();
 
 	return 0;
 
@@ -162,7 +162,7 @@
 	// display suitable answers
 	if (((a->_yesFlags & flags) == a->_yesFlags) && ((a->_noFlags & ~flags) == a->_noFlags)) {
 
-		int id = _vm->_gfx->setDialogueBalloon(a->_text, 1, 3);
+		int id = _vm->_balloonMan->setDialogueBalloon(a->_text, 1, 3);
 		assert(id >= 0);
 		_visAnswers[id] = i;
 
@@ -190,13 +190,13 @@
 
 	if (!scumm_stricmp(_q->_text, "NULL")) return;
 
-	_vm->_gfx->setSingleBalloon(_q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, _q->_mood & 0x10, 0);
+	_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->_gfx->hideDialogueStuff();
+	_vm->hideDialogueStuff();
 
 	return;
 }
@@ -261,9 +261,9 @@
 	_vm->_gfx->setItemFrame(id, _q->_answers[0]->_mood & 0xF);
 
 	if (numAvailableAnswers == 1) {
-		_vm->_gfx->setBalloonText(0, _q->_answers[0]->_text, 0);
+		_vm->_balloonMan->setBalloonText(0, _q->_answers[0]->_text, 0);
 		_vm->_input->waitUntilLeftClick();
-		_vm->_gfx->hideDialogueStuff();
+		_vm->hideDialogueStuff();
 		return 0;
 	}
 
@@ -277,15 +277,15 @@
 		_vm->_input->readInput();
 		_vm->_input->getCursorPos(p);
 		event = _vm->_input->getLastButtonEvent();
-		selection = _vm->_gfx->hitTestDialogueBalloon(p.x, p.y);
+		selection = _vm->_balloonMan->hitTestDialogueBalloon(p.x, p.y);
 
 		if (selection != oldSelection) {
 			if (oldSelection != -1) {
-				_vm->_gfx->setBalloonText(oldSelection, _q->_answers[_visAnswers[oldSelection]]->_text, 3);
+				_vm->_balloonMan->setBalloonText(oldSelection, _q->_answers[_visAnswers[oldSelection]]->_text, 3);
 			}
 
 			if (selection != -1) {
-				_vm->_gfx->setBalloonText(selection, _q->_answers[_visAnswers[selection]]->_text, 0);
+				_vm->_balloonMan->setBalloonText(selection, _q->_answers[_visAnswers[selection]]->_text, 0);
 				_vm->_gfx->setItemFrame(0, _q->_answers[_visAnswers[selection]]->_mood & 0xF);
 			}
 		}
@@ -300,7 +300,7 @@
 		oldSelection = selection;
 	}
 
-	_vm->_gfx->hideDialogueStuff();
+	_vm->hideDialogueStuff();
 
 	return _visAnswers[selection];
 }

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk.h
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk.h	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk.h	2008-07-09 23:59:05 UTC (rev 32982)
@@ -61,7 +61,7 @@
 	virtual GfxObj* loadHead(const char* name) = 0;
 	virtual Font* loadFont(const char* name) = 0;
 	virtual GfxObj* loadStatic(const char* name) = 0;
-	virtual GfxObj* loadFrames(const char* name) = 0;
+	virtual Frames* loadFrames(const char* name) = 0;
 	virtual void loadSlide(BackgroundInfo& info, const char *filename) = 0;
 	virtual void loadScenery(BackgroundInfo& info, const char* background, const char* mask, const char* path) = 0;
 	virtual Table* loadTable(const char* name) = 0;
@@ -153,7 +153,7 @@
 	GfxObj* loadHead(const char* name);
 	Font* loadFont(const char* name);
 	GfxObj* loadStatic(const char* name);
-	GfxObj* loadFrames(const char* name);
+	Frames* loadFrames(const char* name);
 	void loadSlide(BackgroundInfo& info, const char *filename);
 	void loadScenery(BackgroundInfo& info, const char* background, const char* mask, const char* path);
 	Table* loadTable(const char* name);
@@ -187,7 +187,7 @@
 	GfxObj* loadHead(const char* name);
 	Font* loadFont(const char* name);
 	GfxObj* loadStatic(const char* name);
-	GfxObj* loadFrames(const char* name);
+	Frames* loadFrames(const char* name);
 	void loadSlide(BackgroundInfo& info, const char *filename);
 	void loadScenery(BackgroundInfo& info, const char* background, const char* mask, const char* path);
 	Table* loadTable(const char* name);
@@ -226,7 +226,7 @@
 	GfxObj* loadHead(const char* name);
 	Font* loadFont(const char* name);
 	GfxObj* loadStatic(const char* name);
-	GfxObj* loadFrames(const char* name);
+	Frames* loadFrames(const char* name);
 	void loadSlide(BackgroundInfo& info, const char *filename);
 	void loadScenery(BackgroundInfo& info, const char* name, const char* mask, const char* path);
 	Table* loadTable(const char* name);
@@ -251,7 +251,7 @@
 	GfxObj* loadTalk(const char *name);
 	Font* loadFont(const char* name);
 	GfxObj* loadStatic(const char* name);
-	GfxObj* loadFrames(const char* name);
+	Frames* loadFrames(const char* name);
 	void loadSlide(BackgroundInfo& info, const char *filename);
 	void loadScenery(BackgroundInfo& info, const char* name, const char* mask, const char* path);
 };

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk_br.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk_br.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk_br.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -280,7 +280,7 @@
 	return sprites;
 }
 
-GfxObj* DosDisk_br::loadFrames(const char* name) {
+Frames* DosDisk_br::loadFrames(const char* name) {
 	debugC(5, kDebugDisk, "DosDisk_br::loadFrames");
 
 	char path[PATH_LEN];
@@ -291,7 +291,7 @@
 		errorFileNotFound(path);
 
 
-	return new GfxObj(0, createSprites(stream), name);
+	return createSprites(stream);
 }
 
 // Slides in Nippon Safes are basically screen-sized pictures with valid
@@ -600,13 +600,13 @@
 	return sprites;
 }
 
-GfxObj* AmigaDisk_br::loadFrames(const char* name) {
+Frames* AmigaDisk_br::loadFrames(const char* name) {
 	debugC(1, kDebugDisk, "AmigaDisk_br::loadFrames '%s'", name);
 
 	char path[PATH_LEN];
 	sprintf(path, "%s/anims/%s", _partPath, name);
 
-	return new GfxObj(0, createSprites(path));
+	return createSprites(path);
 }
 
 GfxObj* AmigaDisk_br::loadTalk(const char *name) {

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk_ns.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk_ns.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/disk_ns.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -490,8 +490,8 @@
 	return new GfxObj(0, new SurfaceToFrames(cnv), name);
 }
 
-GfxObj* DosDisk_ns::loadFrames(const char* name) {
-	return new GfxObj(0, loadCnv(name), name);
+Frames* DosDisk_ns::loadFrames(const char* name) {
+	return loadCnv(name);
 }
 
 //
@@ -1258,7 +1258,7 @@
 	return;
 }
 
-GfxObj* AmigaDisk_ns::loadFrames(const char* name) {
+Frames* AmigaDisk_ns::loadFrames(const char* name) {
 	debugC(1, kDebugDisk, "AmigaDisk_ns::loadFrames '%s'", name);
 
 	Common::SeekableReadStream *s;
@@ -1273,7 +1273,7 @@
 	Cnv *cnv = makeCnv(*s);
 	delete s;
 
-	return new GfxObj(0, cnv, name);
+	return cnv;
 }
 
 GfxObj* AmigaDisk_ns::loadHead(const char* name) {

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/exec_br.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/exec_br.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/exec_br.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -100,8 +100,13 @@
 }
 
 void Parallaction_br::clearSubtitles() {
-	_gfx->hideLabel(_subtitle[0]);
-	_gfx->hideLabel(_subtitle[1]);
+	if (_subtitle[0] != -1) {
+		_gfx->hideLabel(_subtitle[0]);
+	}
+
+	if (_subtitle[1] != -1) {
+		_gfx->hideLabel(_subtitle[1]);
+	}
 }
 
 

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/exec_ns.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/exec_ns.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/exec_ns.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -469,7 +469,7 @@
 		}
 
 		_gfx->setHalfbriteMode(true);
-		_gfx->setSingleBalloon(data->_description, 0, 90, 0, 0);
+		_balloonMan->setSingleBalloon(data->_description, 0, 90, 0, 0);
 		Common::Rect r;
 		data->_cnv->getRect(0, r);
 		id = _gfx->setItem(data->_cnv, 140, (_screenHeight - r.height())/2);
@@ -477,7 +477,7 @@
 		id = _gfx->setItem(_char._head, 100, 152);
 		_gfx->setItemFrame(id, 0);
 	} else {
-		_gfx->setSingleBalloon(data->_description, 140, 10, 0, 0);
+		_balloonMan->setSingleBalloon(data->_description, 140, 10, 0, 0);
 		id = _gfx->setItem(_char._talk, 190, 80);
 		_gfx->setItemFrame(id, 0);
 	}

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/gfxbase.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/gfxbase.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/gfxbase.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -32,7 +32,7 @@
 
 namespace Parallaction {
 
-GfxObj::GfxObj(uint objType, Frames *frames, const char* name) : type(objType), _frames(frames), x(0), y(0), z(0), frame(0), layer(3), _flags(0), _keep(true) {
+GfxObj::GfxObj(uint objType, Frames *frames, const char* name) : type(objType), _frames(frames), x(0), y(0), z(0), frame(0), layer(3), _flags(kGfxObjNormal), _keep(true) {
 	if (name) {
 		_name = strdup(name);
 	} else {
@@ -86,12 +86,14 @@
 }
 
 GfxObj* Gfx::loadAnim(const char *name) {
-	GfxObj *obj = _disk->loadFrames(name);
+	Frames* frames = _disk->loadFrames(name);
+	assert(frames);
+
+	GfxObj *obj = new GfxObj(kGfxObjTypeAnim, frames, name);
 	assert(obj);
 
 	// animation Z is not set here, but controlled by game scripts and user interaction.
 	// it is always >=0 and <screen height
-	obj->type = kGfxObjTypeAnim;
 	obj->transparentKey = 0;
 	_gfxobjList.push_back(obj);
 	return obj;
@@ -110,34 +112,43 @@
 }
 
 GfxObj* Gfx::loadDoor(const char *name) {
-	GfxObj *obj = _disk->loadFrames(name);
+	Frames *frames = _disk->loadFrames(name);
+	assert(frames);
+
+	GfxObj *obj = new GfxObj(kGfxObjTypeDoor, frames, name);
 	assert(obj);
 
 	obj->z = kGfxObjDoorZ;	// this preset Z value ensures that doors are drawn first
-	obj->type = kGfxObjTypeDoor;
 	obj->transparentKey = 0;
 	_gfxobjList.push_back(obj);
 	return obj;
 }
 
-void Gfx::clearGfxObjects() {
-	_gfxobjList.clear();
+void Gfx::clearGfxObjects(uint filter) {
+
+	GfxObjList::iterator b = _gfxobjList.begin();
+	GfxObjList::iterator e = _gfxobjList.end();
+
+	for ( ; b != e; ) {
+		if (((*b)->_flags & filter) != 0) {
+			b = _gfxobjList.erase(b);
+		} else {
+			b++;
+		}
+	}
+
 }
 
 void Gfx::showGfxObj(GfxObj* obj, bool visible) {
-//	if (!obj || obj->isVisible() == visible) {
-//		return;
-//	}
+	if (!obj) {
+		return;
+	}
 
-	assert(obj);
-
 	if (visible) {
 		obj->setFlags(kGfxObjVisible);
 	} else {
 		obj->clearFlags(kGfxObjVisible);
-//		_gfxobjList.remove(obj);
 	}
-
 }
 
 
@@ -181,9 +192,7 @@
 
 	sortAnimations();
 	// TODO: some zones don't appear because of wrong masking (3 or 0?)
-	// TODO: Dr.Ki is not visible inside the club
 
-
 	GfxObjList::iterator b = _gfxobjList.begin();
 	GfxObjList::iterator e = _gfxobjList.end();
 

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/graphics.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/graphics.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/graphics.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -64,11 +64,7 @@
 
 
 #define	LABEL_TRANSPARENT_COLOR 0xFF
-#define	BALLOON_TRANSPARENT_COLOR 2
 
-
-int16 Gfx::_dialogueBalloonX[5] = { 80, 120, 150, 150, 150 };
-
 void halfbritePixel(int x, int y, int color, void *data) {
 	byte *buffer = (byte*)data;
 	buffer[x + y * _vm->_screenWidth] &= ~0x20;
@@ -238,38 +234,7 @@
 }
 
 
-#define BALLOON_TAIL_WIDTH	12
-#define BALLOON_TAIL_HEIGHT	10
 
-
-byte _resBalloonTail[2][BALLOON_TAIL_WIDTH*BALLOON_TAIL_HEIGHT] = {
-	{
-	  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02,
-	  0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02,
-	  0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
-	  0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
-	  0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
-	  0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02,
-	  0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
-	  0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	  0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	  0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	},
-	{
-	  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02,
-	  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02,
-	  0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
-	  0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
-	  0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-	  0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
-	  0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02,
-	  0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
-	  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02,
-	  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02
-	}
-};
-
-
 void Gfx::setPalette(Palette pal) {
 	byte sysPal[256*4];
 
@@ -362,15 +327,13 @@
 }
 
 void Gfx::drawBalloons() {
-	if (_numBalloons == 0) {
+	if (_balloons.size() == 0) {
 		return;
 	}
 
 	Graphics::Surface *surf = g_system->lockScreen();
-	for (uint i = 0; i < _numBalloons; i++) {
-		Common::Rect r(_balloons[i].surface.w, _balloons[i].surface.h);
-		r.moveTo(_balloons[i].x, _balloons[i].y);
-		blt(r, (byte*)_balloons[i].surface.getBasePtr(0, 0), surf, LAYER_FOREGROUND, BALLOON_TRANSPARENT_COLOR);
+	for (uint i = 0; i < _balloons.size(); i++) {
+		drawGfxObject(_balloons[i], *surf, false);
 	}
 	g_system->unlockScreen();
 }
@@ -686,6 +649,7 @@
 		delete _labels[i];
 	}
 	_labels.clear();
+	_floatingLabel = NO_FLOATING_LABEL;
 }
 
 void Gfx::drawLabels() {
@@ -779,7 +743,6 @@
 
 	setPalette(_palette);
 
-	_numBalloons = 0;
 	_numItems = 0;
 	_floatingLabel = NO_FLOATING_LABEL;
 
@@ -804,6 +767,7 @@
 Gfx::~Gfx() {
 
 	freeBackground();
+	freeLabels();
 
 	return;
 }
@@ -830,138 +794,31 @@
 	_items[item].data->setFlags(kGfxObjVisible);
 }
 
-Gfx::Balloon* Gfx::getBalloon(uint id) {
-	assert(id < _numBalloons);
-	return &_balloons[id];
-}
 
-int Gfx::createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness) {
-	assert(_numBalloons < 5);
+GfxObj* Gfx::registerBalloon(Frames *frames, const char *text) {
 
-	int id = _numBalloons;
+	GfxObj *obj = new GfxObj(kGfxObjTypeBalloon, frames, text);
 
-	Gfx::Balloon *balloon = &_balloons[id];
+	obj->layer = LAYER_FOREGROUND;
+	obj->frame = 0;
+	obj->setFlags(kGfxObjVisible);
 
-	int16 real_h = (winding == -1) ? h : h + 9;
-	balloon->surface.create(w, real_h, 1);
-	balloon->surface.fillRect(Common::Rect(w, real_h), BALLOON_TRANSPARENT_COLOR);
+	_balloons.push_back(obj);
 
-	Common::Rect r(w, h);
-	balloon->surface.fillRect(r, 0);
-	balloon->outerBox = r;
-
-	r.grow(-borderThickness);
-	balloon->surface.fillRect(r, 1);
-	balloon->innerBox = r;
-
-	if (winding != -1) {
-		// draws tail
-		// TODO: this bitmap tail should only be used for Dos games. Amiga should use a polygon fill.
-		winding = (winding == 0 ? 1 : 0);
-		Common::Rect s(BALLOON_TAIL_WIDTH, BALLOON_TAIL_HEIGHT);
-		s.moveTo(r.width()/2 - 5, r.bottom - 1);
-		blt(s, _resBalloonTail[winding], &balloon->surface, LAYER_FOREGROUND, BALLOON_TRANSPARENT_COLOR);
-	}
-
-	_numBalloons++;
-
-	return id;
+	return obj;
 }
 
-int Gfx::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) {
-
-	int16 w, h;
-
-	getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
-
-	int id = createBalloon(w+5, h, winding, 1);
-	Gfx::Balloon *balloon = &_balloons[id];
-
-	drawWrappedText(_vm->_dialogueFont, &balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
-
-	balloon->x = x;
-	balloon->y = y;
-
-	return id;
-}
-
-int Gfx::setDialogueBalloon(char *text, uint16 winding, byte textColor) {
-
-	int16 w, h;
-
-	getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
-
-	int id = createBalloon(w+5, h, winding, 1);
-	Gfx::Balloon *balloon = &_balloons[id];
-
-	drawWrappedText(_vm->_dialogueFont, &balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
-
-	balloon->x = _dialogueBalloonX[id];
-	balloon->y = 10;
-
-	if (id > 0) {
-		balloon->y += _balloons[id - 1].y + _balloons[id - 1].outerBox.height();
+void Gfx::destroyBalloons() {
+	for (uint i = 0; i < _balloons.size(); i++) {
+		delete _balloons[i];
 	}
-
-
-	return id;
+	_balloons.clear();
 }
 
-void Gfx::setBalloonText(uint id, char *text, byte textColor) {
-	Gfx::Balloon *balloon = getBalloon(id);
-	balloon->surface.fillRect(balloon->innerBox, 1);
-	drawWrappedText(_vm->_dialogueFont, &balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
-}
-
-
-int Gfx::setLocationBalloon(char *text, bool endGame) {
-
-	int16 w, h;
-
-	getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
-
-	int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR);
-	Gfx::Balloon *balloon = &_balloons[id];
-	drawWrappedText(_vm->_dialogueFont, &balloon->surface, text, 0, MAX_BALLOON_WIDTH);
-
-	balloon->x = 5;
-	balloon->y = 5;
-
-	return id;
-}
-
-int Gfx::hitTestDialogueBalloon(int x, int y) {
-
-	Common::Point p;
-
-	for (uint i = 0; i < _numBalloons; i++) {
-		p.x = x - _balloons[i].x;
-		p.y = y - _balloons[i].y;
-
-		if (_balloons[i].innerBox.contains(p))
-			return i;
-	}
-
-	return -1;
-}
-
-
-void Gfx::freeBalloons() {
-	for (uint i = 0; i < _numBalloons; i++) {
-		_balloons[i].surface.free();
-	}
-	_numBalloons = 0;
-}
-
 void Gfx::freeItems() {
 	_numItems = 0;
 }
 
-void Gfx::hideDialogueStuff() {
-	freeItems();
-	freeBalloons();
-}
-
 void Gfx::freeBackground() {
 	_backgroundInfo.free();
 }

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/graphics.h
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/graphics.h	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/graphics.h	2008-07-09 23:59:05 UTC (rev 32982)
@@ -340,11 +340,15 @@
 enum {
 	kGfxObjVisible = 1,
 
+	kGfxObjNormal = 2,
+	kGfxObjCharacter = 4,
 
 	kGfxObjTypeDoor = 0,
 	kGfxObjTypeGet = 1,
 	kGfxObjTypeAnim = 2,
-	kGfxObjTypeLabel = 3
+	kGfxObjTypeLabel = 3,
+	kGfxObjTypeBalloon = 4,
+	kGfxObjTypeCharacter = 8
 };
 
 enum {
@@ -355,7 +359,6 @@
 class GfxObj {
 	char *_name;
 	Frames *_frames;
-	uint32 _flags;
 
 	bool _keep;
 
@@ -364,6 +367,7 @@
 
 	int32 z;
 
+	uint32 _flags;
 
 	uint type;
 	uint frame;
@@ -449,6 +453,20 @@
 	kBackgroundSlide = 2
 };
 
+
+class BalloonManager {
+public:
+	virtual ~BalloonManager() { }
+
+	virtual void freeBalloons() = 0;
+	virtual int setLocationBalloon(char *text, bool endGame) = 0;
+	virtual int setDialogueBalloon(char *text, uint16 winding, byte textColor) = 0;
+	virtual int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) = 0;
+	virtual void setBalloonText(uint id, char *text, byte textColor) = 0;
+	virtual int hitTestDialogueBalloon(int x, int y) = 0;
+};
+
+
 typedef Common::HashMap<Common::String, int32, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> VarMap;
 
 class Gfx {
@@ -463,7 +481,7 @@
 	GfxObj* loadDoor(const char *name);
 	void drawGfxObjects(Graphics::Surface &surf);
 	void showGfxObj(GfxObj* obj, bool visible);
-	void clearGfxObjects();
+	void clearGfxObjects(uint filter);
 	void sortAnimations();
 
 
@@ -478,12 +496,9 @@
 	void freeLabels();
 
 	// dialogue balloons
-	int setLocationBalloon(char *text, bool endGame);
-	int setDialogueBalloon(char *text, uint16 winding, byte textColor);
-	int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor);
-	void setBalloonText(uint id, char *text, byte textColor);
-	int hitTestDialogueBalloon(int x, int y);
 	void getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height);
+	GfxObj* registerBalloon(Frames *frames, const char *text);
+	void destroyBalloons();
 
 	// other items
 	int setItem(GfxObj* obj, uint16 x, uint16 y, byte transparentColor = 0);
@@ -549,19 +564,7 @@
 	int32 				getRenderMode(const char *type);
 
 public:
-	static int16 _dialogueBalloonX[5];
 
-	struct Balloon {
-		uint16 x;
-		uint16 y;
-		Common::Rect outerBox;
-		Common::Rect innerBox;
-		uint16 winding;
-		Graphics::Surface surface;
-	} _balloons[5];
-
-	uint	_numBalloons;
-
 	struct Item {
 		GfxObj *data;
 	} _items[14];
@@ -573,6 +576,7 @@
 
 	typedef Common::Array<GfxObj*> GfxObjArray;
 	GfxObjArray	_labels;
+	GfxObjArray _balloons;
 
 	uint _floatingLabel;
 
@@ -584,9 +588,6 @@
 
 	void copyRect(const Common::Rect &r, Graphics::Surface &src, Graphics::Surface &dst);
 
-	int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness);
-	Balloon *getBalloon(uint id);
-
 	// low level text and patches
 	void drawText(Font *font, Graphics::Surface* surf, uint16 x, uint16 y, const char *text, byte color);
 	void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth);

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/gui_br.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/gui_br.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/gui_br.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -195,7 +195,7 @@
 	}
 
 	_system->showMouse(false);
-	_gfx->hideDialogueStuff();
+	hideDialogueStuff();
 
 	for (i = 0; i < availItems; i++) {
 		delete _lines[i];

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/input.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/input.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/input.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -174,7 +174,7 @@
 void Input::updateCommentInput() {
 	waitUntilLeftClick();
 
-	_vm->_gfx->hideDialogueStuff();
+	_vm->hideDialogueStuff();
 	_vm->_gfx->setHalfbriteMode(false);
 
 	_inputMode = kInputModeGame;

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/module.mk
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/module.mk	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/module.mk	2008-07-09 23:59:05 UTC (rev 32982)
@@ -1,6 +1,7 @@
 MODULE := engines/parallaction
 
 MODULE_OBJS := \
+	balloons.o \
 	callables_br.o \
 	callables_ns.o \
 	debug.o \

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/objects.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/objects.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/objects.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -54,6 +54,7 @@
 
 Animation::~Animation() {
 	free(_scriptName);
+	gfxobj->release();
 }
 
 uint16 Animation::width() const {
@@ -182,6 +183,8 @@
 		break;
 	}
 
+
+	free(_linkedName);
 }
 
 void Zone::getRect(Common::Rect& r) const {

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -91,6 +91,9 @@
 	delete _globalTable;
 	delete _callableNames;
 
+	_gfx->clearGfxObjects(kGfxObjCharacter | kGfxObjNormal);
+	hideDialogueStuff();
+	delete _balloonMan;
 	freeLocation();
 
 	freeCharacter();
@@ -134,6 +137,8 @@
 
 	_debugger = new Debugger(this);
 
+	setupBalloonManager();
+
 	return 0;
 }
 
@@ -164,6 +169,8 @@
 	delete _objectsNames;
 	_objectsNames = 0;
 
+	_gfx->clearGfxObjects(kGfxObjCharacter);
+
 	_char.free();
 
 	return;
@@ -246,7 +253,7 @@
 
 	_location._walkNodes.clear();
 
-	_gfx->clearGfxObjects();
+	_gfx->clearGfxObjects(kGfxObjNormal);
 	freeBackground();
 
 	_location._programs.clear();
@@ -281,7 +288,7 @@
 }
 
 void Parallaction::showLocationComment(const char *text, bool end) {
-	_gfx->setLocationBalloon(const_cast<char*>(text), end);
+	_balloonMan->setLocationBalloon(const_cast<char*>(text), end);
 }
 
 
@@ -422,7 +429,7 @@
 
 	showLocationComment(_location._comment, false);
 	_input->waitUntilLeftClick();
-	_gfx->freeBalloons();
+	_balloonMan->freeBalloons();
 
 	// fades maximum intensity palette towards approximation of main palette
 	for (uint16 _si = 0; _si<6; _si++) {
@@ -567,10 +574,14 @@
 	const char *end = begin + strlen(name);
 
 	_prefix = _empty;
+	_suffix = _empty;
 
 	_dummy = IS_DUMMY_CHARACTER(name);
 
 	if (!_dummy) {
+		if (!strstr(name, "donna")) {
+			_engineFlags &= ~kEngineTransformedDonna;
+		} else
 		if (_engineFlags & kEngineTransformedDonna) {
 			_suffix = _suffixTras;
 		} else {
@@ -579,8 +590,6 @@
 				_engineFlags |= kEngineTransformedDonna;
 				_suffix = _suffixTras;
 				end = s;
-			} else {
-				_suffix = _empty;
 			}
 		}
 		if (IS_MINI_CHARACTER(name)) {

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction.h
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction.h	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction.h	2008-07-09 23:59:05 UTC (rev 32982)
@@ -429,6 +429,15 @@
 	Inventory *_inventory;
 	InventoryRenderer *_inventoryRenderer;
 
+	BalloonManager *_balloonMan;
+
+	void setupBalloonManager();
+
+	void hideDialogueStuff() {
+		_gfx->freeItems();
+		_balloonMan->freeBalloons();
+	}
+
 };
 
 

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction_br.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction_br.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction_br.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -80,6 +80,9 @@
 
 	_part = -1;
 
+	_subtitle[0] = -1;
+	_subtitle[1] = -1;
+
 	Parallaction::init();
 
 	return 0;
@@ -221,7 +224,7 @@
 	// free open location stuff
 	clearSubtitles();
 	freeBackground();
-	_gfx->clearGfxObjects();
+	_gfx->clearGfxObjects(kGfxObjNormal | kGfxObjCharacter);
 	_location._programs.clear();
 	freeZones();
 	freeAnimations();

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction_ns.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction_ns.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/parallaction_ns.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -306,6 +306,7 @@
 		setArrowCursor();
 	}
 
+	_gfx->showGfxObj(_char._ani->gfxobj, false);
 	_location._animations.remove(_char._ani);
 
 	freeLocation();
@@ -327,6 +328,7 @@
 	}
 
 	_location._animations.push_front(_char._ani);
+	_gfx->showGfxObj(_char._ani->gfxobj, true);
 
 	strcpy(_saveData1, locname.location());
 	parseLocation(_saveData1);
@@ -411,6 +413,7 @@
 
 	Common::String oldArchive = _disk->selectArchive((getFeatures() & GF_DEMO) ? "disk0" : "disk1");
 	_char._ani->gfxobj = _gfx->loadAnim(_char.getFullName());
+	_char._ani->gfxobj->setFlags(kGfxObjCharacter);
 
 	if (!_char.dummy()) {
 		if (getPlatform() == Common::kPlatformAmiga) {

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/parser_br.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/parser_br.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/parser_br.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -390,7 +390,7 @@
 
 	if ((_vm->getLocationFlags() & kFlagsVisited) == 0) {
 		// only for 1st visit
-		_vm->clearLocationFlags(kFlagsAll);
+		_vm->clearLocationFlags((uint32)kFlagsAll);
 		int _si = 1;
 
 		do {

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/parser_ns.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/parser_ns.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/parser_ns.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -1059,7 +1059,7 @@
 
 	if ((_vm->getLocationFlags() & kFlagsVisited) == 0) {
 		// only for 1st visit
-		_vm->clearLocationFlags(kFlagsAll);
+		_vm->clearLocationFlags((uint32)kFlagsAll);
 		int _si = 1;
 
 		do {

Modified: scummvm/branches/gsoc2008-tfmx/engines/parallaction/sound.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/parallaction/sound.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/parallaction/sound.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -249,6 +249,9 @@
 }
 
 void DosSoundMan::playCharacterMusic(const char *character) {
+	if (character == NULL) {
+		return;
+	}
 
 	if (!scumm_stricmp(_vm->_location._name, "night") ||
 		!scumm_stricmp(_vm->_location._name, "intsushi")) {

Modified: scummvm/branches/gsoc2008-tfmx/engines/scumm/imuse_digi/dimuse_track.h
===================================================================
--- scummvm/branches/gsoc2008-tfmx/engines/scumm/imuse_digi/dimuse_track.h	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/engines/scumm/imuse_digi/dimuse_track.h	2008-07-09 23:59:05 UTC (rev 32982)
@@ -85,13 +85,15 @@
 	int getPan() const { return (pan != 64) ? 2 * pan - 127 : 0; }
 	int getVol() const { return vol / 1000; }
 	Audio::Mixer::SoundType getType() const {
-		Audio::Mixer::SoundType type = Audio::Mixer::kPlainSoundType;
+		Audio::Mixer::SoundType type;
 		if (volGroupId == 1)
 			type = Audio::Mixer::kSpeechSoundType;
 		else if (volGroupId == 2)
 			type = Audio::Mixer::kSFXSoundType;
 		else if (volGroupId == 3)
 			type = Audio::Mixer::kMusicSoundType;
+		else
+			error("Track::getType(): invalid sound type");
 		return type;
 	}
 };

Modified: scummvm/branches/gsoc2008-tfmx/sound/midiparser_smf.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/sound/midiparser_smf.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/sound/midiparser_smf.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -85,16 +85,26 @@
 
 	_position._running_status = info.event;
 	switch (info.command()) {
-	case 0xC: case 0xD:
+	case 0x9: // Note On
 		info.basic.param1 = *(_position._play_pos++);
+		info.basic.param2 = *(_position._play_pos++);
+		if (info.basic.param2 == 0)
+			info.event = info.channel() | 0x80;
+		info.length = 0;
+		break;
+
+	case 0xC:
+	case 0xD:
+		info.basic.param1 = *(_position._play_pos++);
 		info.basic.param2 = 0;
 		break;
 
-	case 0x8: case 0x9: case 0xA: case 0xB: case 0xE:
+	case 0x8:
+	case 0xA:
+	case 0xB:
+	case 0xE:
 		info.basic.param1 = *(_position._play_pos++);
 		info.basic.param2 = *(_position._play_pos++);
-		if (info.command() == 0x9 && info.basic.param2 == 0)
-			info.event = info.channel() | 0x80;
 		info.length = 0;
 		break;
 
@@ -110,7 +120,12 @@
 			info.basic.param2 = 0;
 			break;
 
-		case 0x6: case 0x8: case 0xA: case 0xB: case 0xC: case 0xE:
+		case 0x6:
+		case 0x8:
+		case 0xA:
+		case 0xB:
+		case 0xC:
+		case 0xE:
 			info.basic.param1 = info.basic.param2 = 0;
 			break;
 

Modified: scummvm/branches/gsoc2008-tfmx/sound/midiparser_xmidi.cpp
===================================================================
--- scummvm/branches/gsoc2008-tfmx/sound/midiparser_xmidi.cpp	2008-07-09 23:53:28 UTC (rev 32981)
+++ scummvm/branches/gsoc2008-tfmx/sound/midiparser_xmidi.cpp	2008-07-09 23:59:05 UTC (rev 32982)
@@ -38,6 +38,14 @@
 	NoteTimer _notes_cache[32];
 	uint32 _inserted_delta; // Track simulated deltas for note-off events
 
+	struct Loop {
+		byte *pos;
+		byte repeat;
+	};
+
+	Loop _loop[4];
+	int _loopCount;
+
 protected:
 	uint32 readVLQ2(byte * &data);
 	void resetTracking();
@@ -78,16 +86,56 @@
 		}
 		break;
 
-	case 0xC: case 0xD:
+	case 0xC:
+	case 0xD:
 		info.basic.param1 = *(_position._play_pos++);
 		info.basic.param2 = 0;
 		break;
 
-	case 0x8: case 0xA: case 0xB: case 0xE:
+	case 0x8:
+	case 0xA:
+	case 0xE:
 		info.basic.param1 = *(_position._play_pos++);
 		info.basic.param2 = *(_position._play_pos++);
 		break;
 
+	case 0xB:
+		info.basic.param1 = *(_position._play_pos++);
+		info.basic.param2 = *(_position._play_pos++);
+
+		// Simplified XMIDI looping.
+		//
+		// I would really like to turn the loop events into some sort
+		// of NOP event (perhaps a dummy META event?), but for now we
+		// just pass them on to the MIDI driver. That has worked in the
+		// past, so it shouldn't cause any actual damage...
+
+		if (info.basic.param1 == 0x74) {
+			// XMIDI_CONTROLLER_FOR_LOOP
+			byte *pos = _position._play_pos;
+			if (_loopCount < ARRAYSIZE(_loop) - 1)
+				_loopCount++;
+
+			_loop[_loopCount].pos = pos;
+			_loop[_loopCount].repeat = info.basic.param2;
+		} else if (info.basic.param1 == 0x75) {
+			// XMIDI_CONTROLLER_NEXT_BREAK
+			if (_loopCount >= 0) {
+				if (info.basic.param2 < 64) {
+					// End the current loop.
+					_loopCount--;
+				} else {
+					_position._play_pos = _loop[_loopCount].pos;
+					// Repeat 0 means "loop forever".
+					if (_loop[_loopCount].repeat) {
+						if (--_loop[_loopCount].repeat == 0)
+							_loopCount--;
+					}
+				}
+			}
+		}
+		break;
+
 	case 0xF: // Meta or SysEx event
 		switch (info.event & 0x0F) {
 		case 0x2: // Song Position Pointer
@@ -100,7 +148,12 @@
 			info.basic.param2 = 0;
 			break;
 
-		case 0x6: case 0x8: case 0xA: case 0xB: case 0xC: case 0xE:
+		case 0x6:
+		case 0x8:
+		case 0xA:
+		case 0xB:
+		case 0xC:
+		case 0xE:
 			info.basic.param1 = info.basic.param2 = 0;
 			break;
 
@@ -136,6 +189,8 @@
 	uint32 chunk_len;
 	char buf[32];
 
+	_loopCount = -1;
+
 	unloadMusic();
 	byte *pos = data;
 


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