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

cpage88 at users.sourceforge.net cpage88 at users.sourceforge.net
Sat Aug 16 06:30:04 CEST 2008


Revision: 33924
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33924&view=rev
Author:   cpage88
Date:     2008-08-16 04:30:01 +0000 (Sat, 16 Aug 2008)

Log Message:
-----------
Merged revisions 33777,33781-33788,33790,33792-33793,33795,33797,33805,33807-33812,33815-33817,33819,33822,33826,33829,33837,33839,33844,33847,33858-33861,33864,33871-33873,33875,33877-33879,33886,33889-33892,33894,33896,33900,33902-33903,33919 via svnmerge from 
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk

Modified Paths:
--------------
    scummvm/branches/gsoc2008-rtl/backends/fs/windows/windows-fs.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/symbian/README
    scummvm/branches/gsoc2008-rtl/backends/platform/symbian/src/SymbianActions.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/wii/Makefile
    scummvm/branches/gsoc2008-rtl/backends/platform/wii/gx_supp.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/wii/gx_supp.h
    scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem.h
    scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem_gfx.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEActionsPocket.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEActionsSmartphone.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEkeys/EventsBuffer.cpp
    scummvm/branches/gsoc2008-rtl/backends/platform/wince/wince-sdl.cpp
    scummvm/branches/gsoc2008-rtl/dists/wii/READMII
    scummvm/branches/gsoc2008-rtl/engines/agi/sound.cpp
    scummvm/branches/gsoc2008-rtl/engines/agi/sound.h
    scummvm/branches/gsoc2008-rtl/engines/cine/cine.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/gfx.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/gfx.h
    scummvm/branches/gsoc2008-rtl/engines/cine/main_loop.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/msg.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/pal.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/pal.h
    scummvm/branches/gsoc2008-rtl/engines/cine/part.cpp
    scummvm/branches/gsoc2008-rtl/engines/cine/part.h
    scummvm/branches/gsoc2008-rtl/engines/cine/sound.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/cine/various.h
    scummvm/branches/gsoc2008-rtl/engines/gob/mult_v2.cpp
    scummvm/branches/gsoc2008-rtl/engines/kyra/detection.cpp
    scummvm/branches/gsoc2008-rtl/engines/kyra/lol.cpp
    scummvm/branches/gsoc2008-rtl/engines/kyra/resource.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/balloons.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/callables_br.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/callables_ns.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/debug.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/dialogue.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/disk.h
    scummvm/branches/gsoc2008-rtl/engines/parallaction/disk_br.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/exec.h
    scummvm/branches/gsoc2008-rtl/engines/parallaction/exec_br.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/exec_ns.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/graphics.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/graphics.h
    scummvm/branches/gsoc2008-rtl/engines/parallaction/objects.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/objects.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/parser.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/parser.h
    scummvm/branches/gsoc2008-rtl/engines/parallaction/parser_br.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/parser_ns.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/saveload.cpp
    scummvm/branches/gsoc2008-rtl/engines/parallaction/walk.cpp
    scummvm/branches/gsoc2008-rtl/engines/scumm/boxes.cpp
    scummvm/branches/gsoc2008-rtl/engines/scumm/detection.cpp
    scummvm/branches/gsoc2008-rtl/engines/scumm/script_v5.cpp

Property Changed:
----------------
    scummvm/branches/gsoc2008-rtl/
    scummvm/branches/gsoc2008-rtl/dists/
    scummvm/branches/gsoc2008-rtl/dists/msvc7/
    scummvm/branches/gsoc2008-rtl/dists/msvc71/
    scummvm/branches/gsoc2008-rtl/dists/msvc8/
    scummvm/branches/gsoc2008-rtl/dists/msvc9/


Property changes on: scummvm/branches/gsoc2008-rtl
___________________________________________________________________
Modified: svnmerge-integrated
   - /scummvm/trunk:1-33768
   + /scummvm/trunk:1-33923

Modified: scummvm/branches/gsoc2008-rtl/backends/fs/windows/windows-fs.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/fs/windows/windows-fs.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/fs/windows/windows-fs.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -227,8 +227,7 @@
 		char path[MAX_PATH];
 		GetCurrentDirectory(MAX_PATH, path);
 		_path = path;
-	}
-	else {
+	} else {
 		assert(p.size() > 0);
 		_path = p;
 	}

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/symbian/README
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/symbian/README	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/symbian/README	2008-08-16 04:30:01 UTC (rev 33924)
@@ -1,11 +1,11 @@
 
  ScummVM - ScummVM ported to EPOC/SymbianOS
 
- Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson
- Copyright (C) 2007 Lars 'AnotherGuest' Persson
- Copyright (C) 2007 Jurgen 'SumthinWicked' Braam
- Copyright (C) 2007 ScummVM Team
+ Copyright (C) 2008 ScummVM Team
+ Copyright (C) 2003-2008 Lars 'AnotherGuest' Persson
+ Copyright (C) 2002008 Jurgen 'SumthinWicked' Braam
 
+ Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson
  $Id$
 
 
@@ -13,22 +13,22 @@
 --------------
 	The original ports (uptil 0.7.1) were made by Andreas Karlsson and Lars Persson.
 	The main transition to 0.8.0CVS and all relevant changes were done by Jurgen Braam.
-	Jurgen and Lars have successfully transfered all needed changes into CVS, with additional helpful tools for Symbian OS
+	Jurgen and Lars have successfully transfered all needed changes into CVS/SVN, with additional helpful tools for Symbian OS
 
-	Release version: 0.10.0
+	Release version: 0.12.0
 	* This version is only supported on Symbian OS 9 devices due to compiler constraints for older devices. (That means UIQ3 and S60V3 devices)
-	* Updated to SDL version 1.2.11 (previous version used was 1.2.8)
+	* Updated to SDL version 1.2.13 (previous version used was 1.2.2)
 	* Information about S60 devices can be found here http://wiki.scummvm.org/index.php/SymbianOS_S60
 	* Information about UIQ devices can be found here http://wiki.scummvm.org/index.php/SymbianOS_UIQ
 	* Best source of general information is the ScummVM forum, http://forums.scummvm.org
-	* SVN builds (not frequently updated) can be found at http://anotherguest.k0.se
+	* SVN builds (not frequently updated) can be found at http://www.anotherguest.se
 
 
 Games supported
 ---------------
 	The Symbian port of ScummVM supports all but Sword1 & 2 games. Some games might not run properly due to screenresolution or memory constraints.
+	Minimum free memory requirement is about 12MB to be able to start and run ScummVM, this is enough for most older games, but newer more resource hungry games, might require more.
 
-
 Building ScummVM
 ---------------------
 
@@ -38,7 +38,7 @@
 	Lets just say the framework needs quite some time to set up and takes a while
 	to get used to. If you choose to continue you will need the following items:
 
-	- UIQ 3.0 SDK (To build for UIQ3 devices)
+	- UIQ 3.x SDK (To build for UIQ3 devices)(Build scripts in SDK need tweaking in order to build scummvm since Symbian OS GCCE never builds as large projects as ScummVM before)
 	- UIQ 2.1 SDK (To build for UIQ2 devices);
 	  http://www.symbian.com/developer/sdks_uiq.asp
 
@@ -72,9 +72,8 @@
 	  http://flac.sourceforge.net/
 
 	- libmpeg2, a free MPEG-2 video stream decoder
-	  http://libmpeg2.sourceforge.net/
+	  http://libmpeg2.sourceforge.net
 
-
 	Compiling ScummVM
 	-----------------
 
@@ -89,7 +88,7 @@
 	PETRAN.EXE will be the executable that is started.
 
 
-	SDL: the latest version of SDL at this point in time is 1.2.12. This version
+	SDL: the latest version of SDL at this point in time is 1.2.13. This version
 	works great for compiling on other platforms.
 
 	zlib: the zlib-x.x.x.tar.gz does not come with UIQ .mpp build files, that's why

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/symbian/src/SymbianActions.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/symbian/src/SymbianActions.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/symbian/src/SymbianActions.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -129,12 +129,12 @@
 	bool is_simon = (strncmp(gameid.c_str(), "simon", 5) == 0);
 	bool is_sword1 = (gameid == "sword1");
 	bool is_sword2 = (strcmp(gameid.c_str(), "sword2") == 0);
-	bool is_sky = (strncmp(gameid.c_str(), "sky", 3) == 0);
-	bool is_saga = (gameid == "saga");
+	bool is_queen = (gameid == "queen");
+	bool is_sky = (gameid == "sky");
 	bool is_comi = (strncmp(gameid.c_str(), "comi", 4) == 0);
-	bool is_queen = (strncmp(gameid.c_str(), "queen", 5) == 0);
 	bool is_gob = (strncmp(gameid.c_str(), "gob", 3) == 0);
-	bool is_kyra = (gameid == "kyra1");
+	bool is_saga = (gameid == "saga");
+	bool is_kyra = (strncmp(gameid.c_str(), "kyra",4) == 0);
 	bool is_samnmax = (gameid == "samnmax");
 	bool is_cine = (gameid == "cine");
 	bool is_touche = (gameid == "touche");
@@ -142,6 +142,7 @@
 	bool is_parallaction = (gameid == "parallaction");
 	bool is_lure = (gameid == "lure");
 	bool is_feeble = (gameid == "feeble");
+	bool is_drascula = (strncmp(gameid.c_str(), "drascula",8) == 0);
 
 	Actions::initInstanceGame();
 
@@ -152,16 +153,16 @@
 
 
 	// Save
-	if (is_simon || is_sword2 || is_gob || is_kyra || is_touche)
+	if (is_simon || is_sword2 || is_gob || is_kyra || is_touche || is_feeble)
 		_action_enabled[ACTION_SAVE] = false;
 	else {
 		_action_enabled[ACTION_SAVE] = true;
 
 		if (is_queen) {
-			_key_action[ACTION_SAVE].setKey(Common::ASCII_F5, Common::KEYCODE_F5); // F1 key for FOTAQ
+			_key_action[ACTION_SAVE].setKey(Common::ASCII_F1, Common::KEYCODE_F1); // F1 key for FOTAQ
 		} else if (is_sky) {
 			_key_action[ACTION_SAVE].setKey(Common::ASCII_F5, Common::KEYCODE_F5);
-		} else if (is_cine) {
+		} else if (is_cine || is_drascula) {
 			_key_action[ACTION_SAVE].setKey(Common::ASCII_F10, Common::KEYCODE_F10); // F10
 		} else if (is_agi) {
 			_key_action[ACTION_SAVE].setKey(Common::ASCII_ESCAPE, Common::KEYCODE_ESCAPE);
@@ -177,7 +178,8 @@
 	// Skip text
 	if (!is_cine && !is_parallaction)
 		_action_enabled[ACTION_SKIP_TEXT] = true;
-	if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || is_saga || is_kyra || is_touche || is_lure || is_feeble)
+	if (is_simon || is_sky || is_sword2 || is_queen || is_sword1 || is_gob || 
+		is_saga || is_kyra || is_touche || is_lure || is_feeble || is_drascula)
 		_key_action[ACTION_SKIP_TEXT].setKey(Common::KEYCODE_ESCAPE, Common::KEYCODE_ESCAPE); // Escape key
 	else {
 		_key_action[ACTION_SKIP_TEXT].setKey(SDLK_PERIOD);

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wii/Makefile
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wii/Makefile	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wii/Makefile	2008-08-16 04:30:01 UTC (rev 33924)
@@ -154,8 +154,10 @@
 distclean-wii:
 	@-$(RM) dist
 
+upload:
 ifeq ($(GAMECUBE),1)
-upload:
+	$(DEVKITPPC)/bin/geckoupload $(TARGET).dol
+else
 	$(DEVKITPPC)/bin/wiiload $(TARGET).dol
 endif
 
@@ -167,6 +169,7 @@
 	$(CP) $(TARGET).dol dist/scummvm/boot.dol
 	$(CP) $(DISTPATH)/meta.xml dist/scummvm/
 	$(CP) $(DISTPATH)/icon.png dist/scummvm/
+endif
 	$(CP) $(DISTPATH)/READMII dist/scummvm/
 	$(CP) $(srcdir)/AUTHORS dist/scummvm/
 	$(CP) $(srcdir)/COPYING dist/scummvm/
@@ -175,5 +178,4 @@
 	$(CP) $(srcdir)/README dist/scummvm/
 	$(CP) $(DIST_FILES_THEMES) dist/scummvm/
 	$(CP) $(DIST_FILES_ENGINEDATA) dist/scummvm/
-endif
 

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wii/gx_supp.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wii/gx_supp.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wii/gx_supp.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -1,6 +1,7 @@
 /****************************************************************************
 *	Generic GX Support for Emulators
 *	softdev 2007
+*	dhewg 2008
 *
 *	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
@@ -21,12 +22,13 @@
 * These are pretty standard functions to setup and use GX scaling.
 ****************************************************************************/
 
-#include <gccore.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <malloc.h>
 
+#include "gx_supp.h"
+
 #define DEFAULT_FIFO_SIZE (256 * 1024)
 
 #define HASPECT 320
@@ -39,18 +41,19 @@
 /*** 2D ***/
 static u32 whichfb;
 static u32 *xfb[2];
-static GXRModeObj *vmode;
+GXRModeObj *vmode = NULL;
 
 /*** 3D GX ***/
 static u8 *gp_fifo;
 
 /*** Texture memory ***/
-static u8 *texturemem;
+static u8 *texturemem = NULL;
 static u32 texturesize;
 
-GXTexObj texobj;
+static GXTexObj texobj;
 static Mtx view;
 static u16 vwidth, vheight, oldvwidth, oldvheight;
+static float tex_xT = 0.0f, tex_yT = 0.0f;
 
 /* New texture based scaler */
 typedef struct tagcamera {
@@ -74,6 +77,10 @@
 
 void GX_InitVideo() {
 	vmode = VIDEO_GetPreferredMode(NULL);
+
+	vmode->viWidth = 678;
+	vmode->viXOrigin = (VI_MAX_WIDTH_PAL - 678) / 2;
+
 	VIDEO_Configure(vmode);
 
 	xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer(vmode));
@@ -93,6 +100,15 @@
 		VIDEO_WaitVSync();
 }
 
+void GX_SetTexTrans(float xT, float yT) {
+	tex_xT = xT;
+	tex_yT = yT;
+}
+
+void GX_SetCamPosZ(float f) {
+	cam.pos.z = f;
+}
+
 /****************************************************************************
  * Scaler Support Functions
  ****************************************************************************/
@@ -128,7 +144,7 @@
 	Mtx mv;
 
 	guMtxIdentity(m);
-	guMtxTransApply(m, m, 0, 0, -100);
+	guMtxTransApply(m, m, tex_xT, tex_yT, -100);
 	guMtxConcat(v, m, mv);
 
 	GX_LoadPosMtxImm(mv, GX_PNMTX0);
@@ -144,10 +160,10 @@
  * StartGX
  ****************************************************************************/
 void GX_Start(u16 width, u16 height, s16 haspect, s16 vaspect) {
+	static bool inited = false;
 	Mtx p;
+	GXColor gxbackground = { 0, 0, 0, 0xff };
 
-	GX_AbortFrame();
-
 	/*** Set new aspect ***/
 	square[0] = square[9] = -haspect;
 	square[3] = square[6] = haspect;
@@ -156,10 +172,21 @@
 
 	/*** Allocate 32byte aligned texture memory ***/
 	texturesize = (width * height) * 2;
+
+	if (texturemem)
+		free(texturemem);
+
 	texturemem = (u8 *) memalign(32, texturesize);
+	memset(texturemem, 0, texturesize);
 
-	GXColor gxbackground = { 0, 0, 0, 0xff };
+	/*** Setup for first call to scaler ***/
+	oldvwidth = oldvheight = -1;
 
+	if (inited)
+		return;
+
+	inited = true;
+
 	/*** Clear out FIFO area ***/
 	memset(gp_fifo, 0, DEFAULT_FIFO_SIZE);
 
@@ -184,12 +211,8 @@
 
 	guPerspective(p, 60, 1.33f, 10.0f, 1000.0f);
 	GX_LoadProjectionMtx(p, GX_PERSPECTIVE);
-	memset(texturemem, 0, texturesize);
 
 	GX_Flush();
-
-	/*** Setup for first call to scaler ***/
-	vwidth = vheight = -1;
 }
 
 /****************************************************************************

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wii/gx_supp.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wii/gx_supp.h	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wii/gx_supp.h	2008-08-16 04:30:01 UTC (rev 33924)
@@ -1,6 +1,7 @@
 /****************************************************************************
 *   Generic GX Scaler 
 *   softdev 2007
+*   dhewg 2008
 *
 *   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
@@ -23,11 +24,17 @@
 #ifndef _WII_GX_SUPP_H_
 #define _WII_GX_SUPP_H_
 
+#include <gccore.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+extern GXRModeObj *vmode;
+
 void GX_InitVideo();
+void GX_SetTexTrans(float xT, float yT);
+void GX_SetCamPosZ(float f);
 
 void GX_Start(u16 width, u16 height, s16 haspect, s16 vaspect);
 void GX_Render(u16 width, u16 height, u8 *buffer, u16 pitch);

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -19,9 +19,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-#include "osystem.h"
 #include "backends/fs/wii/wii-fs-factory.h"
+#include "common/config-manager.h"
 
+#include "osystem.h"
+
 #include <unistd.h>
 
 #include <ogc/mutex.h>
@@ -51,8 +53,10 @@
 	_currentHeight(0),
 
 	_supportedGraphicsModes(NULL),
-	_activeGraphicsMode(-1),
+	_activeGraphicsMode(0),
 
+	_fullscreen(false),
+
 	_mouseVisible(false),
 	_mouseX(0),
 	_mouseY(0),
@@ -98,6 +102,8 @@
 	_mixer = new Audio::MixerImpl(this);
 	_timer = new DefaultTimerManager();
 
+	_fullscreen = ConfMan.getBool("fullscreen");
+
 	initGfx();
 	initSfx();
 	initEvents();
@@ -112,14 +118,28 @@
 }
 
 bool OSystem_Wii::hasFeature(Feature f) {
-	return f == kFeatureCursorHasPalette;
+	return (f == kFeatureFullscreenMode) ||
+			(f == kFeatureCursorHasPalette);
 }
 
 void OSystem_Wii::setFeatureState(Feature f, bool enable) {
+	switch (f) {
+	case kFeatureFullscreenMode:
+		_fullscreen = enable;
+		setGraphicsMode(_activeGraphicsMode);
+		break;
+	default:
+		break;
+	}
 }
 
 bool OSystem_Wii::getFeatureState(Feature f) {
-	return false;
+	switch (f) {
+	case kFeatureFullscreenMode:
+		return _fullscreen;
+	default:
+		return false;
+	}
 }
 
 uint32 OSystem_Wii::getMillis() {

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem.h	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem.h	2008-08-16 04:30:01 UTC (rev 33924)
@@ -73,6 +73,8 @@
 	OSystem::GraphicsMode *_supportedGraphicsModes;
 	s32 _activeGraphicsMode;
 
+	bool _fullscreen;
+
 	bool _mouseVisible;
 	s32 _mouseX, _mouseY;
 	u32 _mouseWidth, _mouseHeight;
@@ -110,7 +112,6 @@
 	virtual bool getFeatureState(Feature f);
 	virtual const GraphicsMode *getSupportedGraphicsModes() const;
 	virtual int getDefaultGraphicsMode() const;
-	bool setGraphicsMode(const char *name);
 	virtual bool setGraphicsMode(int mode);
 	virtual int getGraphicsMode() const;
 	virtual void initSize(uint width, uint height);

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem_gfx.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem_gfx.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wii/osystem_gfx.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -27,7 +27,12 @@
 #define MAX_FPS 30
 
 enum GraphicModeID {
-	GM_DEFAULT
+	GM_DEFAULT = 0,
+	GM_OVERSCAN1,
+	GM_OVERSCAN2,
+	GM_OVERSCAN3,
+	GM_OVERSCAN4,
+	GM_OVERSCAN5
 };
 
 void OSystem_Wii::initGfx() {
@@ -42,6 +47,11 @@
 	_overlayWidth = 640;
 	_overlayHeight = 480;
 
+#ifndef GAMECUBE
+	if (CONF_GetAspectRatio() && _fullscreen)
+		_overlayHeight = 360;
+#endif
+
 	_overlaySize = _overlayWidth * _overlayHeight * 2;
 	_overlayPixels = (OverlayColor *) memalign(32, _overlaySize);
 
@@ -51,17 +61,32 @@
 	_cursorPalette = (u16 *) memalign(32, 256 * 2);
 	memset(_cursorPalette, 0, 256 * 2);
 
-	_supportedGraphicsModes = new OSystem::GraphicsMode[2];
-	_supportedGraphicsModes[0].name = strdup("gx");
-	_supportedGraphicsModes[0].description = strdup("wii hardware scaler");
+	_supportedGraphicsModes = new OSystem::GraphicsMode[7];
+	_supportedGraphicsModes[0].name = strdup("standard");
+	_supportedGraphicsModes[0].description = strdup("standard");
 	_supportedGraphicsModes[0].id = GM_DEFAULT;
-	_supportedGraphicsModes[1].name = 0;
-	_supportedGraphicsModes[1].description = 0;
-	_supportedGraphicsModes[1].id = 0;
+	_supportedGraphicsModes[1].name = strdup("overscan1");
+	_supportedGraphicsModes[1].description = strdup("overscan 1");
+	_supportedGraphicsModes[1].id = GM_OVERSCAN1;
+	_supportedGraphicsModes[2].name = strdup("overscan2");
+	_supportedGraphicsModes[2].description = strdup("overscan 2");
+	_supportedGraphicsModes[2].id = GM_OVERSCAN2;
+	_supportedGraphicsModes[3].name = strdup("overscan3");
+	_supportedGraphicsModes[3].description = strdup("overscan 3");
+	_supportedGraphicsModes[3].id = GM_OVERSCAN3;
+	_supportedGraphicsModes[4].name = strdup("overscan4");
+	_supportedGraphicsModes[4].description = strdup("overscan 4");
+	_supportedGraphicsModes[4].id = GM_OVERSCAN4;
+	_supportedGraphicsModes[5].name = strdup("overscan5");
+	_supportedGraphicsModes[5].description = strdup("overscan 5");
+	_supportedGraphicsModes[5].id = GM_OVERSCAN5;
+	_supportedGraphicsModes[6].name = 0;
+	_supportedGraphicsModes[6].description = 0;
+	_supportedGraphicsModes[6].id = 0;
 
-	_texture = (u16 *) memalign(32, _overlaySize);
+	_texture = (u16 *) memalign(32, 640 * 480 * 2);
 
-	GX_Start(_overlayWidth, _overlayHeight, 320, 240);
+	setGraphicsMode(_activeGraphicsMode);
 }
 
 void OSystem_Wii::deinitGfx() {
@@ -111,13 +136,24 @@
 	return GM_DEFAULT;
 }
 
-bool OSystem_Wii::setGraphicsMode(const char *mode) {
-	setGraphicsMode(GM_DEFAULT);
+bool OSystem_Wii::setGraphicsMode(int mode) {
+	s16 xar, yar;
 
-	return true;
-}
+	printf("setGraphicsMode %d\n", mode);
 
-bool OSystem_Wii::setGraphicsMode(int mode) {
+	xar = vmode->viWidth / 2;
+	yar = vmode->xfbHeight / 2;
+
+#ifndef GAMECUBE
+	if (CONF_GetAspectRatio() && !_fullscreen)
+		xar /= 1.33f;
+#endif
+
+	GX_SetCamPosZ(400 - mode * 10);
+	GX_Start(640, 480, xar, yar);
+
+	_activeGraphicsMode = mode;
+
 	return true;
 }
 
@@ -129,6 +165,8 @@
 	if (_gameWidth != width || _gameHeight != height) {
 		printf("initSize %u %u\n", width, height);
 
+		assert((width <= 640) && (height <= 480));
+
 		_gameWidth = width;
 		_gameHeight = height;
 
@@ -136,12 +174,15 @@
 			free(_gamePixels);
 
 		_gamePixels = (u8 *) memalign(32, _gameWidth * _gameHeight);
+		memset(_gamePixels, 0, _gameWidth * _gameHeight);
 
 		if (!_overlayVisible) {
 			_currentWidth = _gameWidth;
 			_currentHeight = _gameHeight;
 			updateEventScreenResolution();
 		}
+
+		setGraphicsMode(_activeGraphicsMode);
 	}
 }
 
@@ -320,6 +361,8 @@
 }
 
 void OSystem_Wii::setShakePos(int shakeOffset) {
+	GX_SetTexTrans(0, (float) -shakeOffset * ((float) vmode->efbHeight /
+												(float) _currentHeight));
 }
 
 void OSystem_Wii::showOverlay() {

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEActionsPocket.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEActionsPocket.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEActionsPocket.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -215,7 +215,7 @@
 }
 
 bool CEActionsPocket::perform(GUI::ActionType action, bool pushed) {
-	static bool keydialogrunning = false;
+	static bool keydialogrunning = false, quitdialog = false;
 
 	if (!pushed) {
 		switch(action) {
@@ -292,12 +292,14 @@
 			_CESystem->move_cursor_right();
 			return true;
 		case POCKET_ACTION_QUIT:
-			{
+			if (!quitdialog) {
+				quitdialog = true;
 				GUI::MessageDialog alert("   Are you sure you want to quit ?   ", "Yes", "No");
 				if (alert.runModal() == GUI::kMessageOK)
 					_mainSystem->quit();
-				return true;
+				quitdialog = false;
 			}
+			return true;
 		case POCKET_ACTION_BINDKEYS:
 			if (!keydialogrunning) {
 				keydialogrunning = true;

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEActionsSmartphone.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEActionsSmartphone.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEActionsSmartphone.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -179,7 +179,7 @@
 }
 
 bool CEActionsSmartphone::perform(GUI::ActionType action, bool pushed) {
-	static bool keydialogrunning = false;
+	static bool keydialogrunning = false, quitdialog = false;
 
 	if (!pushed) {
 		switch (action) {
@@ -250,12 +250,14 @@
 			_CESystem->smartphone_rotate_display();
 			return true;
 		case SMARTPHONE_ACTION_QUIT:
-			{
+			if (!quitdialog) {
+				quitdialog = true;
 				GUI::MessageDialog alert("   Are you sure you want to quit ?   ", "Yes", "No");
 				if (alert.runModal() == GUI::kMessageOK)
 					_mainSystem->quit();
-				return true;
+				quitdialog = false;
 			}
+			return true;
 	}
 
 	return false;

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEkeys/EventsBuffer.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEkeys/EventsBuffer.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wince/CEkeys/EventsBuffer.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -36,9 +36,8 @@
 			key->setKey(key->keycode());
 
 		ev.type = (pushed ? SDL_KEYDOWN : SDL_KEYUP);
-		ev.key.keysym.mod = (SDLMod)key->flags();
+		ev.key.keysym.unicode = (SDLMod)key->flags();	// HACK: put the flags into the unused unicode field
 		ev.key.keysym.sym = (SDLKey)key->keycode();
-		ev.key.keysym.unicode = key->keycode();
 		ev.key.keysym.mod = KMOD_RESERVED;
 		return (SDL_PushEvent(&ev) == 0);
 	}

Modified: scummvm/branches/gsoc2008-rtl/backends/platform/wince/wince-sdl.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/backends/platform/wince/wince-sdl.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/backends/platform/wince/wince-sdl.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -805,8 +805,16 @@
 		debug(1, "Sound opened OK, mixing at %d Hz", _sampleRate);
 
 		// Re-create mixer to match the output rate
+		int vol1 = _mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType);
+		int vol2 = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
+		int vol3 = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType);
+		int vol4 = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType);
 		delete(_mixer);
 		_mixer = new Audio::MixerImpl(this);
+		_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, vol1);
+		_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol2);
+		_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol3);
+		_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol4);
 		_mixer->setOutputRate(_sampleRate);
 		_mixer->setReady(true);
 		SDL_PauseAudio(0);
@@ -2254,15 +2262,18 @@
 				_lastKeyPressed = 0;
 				event.type = Common::EVENT_PREDICTIVE_DIALOG;
 				return true;
-			}
-
-			event.type = Common::EVENT_KEYDOWN;
+			} 			event.type = Common::EVENT_KEYDOWN;
 			if (!_unfilteredkeys)
 				event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
 			else
 				event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
 			event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
 
+			if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
+				event.kbd.ascii ^= 0x20;
+				event.kbd.flags = Common::KBD_SHIFT;
+			}
+
 			return true;
 
 		case SDL_KEYUP:
@@ -2290,6 +2301,11 @@
 				event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
 			event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, _unfilteredkeys);
 
+			if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
+				event.kbd.ascii ^= 0x20;
+				event.kbd.flags = Common::KBD_SHIFT;
+			}
+
 			return true;
 
 		case SDL_MOUSEMOTION:


Property changes on: scummvm/branches/gsoc2008-rtl/dists
___________________________________________________________________
Added: svn:ignore
   + rpl.exe



Property changes on: scummvm/branches/gsoc2008-rtl/dists/msvc7
___________________________________________________________________
Added: svn:ignore
   + *_Debug
*_Release
*.suo
*.ncb
*.user



Property changes on: scummvm/branches/gsoc2008-rtl/dists/msvc71
___________________________________________________________________
Added: svn:ignore
   + *_Debug
*_Release
*.suo
*.ncb
*.user



Property changes on: scummvm/branches/gsoc2008-rtl/dists/msvc8
___________________________________________________________________
Added: svn:ignore
   + *_Debug
*_Release
*.suo
*.ncb
*.user



Property changes on: scummvm/branches/gsoc2008-rtl/dists/msvc9
___________________________________________________________________
Added: svn:ignore
   + *_Debug
*_Release
*.suo
*.ncb
*.user


Modified: scummvm/branches/gsoc2008-rtl/dists/wii/READMII
===================================================================
--- scummvm/branches/gsoc2008-rtl/dists/wii/READMII	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/dists/wii/READMII	2008-08-16 04:30:01 UTC (rev 33924)
@@ -1,5 +1,5 @@
-Wii port of ScummVM README
---------------------------
+Wii/Gamecube port of ScummVM README
+-----------------------------------
 
 features not compiled in:
 - the AGI game engine
@@ -66,6 +66,21 @@
     dpad left: "y"
     dpad right: "n"
 
+DISPLAY SETUP
+
+  "Graphics mode"
+    you can choose between multiple overscan options to adjust the screen size
+    used for drawing. select a higher overscan mode to get rid of black
+    borders or choose a lower overscan mode if parts of the picture get cropped
+
+  "Fullscreen mode"
+    If your wii is set to 16:9, this will stretch the picture to fullscreen.
+    Turning this option off results in black borders on the left and right
+    sides, but the aspect ratio will be kept. This option has no effect on 4:3
+    displays
+
+  you have to restart scummvm after changing one of these options
+
 THANKS
 
   shagkur and WinterMute, for devkitppc/libogc and the coorperation

Modified: scummvm/branches/gsoc2008-rtl/engines/agi/sound.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/agi/sound.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/agi/sound.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -435,13 +435,10 @@
 	_gsChannels.clear();
 }
 
-static int16 *buffer;
-
 int SoundMgr::initSound() {
 	int r = -1;
 
-	buffer = _sndBuffer = (int16 *)calloc(2, BUFFER_SIZE);
-
+	memset(_sndBuffer, 0, BUFFER_SIZE << 1);
 	_env = false;
 
 	switch (_vm->_soundemu) {
@@ -478,7 +475,6 @@
 void SoundMgr::deinitSound() {
 	debugC(3, kDebugLevelSound, "()");
 	_mixer->stopHandle(_soundHandle);
-	free(_sndBuffer);
 }
 
 void SoundMgr::stopNote(int i) {
@@ -1185,7 +1181,7 @@
 	return _gsSound.loadWaveFile(waveFsnode->getPath(), *exeInfo) && _gsSound.loadInstrumentHeaders(exeFsnode->getPath(), *exeInfo);
 }
 
-static void fillAudio(void *udata, int16 *stream, uint len) {
+void SoundMgr::fillAudio(void *udata, int16 *stream, uint len) {
 	SoundMgr *soundMgr = (SoundMgr *)udata;
 	uint32 p = 0;
 	static uint32 n = 0, s = 0;
@@ -1193,32 +1189,34 @@
 	len <<= 2;
 
 	debugC(5, kDebugLevelSound, "(%p, %p, %d)", (void *)udata, (void *)stream, len);
-	memcpy(stream, (uint8 *)buffer + s, p = n);
+	memcpy(stream, (uint8 *)_sndBuffer + s, p = n);
 	for (n = 0, len -= p; n < len; p += n, len -= n) {
 		soundMgr->playSound();
 		n = soundMgr->mixSound() << 1;
 		if (len < n) {
-			memcpy((uint8 *)stream + p, buffer, len);
+			memcpy((uint8 *)stream + p, _sndBuffer, len);
 			s = len;
 			n -= s;
 			return;
 		} else {
-			memcpy((uint8 *)stream + p, buffer, n);
+			memcpy((uint8 *)stream + p, _sndBuffer, n);
 		}
 	}
 	soundMgr->playSound();
 	n = soundMgr->mixSound() << 1;
-	memcpy((uint8 *)stream + p, buffer, s = len);
+	memcpy((uint8 *)stream + p, _sndBuffer, s = len);
 	n -= s;
 }
 
-SoundMgr::SoundMgr(AgiBase *agi, Audio::Mixer *pMixer) {
+SoundMgr::SoundMgr(AgiBase *agi, Audio::Mixer *pMixer) : _chn() {
 	_vm = agi;
 	_mixer = pMixer;
 	_sampleRate = pMixer->getOutputRate();
 	_endflag = -1;
 	_playingSound = -1;
-	_sndBuffer = 0;
+	_env = false;
+	_playing = false;
+	_sndBuffer = (int16 *)calloc(2, BUFFER_SIZE);
 	_waveform = 0;
 }
 
@@ -1231,6 +1229,7 @@
 }
 
 SoundMgr::~SoundMgr() {
+	free(_sndBuffer);
 }
 
 } // End of namespace Agi

Modified: scummvm/branches/gsoc2008-rtl/engines/agi/sound.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/agi/sound.h	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/agi/sound.h	2008-08-16 04:30:01 UTC (rev 33924)
@@ -472,6 +472,7 @@
 	const int16 *_waveform;
 
 	void premixerCall(int16 *buf, uint len);
+	void fillAudio(void *udata, int16 *stream, uint len);
 
 public:
 	void unloadSound(int);

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/cine.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/cine.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/cine.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -68,14 +68,9 @@
 
 CineEngine::~CineEngine() {
 	if (g_cine->getGameType() == Cine::GType_OS) {
-		freePoldatDat();
 		freeErrmessDat();
 	}
 	Common::clearAllSpecialDebugLevels();
-
-	free(palPtr);
-	free(partBuffer);
-	free(textDataPtr);
 }
 
 int CineEngine::init() {
@@ -152,15 +147,16 @@
 	}
 
 	collisionPage = new byte[320 * 200];
-	textDataPtr = (byte *)malloc(8000);
 
-	partBuffer = (PartBuffer *)malloc(NUM_MAX_PARTDATA * sizeof(PartBuffer));
+	// Clear part buffer as there's nothing loaded into it yet.
+	// Its size will change when loading data into it with the loadPart function.
+	partBuffer.clear();
 
 	if (g_cine->getGameType() == Cine::GType_OS) {
 		readVolCnf();
 	}
 
-	loadTextData("texte.dat", textDataPtr);
+	loadTextData("texte.dat");
 
 	if (g_cine->getGameType() == Cine::GType_OS && !(g_cine->getFeatures() & GF_DEMO)) {
 		loadPoldatDat("poldat.dat");

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/gfx.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/gfx.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/gfx.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -31,6 +31,7 @@
 
 #include "common/endian.h"
 #include "common/system.h"
+#include "common/events.h"
 
 #include "graphics/cursorman.h"
 
@@ -91,7 +92,7 @@
  */
 FWRenderer::FWRenderer() : _background(NULL), _palette(NULL), _cmd(""),
 	_cmdY(0), _messageBg(0), _backBuffer(new byte[_screenSize]),
-	_activeLowPal(NULL), _changePal(0) {
+	_activeLowPal(NULL), _changePal(0), _showCollisionPage(false) {
 
 	assert(_backBuffer);
 
@@ -125,6 +126,7 @@
 	_cmdY = 0;
 	_messageBg = 0;
 	_changePal = 0;
+	_showCollisionPage = false;
 }
 
 /*! \brief Draw 1bpp sprite using selected color
@@ -225,14 +227,18 @@
  * \param x Top left message box corner coordinate
  * \param y Top left message box corner coordinate
  * \param width Message box width
- * \param color Message box background color
+ * \param color Message box background color (Or if negative draws only the text)
+ * \note Negative colors are used in Operation Stealth's timed cutscenes
+ * (e.g. when first meeting The Movement for the Liberation of Santa Paragua).
  */
-void FWRenderer::drawMessage(const char *str, int x, int y, int width, byte color) {
+void FWRenderer::drawMessage(const char *str, int x, int y, int width, int color) {
 	int i, tx, ty, tw;
 	int line = 0, words = 0, cw = 0;
 	int space = 0, extraSpace = 0;
 
-	drawPlainBox(x, y, width, 4, color);
+	if (color >= 0) {
+		drawPlainBox(x, y, width, 4, color);
+	}
 	tx = x + 4;
 	ty = str[0] ? y - 5 : y + 4;
 	tw = width - 8;
@@ -252,7 +258,9 @@
 			}
 
 			ty += 9;
-			drawPlainBox(x, ty, width, 9, color);
+			if (color >= 0) {
+				drawPlainBox(x, ty, width, 9, color);
+			}
 			tx = x + 4;
 		}
 
@@ -269,8 +277,10 @@
 	}
 
 	ty += 9;
-	drawPlainBox(x, ty, width, 4, color);
-	drawDoubleBorder(x, y, width, ty - y + 4, 2);
+	if (color >= 0) {
+		drawPlainBox(x, ty, width, 4, color);
+		drawDoubleBorder(x, y, width, ty - y + 4, 2);
+	}
 }
 
 /*! \brief Draw rectangle on screen
@@ -279,55 +289,45 @@
  * \param width Rectangle width (Negative values draw the box horizontally flipped)
  * \param height Rectangle height (Negative values draw the box vertically flipped)
  * \param color Fill color
- * \note Rectangle's drawn width is always at least one.
- * \note Rectangle's drawn height is always at least one.
+ * \note An on-screen rectangle's drawn width is always at least one.
+ * \note An on-screen rectangle's drawn height is always at least one.
  */
 void FWRenderer::drawPlainBox(int x, int y, int width, int height, byte color) {
-	int i;
+	// Make width's and height's absolute values at least one
+	// which forces this function to always draw something if the
+	// drawing position is inside screen bounds. This fixes at least
+	// the showing of the oxygen gauge meter in Operation Stealth's
+	// first arcade sequence where this function is called with a
+	// height of zero.
+	if (width == 0) {
+		width = 1;
+	}
+	if (height == 0) {
+		height = 1;
+	}
 
 	// Handle horizontally flipped boxes
 	if (width < 0) {
-		x += width;
 		width = ABS(width);
+		x -= width;
 	}
 
 	// Handle vertically flipped boxes
 	if (height < 0) {
-		y += height;
 		height = ABS(height);
+		y -= height;
 	}
 
-	// Handle horizontal boundaries
-	if (x < 0) {
-		width += x; // Remove invisible columns
-		x = 0; // Start drawing at the screen's left border
-	} else if (x > 319) {
-		// Nothing left to draw as we're over the screen's right border
-		width = 0;
-	}
+	// Clip the rectangle to screen dimensions
+	Common::Rect boxRect(x, y, x + width, y + height);
+	Common::Rect screenRect(320, 200);
+	boxRect.clip(screenRect);
 
-	// Handle vertical boundaries
-	if (y < 0) {
-		height += y; // Remove invisible rows
-		y = 0; // Start drawing at the screen's top border
-	} else if (y > 199) {
-		// Nothing left to draw as we're below the screen's bottom border
-		height = 0;
+	// Draw the filled rectangle	
+	byte *dest = _backBuffer + boxRect.top * 320 + boxRect.left;
+	for (int i = 0; i < boxRect.height(); i++) {
+		memset(dest + i * 320, color, boxRect.width());
 	}
-
-	// Make width and height at least one
-	// which forces this function to always draw something.
-	// This fixes at least the showing of the oxygen gauge meter in
-	// Operation Stealth's first arcade sequence where this function
-	// is called with a height of zero.
-	width  = MAX(1, width);
-	height = MAX(1, height);
-
-	// Draw the filled rectangle
-	byte *dest = _backBuffer + y * 320 + x;
-	for (i = 0; i < height; i++) {
-		memset(dest + i * 320, color, width);
-	}
 }
 
 /*! \brief Draw empty rectangle
@@ -366,8 +366,8 @@
 
 	if (character == ' ') {
 		x += 5;
-	} else if ((width = fontParamTable[(unsigned char)character].characterWidth)) {
-		idx = fontParamTable[(unsigned char)character].characterIdx;
+	} else if ((width = g_cine->_textHandler.fontParamTable[(unsigned char)character].characterWidth)) {
+		idx = g_cine->_textHandler.fontParamTable[(unsigned char)character].characterIdx;
 		drawSpriteRaw(g_cine->_textHandler.textTable[idx][0], g_cine->_textHandler.textTable[idx][1], 16, 8, _backBuffer, x, y);
 		x += width + 1;
 	}
@@ -513,16 +513,28 @@
 	blit();
 }
 
+/*!
+ * \brief Turn on or off the showing of the collision page.
+ * If turned on the blitting routine shows the collision page instead of the back buffer.
+ * \note Useful for debugging collision page related problems.
+ */
+void FWRenderer::showCollisionPage(bool state) {
+	_showCollisionPage = state;
+}
+
 /*! \brief Update screen
  */
 void FWRenderer::blit() {
-	g_system->copyRectToScreen(_backBuffer, 320, 0, 0, 320, 200);
+	// Show the back buffer or the collision page. Normally the back
+	// buffer but showing the collision page is useful for debugging.
+	byte *source = (_showCollisionPage ? collisionPage : _backBuffer);
+	g_system->copyRectToScreen(source, 320, 0, 0, 320, 200);
 }
 
 /*! \brief Set player command string
  * \param cmd New command string
  */
-void FWRenderer::setCommand(const char *cmd) {
+void FWRenderer::setCommand(Common::String cmd) {
 	_cmd = cmd;
 }
 
@@ -1023,8 +1035,8 @@
 
 	if (character == ' ') {
 		x += 5;
-	} else if ((width = fontParamTable[(unsigned char)character].characterWidth)) {
-		idx = fontParamTable[(unsigned char)character].characterIdx;
+	} else if ((width = g_cine->_textHandler.fontParamTable[(unsigned char)character].characterWidth)) {
+		idx = g_cine->_textHandler.fontParamTable[(unsigned char)character].characterIdx;
 		drawSpriteRaw2(g_cine->_textHandler.textTable[idx][0], 0, 16, 8, _backBuffer, x, y);
 		x += width + 1;
 	}
@@ -1063,10 +1075,11 @@
  * \todo Add handling of type 22 overlays
  */
 void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) {
-	int len;
+	int len, idx, width, height;
 	objectStruct *obj;
 	AnimData *sprite;
 	byte *mask;
+	byte color;
 
 	switch (it->type) {
 	// color sprite
@@ -1096,6 +1109,19 @@
 		}
 		break;
 
+	// action failure message
+	case 3:
+		idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3);
+		len = strlen(failureMessages[idx]);
+		_messageLen += len;
+		width = 6 * len + 20;
+		width = width > 300 ? 300 : width;
+
+		// The used color here differs from Future Wars
+		drawMessage(failureMessages[idx], (320 - width) / 2, 80, width, _messageBg);
+		waitForPlayerClick = 1;
+		break;
+
 	// bitmap
 	case 4:
 		if (objectTable[it->objIdx].frame >= 0) {
@@ -1117,26 +1143,25 @@
 		maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y);
 		break;
 
-	// FIXME: Looking at Operation Stealth's disassembly I can't find any codepath that
-	// will draw a type 21 overlay. But looking at the first arcade sequence's scripts
-	// it looks like the oxygen gauge meter is implemented using a type 21 overlay.
-	// So for the time being I'm simply drawing type 21 overlays as type 22 overlays
-	// and hoping for the best.
-	// TODO: Check how the original game looks under DOSBox to see if the oxygen gauge works in it
+	// FIXME: Implement correct drawing of type 21 overlays.
+	// Type 21 overlays aren't just filled rectangles, I found their drawing routine
+	// from Operation Stealth's drawSprite routine. So they're likely some kind of sprites
+	// and it's just a coincidence that the oxygen meter during the first arcade sequence
+	// works even somehow currently. I tried the original under DOSBox and the oxygen gauge
+	// is a long red bar that gets shorter as the air runs out.
 	case 21:
 	// A filled rectangle:
-	case 22: {
+	case 22:
 		// TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing).
 		assert(it->objIdx < NUM_MAX_OBJECT);
 		obj = &objectTable[it->objIdx];
-		byte color = obj->part & 0x0F;
-		int width = obj->frame;
-		int height = obj->costume;
+		color = obj->part & 0x0F;
+		width = obj->frame;
+		height = obj->costume;
 		drawPlainBox(obj->x, obj->y, width, height, color);
 		debug(5, "renderOverlay: type=%d, x=%d, y=%d, width=%d, height=%d, color=%d",
 			it->type, obj->x, obj->y, width, height, color);
 		break;
-	 }
 
 	// something else
 	default:

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/gfx.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/gfx.h	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/gfx.h	2008-08-16 04:30:01 UTC (rev 33924)
@@ -62,13 +62,14 @@
 	byte *_backBuffer; ///< Screen backbuffer
 	uint16 *_activeLowPal; ///< Active 16 color palette
 	int _changePal; ///< Load active palette to video backend on next frame
+	bool _showCollisionPage; ///< Should we show the collision page instead of the back buffer? Used for debugging.
 
 	void fillSprite(const objectStruct &obj, uint8 color = 0);
 	void drawMaskedSprite(const objectStruct &obj, const byte *mask);
 	virtual void drawSprite(const objectStruct &obj);
 
 	void drawCommand();
-	void drawMessage(const char *str, int x, int y, int width, byte color);
+	void drawMessage(const char *str, int x, int y, int width, int color);
 	void drawPlainBox(int x, int y, int width, int height, byte color);
 	void drawBorder(int x, int y, int width, int height, byte color);
 	void drawDoubleBorder(int x, int y, int width, int height, byte color);
@@ -94,7 +95,7 @@
 
 	void drawFrame();
 	void blit();
-	void setCommand(const char *cmd);
+	void setCommand(Common::String cmd);
 
 	virtual void incrustMask(const objectStruct &obj, uint8 color = 0);
 	virtual void incrustSprite(const objectStruct &obj);
@@ -124,6 +125,7 @@
 	void drawInputBox(const char *info, const char *input, int cursor, int x, int y, int width);
 
 	virtual void fadeToBlack();
+	void showCollisionPage(bool state);
 };
 
 /*! \brief Operation Stealth renderer

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/main_loop.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/main_loop.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/main_loop.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -121,6 +121,9 @@
 				g_cine->makeSystemMenu();
 			}
 			break;
+		case Common::KEYCODE_F11:
+			renderer->showCollisionPage(true);
+			break;
 		case Common::KEYCODE_MINUS:
 		case Common::KEYCODE_KP_MINUS:
 			g_cine->modifyGameSpeed(-1); // Slower
@@ -164,6 +167,9 @@
 		break;
 	case Common::EVENT_KEYUP:
 		switch (event.kbd.keycode) {
+		case Common::KEYCODE_F11:
+			renderer->showCollisionPage(false);
+			break;
 		case Common::KEYCODE_KP5:	// Emulated left mouse button click
 		case Common::KEYCODE_LEFT:	// Left
 		case Common::KEYCODE_KP4:	// Left
@@ -276,7 +282,7 @@
 		menuCommandLen = 0;
 
 		playerCommand = -1;
-		strcpy(commandBuffer, "");
+		commandBuffer = "";
 
 		globalVars[VAR_MOUSE_X_POS] = 0;
 		globalVars[VAR_MOUSE_Y_POS] = 0;

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/msg.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/msg.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/msg.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -34,29 +34,40 @@
 Common::StringList messageTable;
 
 void loadMsg(char *pMsgName) {
-	int i, count, len;
-	byte *ptr, *dataPtr;
-	const char *messagePtr;
+	uint32 sourceSize;
 
 	checkDataDisk(-1);
-
 	messageTable.clear();
+	byte *dataPtr = readBundleFile(findFileInBundle(pMsgName), &sourceSize);
 
-	ptr = dataPtr = readBundleFile(findFileInBundle(pMsgName));
-
 	setMouseCursor(MOUSE_CURSOR_DISK);
 
-	count = READ_BE_UINT16(ptr);
-	ptr += 2;
+	uint count = READ_BE_UINT16(dataPtr);
+	uint messageLenPos = 2;
+	uint messageDataPos = messageLenPos + 2 * count;
 
-	messagePtr = (const char*)(ptr + 2 * count);
+	// Read in the messages
+	for (uint i = 0; i < count; i++) {
+		// Read message's length
+		uint messageLen = READ_BE_UINT16(dataPtr + messageLenPos);
+		messageLenPos += 2;
 
-	for (i = 0; i < count; i++) {
-		len = READ_BE_UINT16(ptr);
-		ptr += 2;
-		
-		messageTable.push_back(messagePtr);
-		messagePtr += len;
+		// Store the read message.
+		// This code works around input data that has empty strings residing outside the input
+		// buffer (e.g. message indexes 58-254 in BATEAU.MSG in PROCS08 in Operation Stealth).
+		if (messageDataPos < sourceSize) {
+			messageTable.push_back((const char *)(dataPtr + messageDataPos));
+		} else {			
+			if (messageLen > 0) { // Only warn about overflowing non-empty strings
+				warning("loadMsg(%s): message (%d. / %d) is overflowing the input buffer. Replacing it with an empty string", pMsgName, i + 1, count);
+			} else {
+				debugC(5, kCineDebugPart, "loadMsg(%s): empty message (%d. / %d) resides outside input buffer", pMsgName, i + 1, count);
+			}
+			// Message resides outside the input buffer so we replace it with an empty string
+			messageTable.push_back("");
+		}
+		// Jump to the next message
+		messageDataPos += messageLen;
 	}
 
 	free(dataPtr);

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/pal.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/pal.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/pal.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -28,10 +28,7 @@
 
 namespace Cine {
 
-uint16 palEntriesCount;
-
-PalEntry *palPtr = NULL;
-
+Common::Array<PalEntry> palArray;
 static byte paletteBuffer1[16];
 static byte paletteBuffer2[16];
 
@@ -41,27 +38,20 @@
 	removeExtention(buffer, fileName);
 
 	strcat(buffer, ".PAL");
+	palArray.clear();
 
-	if (palPtr) {
-		free(palPtr);
-		palPtr = NULL;
-	}
-
-	palEntriesCount = 0;
-
 	Common::File palFileHandle;
 	if (!palFileHandle.open(buffer))
 		error("loadPal(): Cannot open file %s", fileName);
 
-	palEntriesCount = palFileHandle.readUint16LE();
+	uint16 palEntriesCount = palFileHandle.readUint16LE();	
 	palFileHandle.readUint16LE(); // entry size
 
-	palPtr = (PalEntry *)malloc(palEntriesCount * sizeof(PalEntry));
-	assert(palPtr);
-	for (int i = 0; i < palEntriesCount; ++i) {
-		palFileHandle.read(palPtr[i].name, 10);
-		palFileHandle.read(palPtr[i].pal1, 16);
-		palFileHandle.read(palPtr[i].pal2, 16);
+	palArray.resize(palEntriesCount);
+	for (uint i = 0; i < palArray.size(); ++i) {
+		palFileHandle.read(palArray[i].name, 10);
+		palFileHandle.read(palArray[i].pal1, 16);
+		palFileHandle.read(palArray[i].pal2, 16);
 	}
 	palFileHandle.close();
 }
@@ -81,8 +71,8 @@
 		position++;
 	}
 
-	for (i = 0; i < palEntriesCount; i++) {
-		if (!strcmp(buffer, palPtr[i].name)) {
+	for (i = 0; i < palArray.size(); i++) {
+		if (!strcmp(buffer, palArray[i].name)) {
 			return i;
 		}
 	}
@@ -105,9 +95,9 @@
 			paletteBuffer1[i] = paletteBuffer2[i] = (i << 4) + i;
 		}
 	} else {
-		assert(paletteIndex < palEntriesCount);
-		memcpy(paletteBuffer1, palPtr[paletteIndex].pal1, 16);
-		memcpy(paletteBuffer2, palPtr[paletteIndex].pal2, 16);
+		assert(paletteIndex < (int32)palArray.size());
+		memcpy(paletteBuffer1, palArray[paletteIndex].pal1, 16);
+		memcpy(paletteBuffer2, palArray[paletteIndex].pal2, 16);
 	}
 }
 

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/pal.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/pal.h	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/pal.h	2008-08-16 04:30:01 UTC (rev 33924)
@@ -34,7 +34,7 @@
 	byte pal2[16];
 };
 
-extern PalEntry *palPtr;
+extern Common::Array<PalEntry> palArray;
 
 void loadPal(const char *fileName);
 

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/part.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/part.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/part.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -31,13 +31,10 @@
 
 namespace Cine {
 
-uint16 numElementInPart;
+Common::Array<PartBuffer> partBuffer;
 
-PartBuffer *partBuffer;
-
 void loadPart(const char *partName) {
-	memset(partBuffer, 0, sizeof(PartBuffer) * NUM_MAX_PARTDATA);
-	numElementInPart = 0;
+	partBuffer.clear();
 
 	g_cine->_partFileHandle.close();
 
@@ -48,13 +45,14 @@
 
 	setMouseCursor(MOUSE_CURSOR_DISK);
 
-	numElementInPart = g_cine->_partFileHandle.readUint16BE();
+	uint16 numElementInPart = g_cine->_partFileHandle.readUint16BE();
+	partBuffer.resize(numElementInPart);
 	g_cine->_partFileHandle.readUint16BE(); // entry size
 
 	if (currentPartName != partName)
 		strcpy(currentPartName, partName);
 
-	for (uint16 i = 0; i < numElementInPart; i++) {
+	for (uint16 i = 0; i < partBuffer.size(); i++) {
 		g_cine->_partFileHandle.read(partBuffer[i].partName, 14);
 		partBuffer[i].offset = g_cine->_partFileHandle.readUint32BE();
 		partBuffer[i].packedSize = g_cine->_partFileHandle.readUint32BE();
@@ -190,7 +188,7 @@
 int16 findFileInBundle(const char *fileName) {
 	if (g_cine->getGameType() == Cine::GType_OS) {
 		// look first in currently loaded resource file
-		for (int i = 0; i < numElementInPart; i++) {
+		for (uint i = 0; i < partBuffer.size(); i++) {
 			if (!scumm_stricmp(fileName, partBuffer[i].partName)) {
 				return i;
 			}
@@ -204,7 +202,7 @@
 		const char *part = (*it)._value;
 		loadPart(part);
 	}
-	for (int i = 0; i < numElementInPart; i++) {
+	for (uint i = 0; i < partBuffer.size(); i++) {
 		if (!scumm_stricmp(fileName, partBuffer[i].partName)) {
 			return i;
 		}
@@ -212,28 +210,37 @@
 	return -1;
 }
 
-void readFromPart(int16 idx, byte *dataPtr) {
+void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize) {
 	setMouseCursor(MOUSE_CURSOR_DISK);
 
 	g_cine->_partFileHandle.seek(partBuffer[idx].offset, SEEK_SET);
-	g_cine->_partFileHandle.read(dataPtr, partBuffer[idx].packedSize);
+	g_cine->_partFileHandle.read(dataPtr, MIN(partBuffer[idx].packedSize, maxSize));
 }
 
-byte *readBundleFile(int16 foundFileIdx) {
-	assert(foundFileIdx >= 0 && foundFileIdx < numElementInPart);
+byte *readBundleFile(int16 foundFileIdx, uint32 *size) {
+	assert(foundFileIdx >= 0 && foundFileIdx < (int32)partBuffer.size());
+	bool error = false;
 	byte *dataPtr = (byte *)calloc(partBuffer[foundFileIdx].unpackedSize, 1);
-	if (partBuffer[foundFileIdx].unpackedSize != partBuffer[foundFileIdx].packedSize) {
-		byte *unpackBuffer = (byte *)malloc(partBuffer[foundFileIdx].packedSize);
-		readFromPart(foundFileIdx, unpackBuffer);
+	readFromPart(foundFileIdx, dataPtr, partBuffer[foundFileIdx].unpackedSize);
+	if (partBuffer[foundFileIdx].unpackedSize > partBuffer[foundFileIdx].packedSize) {
 		CineUnpacker cineUnpacker;
-		if (!cineUnpacker.unpack(unpackBuffer, partBuffer[foundFileIdx].packedSize, dataPtr, partBuffer[foundFileIdx].unpackedSize)) {
-			warning("Error unpacking '%s' from bundle file '%s'", partBuffer[foundFileIdx].partName, currentPartName);
-		}
-		free(unpackBuffer);
-	} else {
-		readFromPart(foundFileIdx, dataPtr);
+		error = !cineUnpacker.unpack(dataPtr, partBuffer[foundFileIdx].packedSize, dataPtr, partBuffer[foundFileIdx].unpackedSize);
+	} else if (partBuffer[foundFileIdx].unpackedSize < partBuffer[foundFileIdx].packedSize) {
+		// Unpacked size of a file should never be less than its packed size
+		error = true;
+	} else { // partBuffer[foundFileIdx].unpackedSize == partBuffer[foundFileIdx].packedSize
+		debugC(5, kCineDebugPart, "Loaded non-compressed file '%s' from bundle file '%s'", partBuffer[foundFileIdx].partName, currentPartName);
 	}
 
+	if (error) {
+		warning("Error unpacking '%s' from bundle file '%s'", partBuffer[foundFileIdx].partName, currentPartName);
+	}
+
+	// Set the size variable if a pointer to it has been given
+	if (size != NULL) {
+		*size = partBuffer[foundFileIdx].unpackedSize;
+	}
+
 	return dataPtr;
 }
 
@@ -300,7 +307,7 @@
 	strcpy(tmpPart, currentPartName);
 
 	loadPart(fileName);
-	for (int i = 0; i < numElementInPart; i++) {
+	for (uint i = 0; i < partBuffer.size(); i++) {
 		byte *data = readBundleFile(i);
 
 		debug(0, "%s", partBuffer[i].partName);

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/part.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/part.h	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/part.h	2008-08-16 04:30:01 UTC (rev 33924)
@@ -37,16 +37,16 @@
 
 #define NUM_MAX_PARTDATA 255
 
-extern PartBuffer *partBuffer;
+extern Common::Array<PartBuffer> partBuffer;
 
 void loadPart(const char *partName);
 void closePart(void);
 
 int16 findFileInBundle(const char *fileName);
 
-void readFromPart(int16 idx, byte *dataPtr);
+void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize);
 
-byte *readBundleFile(int16 foundFileIdx);
+byte *readBundleFile(int16 foundFileIdx, uint32 *size = NULL);
 byte *readBundleSoundFile(const char *entryName, uint32 *size = 0);
 byte *readFile(const char *filename, bool crypted = false);
 

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/sound.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/sound.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/sound.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -604,6 +604,7 @@
 		_instrumentsData[i] = NULL;
 
 		char instrument[64];
+		memset(instrument, 0, 64); // Clear the data first
 		memcpy(instrument, _sfxData + 20 + i * 30, 12);
 		instrument[63] = '\0';
 

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/texte.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/texte.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/texte.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -29,70 +29,53 @@
 
 namespace Cine {
 
-byte *textDataPtr;
-
 const char **failureMessages;
 const CommandeType *defaultActionCommand;
 const CommandeType *systemMenu;
 const CommandeType *confirmMenu;
 const char **otherMessages;
-const char *commandPrepositionOn;
+const char *defaultCommandPreposition;
+const char **commandPrepositionTable;
 
 void generateMask(const byte *sprite, byte *mask, uint16 size, byte transparency);
 
-void loadTextData(const char *pFileName, byte *pDestinationBuffer) {
-	Common::File pFileHandle;
-	uint16 entrySize;
-	uint16 numEntry;
-	uint16 i;
-	byte *tempBuffer;
-	uint16 dataSize;
+void loadTextData(const char *filename) {
+	Common::File fileHandle;
+	assert(filename);
 
-	assert(pFileName);
-	assert(pDestinationBuffer);
+	if (!fileHandle.open(filename))
+		error("loadTextData(): Cannot open file %s", filename);
 
-	if (!pFileHandle.open(pFileName))
-		error("loadTextData(): Cannot open file %s", pFileName);
+	uint entrySize = fileHandle.readUint16BE();
+	uint numEntry = fileHandle.readUint16BE();
 
-	entrySize = pFileHandle.readUint16BE();
-	numEntry = pFileHandle.readUint16BE();
+	uint sourceSize = numEntry * entrySize;
+	Common::Array<byte> source;
+	source.resize(sourceSize);
+	fileHandle.read(source.begin(), sourceSize);
 
-	dataSize = numEntry * entrySize;
-	pFileHandle.read(pDestinationBuffer, numEntry * entrySize);
-
-	tempBuffer = pDestinationBuffer;
-
+	const int fontHeight = 8;
+	const int fontWidth = (g_cine->getGameType() == Cine::GType_FW) ? 16 : 8;
+	uint numCharacters;
+	uint bytesPerCharacter;
 	if (g_cine->getGameType() == Cine::GType_FW) {
-		int numCharacters;
-		if (g_cine->getFeatures() & GF_ALT_FONT) {
-			numCharacters = 85;
-		} else {
-			numCharacters = 78;
-		}
-
-		dataSize = dataSize / numCharacters;
-
-		loadRelatedPalette(pFileName);
-
-		for (i = 0; i < numCharacters; i++) {
-			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;
-		}
+		numCharacters = (g_cine->getFeatures() & GF_ALT_FONT) ? 85 : 78;		
+		bytesPerCharacter = sourceSize / numCharacters; // TODO: Check if this could be replaced with fontWidth * fontHeight
+		loadRelatedPalette(filename);
 	} else {
-		for (i = 0; i < 90; i++) {
-			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;
-		}
+		numCharacters = 90;
+		bytesPerCharacter = fontWidth * fontHeight;
 	}
 
-	pFileHandle.close();
+	for (uint i = 0; i < numCharacters; i++) {
+		gfxConvertSpriteToRaw(g_cine->_textHandler.textTable[i][0], &source[i * bytesPerCharacter], fontWidth, fontHeight);
+		generateMask(g_cine->_textHandler.textTable[i][0], g_cine->_textHandler.textTable[i][1], fontWidth * fontHeight, 0);
+	}
+
+	fileHandle.close();
 }
 
-const CharacterEntry *fontParamTable;
-
-const CharacterEntry fontParamTable_standard[256] = {
+static const CharacterEntry fontParamTable_standard[NUM_FONT_CHARS] = {
 	{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
 	{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
 	{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
@@ -129,7 +112,7 @@
 	{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}
 };
 
-const CharacterEntry fontParamTable_alt[256] = {
+static const CharacterEntry fontParamTable_alt[NUM_FONT_CHARS] = {
 	{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
 	{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
 	{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
@@ -208,6 +191,16 @@
 		"NOACTION"
 	};
 
+	static const char *commandPrepositionTable_EN[] = {
+		"",   // EXAMINE
+		"",   // TAKE
+		"",   // INVENTORY
+		"on", // USE
+		"",   // OPERATE
+		"to", // SPEAK
+		""    // NOACTION
+	};
+
 	static const CommandeType systemMenu_EN[] = {
 		"Pause",
 		"Restart Game",
@@ -223,9 +216,8 @@
 		"PAUSE",
 		"Loading | %s",
 		"Loading canceled ...",
-		"No baclup in the drive...",
-		"Please enter the backup name",
-		"on"
+		"No backup in the drive...",
+		"Please enter the backup name"
 	};
 
 	static const CommandeType confirmMenu_EN[] = {
@@ -276,6 +268,16 @@
 		"NOACTION"
 	};
 
+	static const char *commandPrepositionTable_FR[] = {
+		"",    // EXAMINER
+		"",    // PRENDRE
+		"",    // INVENTAIRE
+		"sur", // UTILISER
+		"",    // ACTIONNER
+		"a",   // PARLER
+		""     // NOACTION
+	};
+
 	static const CommandeType systemMenu_FR[] = {
 		"Pause",
 		"Nouvelle partie",
@@ -297,8 +299,7 @@
 		"Sauvegarde de | %s",
 		"Sauvegarde Annul\x82""e ...",
 		"Aucune sauvegarde dans le lecteur ...",
-		"Veuillez entrer le Nom de la Sauvegarde .",
-		"sur"
+		"Veuillez entrer le Nom de la Sauvegarde ."
 	};
 
 	static const char *failureMessages_ES[] = {
@@ -344,6 +345,16 @@
 		"NOACTION"
 	};
 
+	static const char *commandPrepositionTable_ES[] = {
+		"",      // EXAMINAR
+		"",      // COGER
+		"",      // INVENTARIO
+		"donde", // USAR
+		"",      // ACCIONAR
+		"a",     // HABLAR
+		""       // NOACTION
+	};
+
 	static const CommandeType systemMenu_ES[] = {
 		"Pause",
 		"Nueva partida",
@@ -365,8 +376,7 @@
 		"Gabacion de| %s",
 		"Rrabacion anulada",
 		"No hay partidas grabadas en este disco...",
-		"Teclea el nombre de la partida grabada",
-		"donde"
+		"Teclea el nombre de la partida grabada"
 	};
 
 	static const char *failureMessages_DE[] = {
@@ -403,15 +413,25 @@
 	};
 
 	static const CommandeType defaultActionCommand_DE[] = {
-		"Pr\x81""fe",
+		"Pr\x81""fe", // FIXME? The third letter should be Latin Small Letter U with diaeresis
 		"Nimm",
 		"Bestand",
 		"Benutze",
-		"Bet\x84tige",
+		"Bet\x84tige", // FIXME? The fourth letter should be Latin Small Letter A with diaeresis
 		"Sprich",
 		"NOACTION"
 	};
 
+	static const char *commandPrepositionTable_DE[] = {
+		"",      // Prufe
+		"",      // Nimm
+		"",      // Bestand
+		"gegen", // Benutze
+		"",      // Betatige
+		"a",     // Sprich
+		""       // NOACTION
+	};
+
 	static const CommandeType systemMenu_DE[] = {
 		"Pause",
 		"Spiel Neu Starten",
@@ -433,8 +453,7 @@
 		"Er L\x84""dt | %s",
 		"Ladevorgang Abgebrochen...",
 		"Kein Backup im Laufwerk...",
-		"Geben Sie den Namen|der Sicherungsdiskette ein",
-		"gegen"
+		"Geben Sie den Namen|der Sicherungsdiskette ein"
 	};
 
 	static const char *failureMessages_IT[] = {
@@ -480,6 +499,16 @@
 		"NOACTION"
 	};
 
+	static const char *commandPrepositionTable_IT[] = {
+		"",   // ESAMINARE
+		"",   // PRENDERE
+		"",   // INVENTARIO
+		"su", // UTILIZZARE
+		"",   // AZIONARE
+		"a",  // PARLARE
+		""    // NOACTION
+	};
+
 	static const CommandeType systemMenu_IT[] = {
 		"Pausa",
 		"Parte nuova",
@@ -501,8 +530,7 @@
 		"Caricamento di| %s",
 		"Caricamento annullato...",
 		"Nessun salvataggio su questo disco...",
-		"Vogliate accedere con il nome del salvataggio",
-		"su"
+		"Vogliate accedere con il nome del salvataggio"
 	};
 
 	switch (lang) {
@@ -512,7 +540,8 @@
 		systemMenu = systemMenu_FR;
 		confirmMenu = confirmMenu_FR;
 		otherMessages = otherMessages_FR;
-		commandPrepositionOn = otherMessages_FR[7];
+		defaultCommandPreposition = commandPrepositionTable_FR[3];
+		commandPrepositionTable = commandPrepositionTable_FR;
 		break;
 
 	case Common::ES_ESP:
@@ -521,7 +550,8 @@
 		systemMenu = systemMenu_ES;
 		confirmMenu = confirmMenu_ES;
 		otherMessages = otherMessages_ES;
-		commandPrepositionOn = otherMessages_ES[7];
+		defaultCommandPreposition = commandPrepositionTable_ES[3];
+		commandPrepositionTable = commandPrepositionTable_ES;
 		break;
 
 	case Common::DE_DEU:
@@ -530,7 +560,8 @@
 		systemMenu = systemMenu_DE;
 		confirmMenu = confirmMenu_DE;
 		otherMessages = otherMessages_DE;
-		commandPrepositionOn = otherMessages_DE[7];
+		defaultCommandPreposition = commandPrepositionTable_DE[3];
+		commandPrepositionTable = commandPrepositionTable_DE;
 		break;
 
 	case Common::IT_ITA:
@@ -539,7 +570,8 @@
 		systemMenu = systemMenu_IT;
 		confirmMenu = confirmMenu_IT;
 		otherMessages = otherMessages_IT;
-		commandPrepositionOn = otherMessages_IT[7];
+		defaultCommandPreposition = commandPrepositionTable_IT[3];
+		commandPrepositionTable = commandPrepositionTable_IT;
 		break;
 
 	default:
@@ -548,14 +580,17 @@
 		systemMenu = systemMenu_EN;
 		confirmMenu = confirmMenu_EN;
 		otherMessages = otherMessages_EN;
-		commandPrepositionOn = otherMessages_EN[7];
+		defaultCommandPreposition = commandPrepositionTable_EN[3];
+		commandPrepositionTable = commandPrepositionTable_EN;
 		break;
 	}
 
 	if (g_cine->getFeatures() & GF_ALT_FONT) {
-		fontParamTable = fontParamTable_alt;
+		// Copy alternative font parameter table to the current font parameter table
+		Common::copy(fontParamTable_alt, fontParamTable_alt + NUM_FONT_CHARS, g_cine->_textHandler.fontParamTable);
 	} else {
-		fontParamTable = fontParamTable_standard;
+		// Copy standard font parameter to the current font parameter table
+		Common::copy(fontParamTable_standard, fontParamTable_standard + NUM_FONT_CHARS, g_cine->_textHandler.fontParamTable);
 	}
 }
 
@@ -590,25 +625,16 @@
 	in.open(fname);
 
 	if (in.isOpen()) {
-		CharacterEntry *ptr = (CharacterEntry *)malloc(sizeof(CharacterEntry) * 256);
-
-		for (int i = 0; i < 256; i++) {
-			ptr[i].characterIdx = (int)in.readByte();
-			ptr[i].characterWidth = (int)in.readByte();
+		for (int i = 0; i < NUM_FONT_CHARS; i++) {
+			g_cine->_textHandler.fontParamTable[i].characterIdx   = in.readByte();
+			g_cine->_textHandler.fontParamTable[i].characterWidth = in.readByte();
 		}
-		fontParamTable = ptr;
-
 		in.close();
 	} else {
 		error("Cannot open file %s for reading", fname);
 	}
 }
 
-void freePoldatDat() {
-	free(const_cast<Cine::CharacterEntry *>(fontParamTable));
-	fontParamTable = 0;
-}
-
 /*! \brief Fit a substring of text into one line of fixed width text box
  * \param str Text to fit
  * \param maxWidth Text box width
@@ -633,7 +659,7 @@
 			bkpWidth = width;
 			bkpLen = i + 1;
 		} else {
-			charWidth = fontParamTable[(unsigned char)str[i]].characterWidth + 1;
+			charWidth = g_cine->_textHandler.fontParamTable[(unsigned char)str[i]].characterWidth + 1;
 			width += charWidth;
 		}
 

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/texte.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/texte.h	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/texte.h	2008-08-16 04:30:01 UTC (rev 33924)
@@ -33,10 +33,17 @@
 
 typedef char CommandeType[20];
 
-extern byte *textDataPtr;
+// Number of characters in a font
+#define NUM_FONT_CHARS 256
 
+struct CharacterEntry {
+	byte characterIdx;
+	byte characterWidth;
+};
+
 struct TextHandler {
-	byte textTable[256][2][16 * 8];
+	byte textTable[NUM_FONT_CHARS][2][16 * 8];
+	CharacterEntry fontParamTable[NUM_FONT_CHARS];
 };
 
 extern const char **failureMessages;
@@ -44,20 +51,13 @@
 extern const CommandeType *systemMenu;
 extern const CommandeType *confirmMenu;
 extern const char **otherMessages;
-extern const char *commandPrepositionOn;
+extern const char *defaultCommandPreposition;
+extern const char **commandPrepositionTable;
 
-struct CharacterEntry {
-	byte characterIdx;
-	byte characterWidth;
-};
-
-extern const CharacterEntry *fontParamTable;
-
-void loadTextData(const char *pFileName, byte *pDestinationBuffer);
+void loadTextData(const char *filename);
 void loadErrmessDat(const char *fname);
 void freeErrmessDat(void);
 void loadPoldatDat(const char *fname);
-void freePoldatDat(void);
 
 int fitLine(const char *ptr, int maxWidth, int &words, int &width);
 

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/various.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/various.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/various.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -77,7 +77,7 @@
 
 int16 playerCommand;
 
-char commandBuffer[80];
+Common::String commandBuffer;
 char currentPrcName[20];
 char currentRelName[20];
 char currentObjectName[20];
@@ -316,6 +316,18 @@
 	}
 }
 
+/*! \brief Save the 80 bytes long command buffer padded to that length with zeroes. */
+void saveCommandBuffer(Common::OutSaveFile &out) {
+	// Let's make sure there's space for the trailing zero
+	// (That's why we subtract one from the maximum command buffer size here).
+	uint32 size = MIN<uint32>(commandBuffer.size(), kMaxCommandBufferSize - 1);
+	out.write(commandBuffer.c_str(), size);
+	// Write the rest as zeroes (Here we also write the string's trailing zero)
+	for (uint i = 0; i < kMaxCommandBufferSize - size; i++) {
+		out.writeByte(0);
+	}
+}
+
 void saveAnimDataTable(Common::OutSaveFile &out) {
 	out.writeUint16BE(NUM_MAX_ANIMDATA); // Entry count
 	out.writeUint16BE(0x1E); // Entry size
@@ -633,7 +645,7 @@
 	playerCommand = -1;
 	isDrawCommandEnabled = 0;
 
-	strcpy(commandBuffer, "");
+	commandBuffer = "";
 
 	globalVars[VAR_MOUSE_X_POS] = 0;
 	globalVars[VAR_MOUSE_Y_POS] = 0;
@@ -834,7 +846,10 @@
 	globalVars.load(in, NUM_MAX_VAR);
 	loadZoneData(in);
 	loadCommandVariables(in);
-	in.read(commandBuffer, 0x50);
+	char tempCommandBuffer[kMaxCommandBufferSize];
+	in.read(tempCommandBuffer, kMaxCommandBufferSize);
+	commandBuffer = tempCommandBuffer;
+	renderer->setCommand(commandBuffer);
 	loadZoneQuery(in);
 
 	// TODO: Use the loaded string (Current music name (String, 13 bytes)).
@@ -971,7 +986,9 @@
 	loadCommandVariables(in);
 
 	// At 0x22A9 (i.e. 0x22A1 + 4 * 2):
-	in.read(commandBuffer, 0x50);
+	char tempCommandBuffer[kMaxCommandBufferSize];
+	in.read(tempCommandBuffer, kMaxCommandBufferSize);
+	commandBuffer = tempCommandBuffer;
 	renderer->setCommand(commandBuffer);
 
 	// At 0x22F9 (i.e. 0x22A9 + 0x50):
@@ -1119,7 +1136,7 @@
 	globalVars.save(out, NUM_MAX_VAR);
 	saveZoneData(out);
 	saveCommandVariables(out);
-	out.write(commandBuffer, 0x50);
+	saveCommandBuffer(out);
 
 	out.writeUint16BE(renderer->_cmdY);
 	out.writeUint16BE(bgVar0);
@@ -1334,7 +1351,7 @@
 	globalVars.save(out, NUM_MAX_VAR);
 	saveZoneData(out);
 	saveCommandVariables(out);
-	out.write(commandBuffer, 0x50);
+	saveCommandBuffer(out);
 	saveZoneQuery(out);
 
 	// FIXME: Save a proper name here, saving an empty string currently.
@@ -1397,19 +1414,38 @@
 }
 
 void processInventory(int16 x, int16 y) {
-	int16 listSize = buildObjectListCommand(-2);
 	uint16 button;
+	int menuWidth;
+	int listSize;
+	int commandParam;
 
+	if (g_cine->getGameType() == Cine::GType_FW) {
+		menuWidth = 140;
+		commandParam = -2;
+	} else { // Operation Stealth
+		menuWidth = 160;
+		commandParam = -3;
+	}
+
+	listSize = buildObjectListCommand(commandParam);
+
 	if (!listSize)
 		return;
 
-	renderer->drawMenu(objectListCommand, listSize, x, y, 140, -1);
+	renderer->drawMenu(objectListCommand, listSize, x, y, menuWidth, -1);
 	renderer->blit();
 
 	do {
 		manageEvents();
 		getMouseData(mouseUpdateStatus, &button, &dummyU16, &dummyU16);
 	} while (!button);
+
+	do {
+		manageEvents();
+		getMouseData(mouseUpdateStatus, &button, &dummyU16, &dummyU16);
+	} while (button);
+
+	// TODO: Both Future Wars and Operation Stealth call showMouse, drawMouse or something similar here.
 }
 
 int16 buildObjectListCommand(int16 param) {
@@ -1453,6 +1489,8 @@
 	return objListTab[selectedObject];
 }
 
+// TODO: Make separate functions for Future Wars's and Operation Stealth's version of this function, this is getting too messy
+// TODO: Add support for using the different prepositions for different verbs (Doesn't work currently)
 void makeCommandLine(void) {
 	uint16 x, y;
 
@@ -1460,9 +1498,9 @@
 	commandVar2 = -10;
 
 	if (playerCommand != -1) {
-		strcpy(commandBuffer, defaultActionCommand[playerCommand]);
+		commandBuffer = defaultActionCommand[playerCommand];
 	} else {
-		strcpy(commandBuffer, "");
+		commandBuffer = "";
 	}
 
 	if ((playerCommand != -1) && (choiceResultTable[playerCommand] == 2)) {	// need object selection ?
@@ -1477,8 +1515,12 @@
 		}
 
 		if (si < 0) {
-			playerCommand = -1;
-			strcpy(commandBuffer, "");
+			if (g_cine->getGameType() == Cine::GType_OS) {
+				canUseOnObject = 0;
+			} else { // Future Wars
+				playerCommand = -1;
+				commandBuffer = "";
+			}
 		} else {
 			if (g_cine->getGameType() == Cine::GType_OS) {
 				if (si >= 8000) {
@@ -1491,23 +1533,28 @@
 
 			commandVar3[0] = si;
 			commandVar1 = 1;
-
-			strcat(commandBuffer, " ");
-			strcat(commandBuffer, objectTable[commandVar3[0]].name);
-			strcat(commandBuffer, " ");
-			strcat(commandBuffer, commandPrepositionOn);
+			commandBuffer += " ";
+			commandBuffer += objectTable[commandVar3[0]].name;
+			commandBuffer += " ";
+			if (g_cine->getGameType() == Cine::GType_OS) {
+				commandBuffer += commandPrepositionTable[playerCommand];
+			} else { // Future Wars
+				commandBuffer += defaultCommandPreposition;
+			}
 		}
-	} else {
+	}
+	
+	if (g_cine->getGameType() == Cine::GType_OS || !(playerCommand != -1 && choiceResultTable[playerCommand] == 2)) {
 		if (playerCommand == 2) {
 			getMouseData(mouseUpdateStatus, &dummyU16, &x, &y);
 			processInventory(x, y + 8);
 			playerCommand = -1;
 			commandVar1 = 0;
-			strcpy(commandBuffer, "");
+			commandBuffer = "";
 		}
 	}
 
-	if (g_cine->getGameType() == Cine::GType_OS) {
+	if (g_cine->getGameType() == Cine::GType_OS && playerCommand != 2) {
 		if (playerCommand != -1 && canUseOnObject != 0)	{ // call use on sub object
 			int16 si;
 
@@ -1515,34 +1562,37 @@
 
 			si = selectSubObject(x, y + 8, -subObjectUseTable[playerCommand]);
 
-			if (si) {
+			if (si >= 0) {
 				if (si >= 8000) {
 					si -= 8000;
 				}
 
 				commandVar3[commandVar1] = si;
-
 				commandVar1++;
-
-				// TODO: add command message draw
+				commandBuffer += " ";
+				commandBuffer += objectTable[si].name;
 			}
+		}
 
-			isDrawCommandEnabled = 1;
+		isDrawCommandEnabled = 1;
 
-			if (playerCommand != -1 && choiceResultTable[playerCommand] == commandVar1) {
-				SelectedObjStruct obj;
-				obj.idx = commandVar3[0];
-				obj.param = commandVar3[1];
-				int16 di = getRelEntryForObject(playerCommand, commandVar1, &obj);
+		if (playerCommand != -1 && choiceResultTable[playerCommand] == commandVar1) {
+			SelectedObjStruct obj;
+			obj.idx = commandVar3[0];
+			obj.param = commandVar3[1];
+			int16 di = getRelEntryForObject(playerCommand, commandVar1, &obj);
 
-				if (di != -1) {
-					runObjectScript(di);
-				}
-			}
+			if (di != -1) {
+				runObjectScript(di);
+			} // TODO: else addFailureMessage(playerCommand)
+
+			playerCommand = -1;
+			commandVar1 = 0;
+			commandBuffer = "";
 		}
 	}
 
-	if (!disableSystemMenu) {
+	if (g_cine->getGameType() == Cine::GType_OS || !disableSystemMenu) {
 		isDrawCommandEnabled = 1;
 		renderer->setCommand(commandBuffer);
 	}
@@ -1759,8 +1809,9 @@
 						commandVar3[commandVar1] = si;
 						commandVar1++;
 
-						strcat(commandBuffer, " ");
-						strcat(commandBuffer, objectTable[si].name);
+						commandBuffer += " ";
+						commandBuffer += objectTable[si].name;
+						
 
 						isDrawCommandEnabled = 1;
 
@@ -1782,8 +1833,8 @@
 							playerCommand = -1;
 
 							commandVar1 = 0;
-							strcpy(commandBuffer, "");
-							renderer->setCommand("");
+							commandBuffer = "";
+							renderer->setCommand(commandBuffer);
 						}
 					} else {
 						globalVars[VAR_MOUSE_X_POS] = mouseX;
@@ -1804,13 +1855,7 @@
 
 				if (commandVar2 != objIdx) {
 					if (objIdx != -1) {
-						char command[256];
-
-						strcpy(command, commandBuffer);
-						strcat(command, " ");
-						strcat(command, objectTable[objIdx].name);
-
-						renderer->setCommand(command);
+						renderer->setCommand(commandBuffer + " " + objectTable[objIdx].name);
 					} else {
 						isDrawCommandEnabled = 1;
 					}
@@ -1986,6 +2031,14 @@
 		}
 	}
 
+	// Update Operation Stealth specific global variables.
+	// This fixes swimming at the bottom of the ocean after
+	// having been thrown into it with the girl.
+	if (g_cine->getGameType() == Cine::GType_OS) {
+		globalVars[251] = globalVars[VAR_MOUSE_X_POS];
+		globalVars[252] = globalVars[VAR_MOUSE_Y_POS];
+	}
+
 	return var_5E;
 }
 

Modified: scummvm/branches/gsoc2008-rtl/engines/cine/various.h
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/cine/various.h	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/cine/various.h	2008-08-16 04:30:01 UTC (rev 33924)
@@ -33,6 +33,9 @@
 
 namespace Cine {
 
+// Maximum size of the command buffer including the trailing zero
+#define kMaxCommandBufferSize 80
+
 void initLanguage(Common::Language lang);
 
 int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, uint16 Y, uint16 width, bool recheckValue = false);
@@ -85,7 +88,7 @@
 
 extern int16 playerCommand;
 
-extern char commandBuffer[80];
+extern Common::String commandBuffer;
 
 extern char currentPrcName[20];
 extern char currentRelName[20];

Modified: scummvm/branches/gsoc2008-rtl/engines/gob/mult_v2.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/gob/mult_v2.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/gob/mult_v2.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -510,10 +510,11 @@
 	if (!_animSurf) {
 		int16 width, height;
 
-		for (int i = 0; i < _objCount; i++) {
-			delete _objects[i].pPosX;
-			delete _objects[i].pPosY;
-		}
+		if (_objects)
+			for (int i = 0; i < _objCount; i++) {
+				delete _objects[i].pPosX;
+				delete _objects[i].pPosY;
+			}
 
 		delete[] _objects;
 	

Modified: scummvm/branches/gsoc2008-rtl/engines/kyra/detection.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/kyra/detection.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/kyra/detection.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -67,11 +67,14 @@
 #define KYRA3_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, true, false, Kyra::GI_KYRA3)
 
 #define LOL_CD_FLAGS FLAGS(false, false, true, false, false, false, Kyra::GI_LOL)
+#define LOL_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, Kyra::GI_LOL)
+#define LOL_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, true, Kyra::GI_LOL)
 #define LOL_PC98_FLAGS FLAGS(false, false, false, false, false, false, Kyra::GI_LOL)
 #define LOL_PC98_SJIS_FLAGS FLAGS(false, false, false, true, false, false, Kyra::GI_LOL)
 #define LOL_DEMO_FLAGS FLAGS(true, false, false, false, false, false, Kyra::GI_KYRA2)
 
 const KYRAGameDescription adGameDescs[] = {
+	/* disable these targets until they get supported
 	{
 		{
 			"kyra1",
@@ -83,6 +86,7 @@
 		},
 		KYRA1_FLOPPY_CMP_FLAGS
 	},
+
 	{
 		{
 			"kyra1",
@@ -94,6 +98,8 @@
 		},
 		KYRA1_FLOPPY_CMP_FLAGS
 	},
+	*/
+
 	{
 		{
 			"kyra1",
@@ -460,6 +466,42 @@
 		KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
 	},
 
+	{ 
+		{
+			"kyra2",
+			"CD",
+			AD_ENTRY1("FATE.PAK", "39772ff82e42c4c520050518deb82e64"),
+			Common::IT_ITA,
+			Common::kPlatformPC,
+			Common::ADGF_DROPLANGUAGE | Common::ADGF_CD
+		},
+		KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+	},
+
+	{ 
+		{
+			"kyra2",
+			"CD",
+			AD_ENTRY1("FATE.PAK", "39772ff82e42c4c520050518deb82e64"),
+			Common::DE_DEU,
+			Common::kPlatformPC,
+			Common::ADGF_DROPLANGUAGE | Common::ADGF_CD
+		},
+		KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+	},
+
+	{ 
+		{
+			"kyra2",
+			"CD",
+			AD_ENTRY1("FATE.PAK", "39772ff82e42c4c520050518deb82e64"),
+			Common::FR_FRA,
+			Common::kPlatformPC,
+			Common::ADGF_DROPLANGUAGE | Common::ADGF_CD
+		},
+		KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+	},
+
 	{ // Interactive Demo
 		{
 			"kyra2",
@@ -649,6 +691,53 @@
 		KYRA3_CD_INS_FLAGS
 	},
 
+	// Mac version
+	{ 
+		{
+			"kyra3",
+			0,
+			{
+				{ "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 },
+				{ "AUD.PAK", 0, 0, -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::EN_ANY,
+			Common::kPlatformMacintosh,
+			Common::ADGF_DROPLANGUAGE
+		},
+		KYRA3_CD_INS_FLAGS
+	},
+	{
+		{
+			"kyra3",
+			0,
+			{
+				{ "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 },
+				{ "AUD.PAK", 0, 0, -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::DE_DEU,
+			Common::kPlatformMacintosh,
+			Common::ADGF_DROPLANGUAGE
+		},
+		KYRA3_CD_INS_FLAGS
+	},
+	{
+		{
+			"kyra3",
+			0,
+			{
+				{ "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 },
+				{ "AUD.PAK", 0, 0, -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::FR_FRA,
+			Common::kPlatformMacintosh,
+			Common::ADGF_DROPLANGUAGE
+		},
+		KYRA3_CD_INS_FLAGS
+	},
+
 	// Spanish fan translation, see fr#1994040 "KYRA3: Add support for Spanish fan translation"
 	{
 		{
@@ -696,7 +785,7 @@
 		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"
+	// Italian fan translation, see fr#2003504 "KYRA: add support for Italian version of Kyrandia 2&3"
 	{
 		{
 			"kyra3",
@@ -839,12 +928,44 @@
 		},
 		LOL_CD_FLAGS
 	},
-	
-	/*{
+
+	{
 		{
 			"lol",
 			0,
 			{
+				{ "WESTWOOD.1", 0, "3c61cb7de5b2ec452f5851f5075207ee", -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::DE_DEU,
+			Common::kPlatformPC,
+			Common::ADGF_NO_FLAGS
+		},
+		LOL_FLOPPY_CMP_FLAGS
+	},
+
+	{
+		{
+			"lol",
+			"Extracted",
+			{
+				{ "GENERAL.PAK", 0, "996e66e81054d36249907a1d8158da3d", -1 },
+				{ "CHAPTER7.PAK", 0, "cabee57f00d6d84b65a732b6868a4959", -1 },
+				{ 0, 0, 0, 0 }
+			},
+			Common::DE_DEU,
+			Common::kPlatformPC,
+			Common::ADGF_NO_FLAGS
+		},
+		LOL_FLOPPY_FLAGS
+	},
+
+	/* disable these targets until they get supported
+	{
+		{
+			"lol",
+			0,
+			{
 				{ "GENERAL.PAK", 0, "3fe6539b9b09084c0984eaf7170464e9", -1 },
 				{ "MUS.PAK", 0, "008dc69d8cbcdb6bae30e270fab26e76", -1 },
 				{ 0, 0, 0, 0 }

Modified: scummvm/branches/gsoc2008-rtl/engines/kyra/lol.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/kyra/lol.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/kyra/lol.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -255,11 +255,14 @@
 		"xxx/intro9.pak"
 	};
 
-	char filename[32];
+	char filepath[32];
+	char *filename = filepath;
 	for (uint i = 0; i < ARRAYSIZE(fileList); ++i) {
 		strcpy(filename, fileList[i]);
 		memcpy(filename, _languageExt[_lang], 3);
-
+		if (!_flags.isTalkie)
+			filename += 4;		
+		
 		if (load) {
 			if (!_res->loadPakFile(filename))
 				error("Couldn't load file: '%s'", filename);

Modified: scummvm/branches/gsoc2008-rtl/engines/kyra/resource.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/kyra/resource.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/kyra/resource.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -103,6 +103,9 @@
 
 		return true;
 	} else if (_vm->game() == GI_LOL) {
+		if (_vm->gameFlags().useInstallerPackage)
+			tryLoadCompFiles();
+
 		return true;
 	}
 
@@ -181,8 +184,14 @@
 	for (ResArchiveLoader::FileList::iterator i = files.begin(); i != files.end(); ++i) {
 		iter = _map.find(i->filename);
 		if (iter == _map.end()) {
+			// We do an internal check for a file in gamepath with same filename to
+			// allow overwriting files inside archives with plain files inside the
+			// game directory
+			checkFile(i->filename);
+
 			// A new file entry, so we just insert it into the file map.
-			_map[i->filename] = i->entry;
+			if (_map.find(i->filename) == _map.end())
+				_map[i->filename] = i->entry;
 		} else if (!iter->_value.parent.empty()) {
 			if (!iter->_value.parent.equalsIgnoreCase(filename)) {
 				ResFileMap::iterator oldParent = _map.find(iter->_value.parent);
@@ -350,7 +359,17 @@
 Common::SeekableReadStream *Resource::getFileStream(const Common::String &file) {
 	CompFileMap::iterator compEntry;
 
-	if (Common::File::exists(file)) {
+	if ((compEntry = _compFiles.find(file)) != _compFiles.end())
+		return new Common::MemoryReadStream(compEntry->_value.data, compEntry->_value.size, false);		
+
+	if (!isAccessable(file))
+		return 0;
+
+	ResFileMap::const_iterator iter = _map.find(file);
+	if (iter == _map.end())
+		return 0;
+
+	if (iter->_value.parent.empty()) {
 		Common::File *stream = new Common::File();
 		if (!stream->open(file)) {
 			delete stream;
@@ -358,28 +377,15 @@
 			error("Couldn't open file '%s'", file.c_str());
 		}
 		return stream;
-	} else if ((compEntry = _compFiles.find(file)) != _compFiles.end()) {
-		return new Common::MemoryReadStream(compEntry->_value.data, compEntry->_value.size, false);		
 	} else {
-		if (!isAccessable(file))
-			return 0;
+		Common::SeekableReadStream *parent = getFileStream(iter->_value.parent);
+		assert(parent);
 
-		ResFileMap::const_iterator iter = _map.find(file);
-		if (iter == _map.end())
-			return 0;
+		ResFileMap::const_iterator parentIter = _map.find(iter->_value.parent);
+		const ResArchiveLoader *loader = getLoader(parentIter->_value.type);
+		assert(loader);
 
-		if (!iter->_value.parent.empty()) {
-			Common::SeekableReadStream *parent = getFileStream(iter->_value.parent);
-			assert(parent);
-
-			ResFileMap::const_iterator parentIter = _map.find(iter->_value.parent);
-			const ResArchiveLoader *loader = getLoader(parentIter->_value.type);
-			assert(loader);
-
-			return loader->loadFileFromArchive(file, parent, iter->_value);
-		} else {
-			error("Couldn't open file '%s'", file.c_str());
-		}
+		return loader->loadFileFromArchive(file, parent, iter->_value);
 	}
 
 	return 0;
@@ -411,7 +417,19 @@
 	if (_map.find(file) == _map.end()) {
 		CompFileMap::const_iterator iter;
 
-		if (Common::File::exists(file)) {
+		if ((iter = _compFiles.find(file)) != _compFiles.end()) {
+			ResFileEntry entry;
+			entry.parent = "";
+			entry.size = iter->_value.size;
+			entry.mounted = false;
+			entry.preload = false;
+			entry.prot = false;
+			entry.type = ResFileEntry::kAutoDetect;
+			entry.offset = 0;
+			_map[file] = entry;
+
+			detectFileTypes();
+		} else if (Common::File::exists(file)) {
 			Common::File temp;
 			if (temp.open(file)) {
 				ResFileEntry entry;
@@ -427,18 +445,6 @@
 
 				detectFileTypes();
 			}
-		} else if ((iter = _compFiles.find(file)) != _compFiles.end()) {
-			ResFileEntry entry;
-			entry.parent = "";
-			entry.size = iter->_value.size;
-			entry.mounted = false;
-			entry.preload = false;
-			entry.prot = false;
-			entry.type = ResFileEntry::kAutoDetect;
-			entry.offset = 0;
-			_map[file] = entry;
-
-			detectFileTypes();
 		}
 	}
 }
@@ -1257,10 +1263,17 @@
 
 class CompLoaderInsHof : public CompArchiveLoader {
 public:
-	bool checkForFiles() const;
-	bool loadFile(CompFileMap &loadTo) const;
+	CompLoaderInsHof() {
+		_fileExtP = "%03d";
+		_checkFile1 = "WESTWOOD.001";
+		_checkFile2 = "WESTWOOD.002";
+		_containerOffset = 6;
+	}
 
-private:
+	virtual bool checkForFiles() const;
+	virtual bool loadFile(CompFileMap &loadTo) const;
+
+protected:
 	struct Archive {
 		Common::String filename;
 		uint32 firstFile;
@@ -1269,10 +1282,25 @@
 		uint32 endOffset;
 		uint32 totalSize;
 	};
+
+	const char *_fileExtP;
+	const char *_checkFile1;
+	const char *_checkFile2;
+	uint8 _containerOffset;
 };
 
+class CompLoaderInsLol : public CompLoaderInsHof {
+public:
+	CompLoaderInsLol() {
+		_fileExtP = "%d";
+		_checkFile1 = "WESTWOOD.1";
+		_checkFile2 = "WESTWOOD.2";
+		_containerOffset = 0;
+	}
+};
+
 bool CompLoaderInsHof::checkForFiles() const {
-	return (Common::File::exists("WESTWOOD.001") && Common::File::exists("WESTWOOD.002"));
+	return (Common::File::exists(_checkFile1) && Common::File::exists(_checkFile2));
 }
 
 bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const {
@@ -1294,7 +1322,7 @@
 	Common::List<Archive> archives;
 
 	for (int8 currentFile = 1; currentFile; currentFile++) {
-		sprintf(filenameExt, "%03d", currentFile);
+		sprintf(filenameExt, _fileExtP, currentFile);
 		filenameTemp = filenameBase + Common::String(filenameExt);
 
 		if (!tmpFile.open(filenameTemp)) {
@@ -1310,9 +1338,9 @@
 		if (startFile) {
 			size -= 4;
 			if (fileId == currentFile) {
-				size -= 6;
-				pos += 6;
-				tmpFile.seek(6, SEEK_CUR);
+				size -= _containerOffset;
+				pos += _containerOffset;
+				tmpFile.seek(_containerOffset, SEEK_CUR);
 			} else {
 				size = size + 1 - pos;
 			}
@@ -1356,6 +1384,7 @@
 	uint8 *outbuffer = 0;
 	uint32 inPart1 = 0;
 	uint32 inPart2 = 0;
+	uint8 compressionType = 0;
 	Common::String entryStr;
 
 	pos = 0;
@@ -1367,7 +1396,7 @@
 	for (Common::List<Archive>::iterator a = archives.begin(); a != archives.end(); ++a) {
 		startFile = true;
 		for (uint32 i = a->firstFile; i != (a->lastFile + 1); i++) {
-			sprintf(filenameExt, "%03d", i);
+			sprintf(filenameExt, _fileExtP, i);
 			filenameTemp = a->filename + Common::String(filenameExt);
 
 			if (!tmpFile.open(filenameTemp)) {
@@ -1390,7 +1419,12 @@
 					tmpFile.seek(1);
 					tmpFile.read(inbuffer + inPart1, inPart2);
 					inPart2 = 0;
-					exp.process(outbuffer, inbuffer, outsize, insize);
+
+					if (compressionType > 0)
+						exp.process(outbuffer, inbuffer, outsize, insize);
+					else
+						memcpy(outbuffer, inbuffer, outsize);
+
 					delete[] inbuffer;
 					inbuffer = 0;
 					newEntry.data = outbuffer;
@@ -1419,7 +1453,7 @@
 						}
 					}
 				
-					sprintf(filenameExt, "%03d", i + 1);
+					sprintf(filenameExt, _fileExtP, i + 1);
 					filenameTemp = a->filename + Common::String(filenameExt);
 
 					Common::File tmpFile2;
@@ -1435,8 +1469,7 @@
 				uint32 id = READ_LE_UINT32(hdr);
 				
 				if (id == 0x04034B50) {
-					if (hdr[8] != 8)
-						error("compression type not implemented");
+					compressionType = hdr[8];
 					insize = READ_LE_UINT32(hdr + 18);
 					outsize = READ_LE_UINT32(hdr + 22);
 			
@@ -1464,7 +1497,12 @@
 					} else {
 						tmpFile.read(inbuffer, insize);
 						inPart2 = 0;
-						exp.process(outbuffer, inbuffer, outsize, insize);
+
+						if (compressionType > 0)
+							exp.process(outbuffer, inbuffer, outsize, insize);
+						else
+							memcpy(outbuffer, inbuffer, outsize);
+
 						delete[] inbuffer;
 						inbuffer = 0;
 						newEntry.data = outbuffer;
@@ -1498,6 +1536,7 @@
 	_loaders.push_back(LoaderList::value_type(new ResLoaderTlk()));
 
 	_compLoaders.push_back(CompLoaderList::value_type(new CompLoaderInsHof()));
+	_compLoaders.push_back(CompLoaderList::value_type(new CompLoaderInsLol()));
 }
 
 const ResArchiveLoader *Resource::getLoader(ResFileEntry::kType type) const {

Modified: scummvm/branches/gsoc2008-rtl/engines/parallaction/balloons.cpp
===================================================================
--- scummvm/branches/gsoc2008-rtl/engines/parallaction/balloons.cpp	2008-08-16 04:15:11 UTC (rev 33923)
+++ scummvm/branches/gsoc2008-rtl/engines/parallaction/balloons.cpp	2008-08-16 04:30:01 UTC (rev 33924)
@@ -30,7 +30,184 @@
 
 namespace Parallaction {
 
+class WrappedLineFormatter {
 
+protected:
+	Common::String _line;
+	Font *_font;
+	uint16 _lines, _lineWidth;
+
+	virtual void setup() = 0;
+	virtual void action() = 0;
+	virtual void end() = 0;
+	virtual Common::String expand(const Common::String &token) { return token; }
+
+	void textAccum(const Common::String &token, uint16 width) {
+		if (token.empty()) {
+			return;
+		}
+
+		_lineWidth += width;
+		_line += token;
+	}
+
+	void textNewLine() {
+		_lines++;
+		_lineWidth = 0;
+		_line.clear();
+	}
+
+public:
+	WrappedLineFormatter(Font *font) : _font(font) { }
+	virtual ~WrappedLineFormatter() { }
+
+	virtual void calc(const char *text, uint16 maxwidth) {
+		setup();
+
+		_lineWidth = 0;
+		_line.clear();
+		_lines = 0;
+
+		Common::StringTokenizer	tokenizer(text, " ");
+		Common::String token;
+		Common::String blank(" ");
+
+		uint16 blankWidth = _font->getStringWidth(" ");
+		uint16 tokenWidth = 0;
+
+		while (!tokenizer.empty()) {
+			token = tokenizer.nextToken();
+			token = expand(token);
+
+			if (token == '/') {
+				tokenWidth = 0;
+				action();
+				textNewLine();
+			} else {
+				// todo: expand '%'
+				tokenWidth = _font->getStringWidth(token.c_str());
+
+				if (_lineWidth == 0) {
+					textAccum(token, tokenWidth);
+				} else {
+					if (_lineWidth + blankWidth + tokenWidth <= maxwidth) {
+						textAccum(blank, blankWidth);
+						textAccum(token, tokenWidth);
+					} else {
+						action();
+						textNewLine();
+						textAccum(token, tokenWidth);
+					}
+				}
+			}
+		}
+
+		end();
+	}
+};
+
+class StringExtent_NS : public WrappedLineFormatter {
+
+	uint	_width, _height;
+
+protected:
+	virtual Common::String expand(const Common::String &token) {
+		if (token.compareToIgnoreCase("%p") == 0) {
+			return Common::String("/");
+		}
+
+		return token;
+	}
+
+	virtual void setup() {
+		_width = _height = 0;
+
+		_line.clear();
+		_lines = 0;
+		_width = 0;
+	}
+
+	virtual void action() {
+		if (_lineWidth > _width) {
+			_width = _lineWidth;
+		}
+		_height = _lines * _font->height();
+	}
+
+	virtual void end() {
+		action();
+	}
+
+public:
+	StringExtent_NS(Font *font) : WrappedLineFormatter(font) { }
+
+	uint width() const { return _width; }
+	uint height() const { return _height; }
+};
+
+
+class StringWriter_NS : public WrappedLineFormatter {
+
+	uint	_width, _height;
+	byte	_color;
+
+	Graphics::Surface	*_surf;
+
+protected:
+	virtual Common::String expand(const Common::String& token) {
+		if (token.compareToIgnoreCase("%p") == 0) {
+			Common::String t(".......");
+			for (int i = 0; _password[i]; i++) {
+				t.setChar(_password[i], i);
+			}
+			return Common::String("> ") + t;
+		} else
+		if (token.compareToIgnoreCase("%s") == 0) {
+			char buf[20];
+			sprintf(buf, "%i", _score);
+			return Common::String(buf);
+		}
+
+		return token;
+	}
+
+	virtual void setup() {
+	}
+
+	virtual void action() {
+		if (_line.empty()) {
+			return;
+		}
+		uint16 rx = 10;
+		uint16 ry = 4 + _lines * _font->height();	// y
+
+		byte *dst = (byte*)_surf->getBasePtr(rx, ry);
+		_font->setColor(_color);
+		_font->drawString(dst, _surf->w, _line.c_str());
+	}
+
+	virtual void end() {
+		action();
+	}
+
+public:
+	StringWriter_NS(Font *font) : WrappedLineFormatter(font) { }
+
+	void write(const char *text, uint maxWidth, byte color, Graphics::Surface *surf) {
+		StringExtent_NS	se(_font);
+		se.calc(text, maxWidth);
+		_width = se.width() + 10;
+		_height = se.height() + 20;
+		_color = color;
+		_surf = surf;
+
+		calc(text, maxWidth);
+	}
+
+};
+
+
+
 #define	BALLOON_TRANSPARENT_COLOR_NS 2
 #define BALLOON_TRANSPARENT_COLOR_BR 0
 
@@ -78,8 +255,6 @@
 
 	uint	_numBalloons;
 
-	void getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height);
-	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);
 
@@ -152,12 +327,16 @@
 
 	int16 w, h;
 
-	getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
+	StringExtent_NS	se(_vm->_dialogueFont);
+	se.calc(text, MAX_BALLOON_WIDTH);
+	w = se.width() + 14;
+	h = se.height() + 20;
 
 	int id = createBalloon(w+5, h, winding, 1);
 	Balloon *balloon = &_intBalloons[id];
 
-	drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+	StringWriter_NS sw(_vm->_dialogueFont);
+	sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface);
 
 	// TODO: extract some text to make a name for obj
 	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
@@ -172,12 +351,17 @@
 
 	int16 w, h;
 
-	getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
+	StringExtent_NS	se(_vm->_dialogueFont);
+	se.calc(text, MAX_BALLOON_WIDTH);
+	w = se.width() + 14;
+	h = se.height() + 20;
 
+
 	int id = createBalloon(w+5, h, winding, 1);
 	Balloon *balloon = &_intBalloons[id];
 
-	drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+	StringWriter_NS sw(_vm->_dialogueFont);
+	sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface);
 
 	// TODO: extract some text to make a name for obj
 	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
@@ -196,7 +380,9 @@
 void BalloonManager_ns::setBalloonText(uint id, char *text, byte textColor) {
 	Balloon *balloon = getBalloon(id);
 	balloon->surface->fillRect(balloon->innerBox, 1);
-	drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+
+	StringWriter_NS sw(_vm->_dialogueFont);
+	sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface);
 }
 
 
@@ -204,11 +390,15 @@
 
 	int16 w, h;
 
-	getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
+	StringExtent_NS	se(_vm->_dialogueFont);
+	se.calc(text, MAX_BALLOON_WIDTH);
+	w = se.width() + 14;
+	h = se.height() + 20;
 
 	int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR_NS);
 	Balloon *balloon = &_intBalloons[id];
-	drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH);
+	StringWriter_NS sw(_vm->_dialogueFont);
+	sw.write(text, MAX_BALLOON_WIDTH, 0, balloon->surface);
 
 	// TODO: extract some text to make a name for obj
 	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
@@ -245,114 +435,103 @@
 	_numBalloons = 0;
 }
 
-// TODO: get rid of parseNextToken from here. Use the
-// StringTokenizer instead.
-void BalloonManager_ns::drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth) {
 
-	uint16 lines = 0;
-	uint16 linewidth = 0;
 
-	uint16 rx = 10;
-	uint16 ry = 4;
 
-	uint16 blankWidth = font->getStringWidth(" ");
-	uint16 tokenWidth = 0;
 
-	char token[MAX_TOKEN_LEN];
 
-	if (wrapwidth == -1)
-		wrapwidth = _vm->_screenWidth;
 
-	while (strlen(text) > 0) {
 
-		text = parseNextToken(text, token, MAX_TOKEN_LEN, "   ", true);
 
-		if (!scumm_stricmp(token, "%p")) {
-			lines++;
-			rx = 10;
-			ry = 4 + lines*10;	// y
 
-			strcpy(token, "> .......");
-			strncpy(token+2, _password, strlen(_password));
-			tokenWidth = font->getStringWidth(token);
-		} else {
-			tokenWidth = font->getStringWidth(token);
 
-			linewidth += tokenWidth;
+class StringExtent_BR : public WrappedLineFormatter {
 
-			if (linewidth > wrapwidth) {
-				// wrap line
-				lines++;
-				rx = 10;			// x
-				ry = 4 + lines*10;	// y
-				linewidth = tokenWidth;
-			}
+	uint	_width, _height;
 
-			if (!scumm_stricmp(token, "%s")) {
-				sprintf(token, "%d", _score);
-			}
+protected:
+	virtual void setup() {
+		_width = _height = 0;
 
+		_line.clear();
+		_lines = 0;
+		_width = 0;
+	}
+
+	virtual void action() {
+		if (_lineWidth > _width) {
+			_width = _lineWidth;
 		}
+		_height = _lines * _font->height();
+	}
 
-		_gfx->drawText(font, surf, rx, ry, token, color);
-
-		rx += tokenWidth + blankWidth;
-		linewidth += blankWidth;
-
-		text = Common::ltrim(text);
+	virtual void end() {
+		action();
 	}
 
-}
+public:
+	StringExtent_BR(Font *font) : WrappedLineFormatter(font) { }
 
-// TODO: get rid of parseNextToken from here. Use the
-// StringTokenizer instead.
-void BalloonManager_ns::getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height) {
+	uint width() const { return _width; }
+	uint height() const { return _height; }
+};
 
-	uint16 lines = 0;
-	uint16 w = 0;
-	*width = 0;
 
-	uint16 blankWidth = font->getStringWidth(" ");
-	uint16 tokenWidth = 0;
+class StringWriter_BR : public WrappedLineFormatter {
 
-	char token[MAX_TOKEN_LEN];
+	uint	_width, _height;
+	byte	_color;
+	uint	_x, _y;
 
-	while (strlen(text) != 0) {
+	Graphics::Surface	*_surf;
 
-		text = parseNextToken(text, token, MAX_TOKEN_LEN, "   ", true);
-		tokenWidth = font->getStringWidth(token);
+protected:
+	StringWriter_BR(Font *font, byte color) : WrappedLineFormatter(font) {
 
-		w += tokenWidth;
+	}
 
-		if (!scumm_stricmp(token, "%p")) {
-			lines++;
-		} else {
-			if (w > maxwidth) {
-				w -= tokenWidth;
-				lines++;
-				if (w > *width)
-					*width = w;
+	virtual void setup() {
+	}
 
-				w = tokenWidth;
-			}
+	virtual void action() {
+		if (_line.empty()) {
+			return;
 		}
+		uint16 rx = _x + (_surf->w - _lineWidth) / 2;
+		uint16 ry = _y + _lines * _font->height();	// y
 
-		w += blankWidth;
-		text = Common::ltrim(text);
+		byte *dst = (byte*)_surf->getBasePtr(rx, ry);
+		_font->setColor(_color);
+		_font->drawString(dst, _surf->w, _line.c_str());
 	}
 
-	if (*width < w) *width = w;
-	*width += 10;
+	virtual void end() {
+		action();
+	}
 
-	*height = lines * 10 + 20;
+public:
+	StringWriter_BR(Font *font) : WrappedLineFormatter(font) { }
 
-	return;
-}
+	void write(const char *text, uint maxWidth, byte color, Graphics::Surface *surf) {
+		maxWidth = 216;
 
+		StringExtent_BR	se(_font);
+		se.calc(text, maxWidth);
+		_width = se.width() + 10;
+		_height = se.height() + 12;
+		_color = color;
+		_surf = surf;
 
+		_x = 0;
+		_y = (_surf->h - _height) / 2;
+		calc(text, maxWidth);
+	}
 
+};
 
 
+
+
 class BalloonManager_br : public BalloonManager {
 
 	struct Balloon {
@@ -370,30 +549,13 @@
 	Frames *_rightBalloon;
 
 	void cacheAnims();
-	void getStringExtent(Font *font, const char *text, uint16 maxwidth, int16* width, int16* height);
 	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);
 
-	void textSetupRendering(const Common::String &text, Graphics::Surface *dest, Font *font, byte color);
-	void textEmitCenteredLine();
-	void textAccum(const Common::String &token, uint16 width);
-	void textNewLine();
+	StringWriter_BR	_writer;
 
-	Common::String _textLine;
-	Graphics::Surface *_textSurf;
-	Font *_textFont;
-	uint16 _textX, _textY;
-	byte _textColor;
-	uint16 _textLines, _textWidth;
-
-	void extentSetup(Font *font, int16 *width, int16 *height);
-	void extentAction();
-
-	int16 *_extentWidth, *_extentHeight;
-
-
 public:
 	BalloonManager_br(Disk *disk, Gfx *gfx);
 	~BalloonManager_br();
@@ -451,7 +613,7 @@
 	balloon->surface = expandBalloon(src, srcFrame);
 	src->getRect(srcFrame, balloon->box);
 
-	drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+	_writer.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface);
 
 	// TODO: extract some text to make a name for obj
 	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
@@ -487,7 +649,7 @@
 	balloon->surface = expandBalloon(src, srcFrame);
 	src->getRect(srcFrame, balloon->box);
 
-	drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
+	_writer.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface);
 
 	// TODO: extract some text to make a name for obj
 	balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
@@ -558,157 +720,11 @@
 }
 
 
-void BalloonManager_br::extentSetup(Font *font, int16 *width, int16 *height) {
-	_extentWidth = width;
-	_extentHeight = height;
 
-	_textLine.clear();
-	_textLines = 0;
-	_textWidth = 0;
-	_textFont = font;
+BalloonManager_br::BalloonManager_br(Disk *disk, Gfx *gfx) : _numBalloons(0), _disk(disk), _gfx(gfx),
+	_leftBalloon(0), _rightBalloon(0), _writer(_vm->_dialogueFont) {
 }
 
-void BalloonManager_br::extentAction() {
-	if (_textWidth > *_extentWidth) {
-		*_extentWidth = _textWidth;
-	}
-	*_extentHeight = _textLines * _textFont->height();
-}
-
-void BalloonManager_br::textSetupRendering(const Common::String &text, Graphics::Surface *dest, Font *font, byte color) {
-	uint16 maxWidth = 216;
-
-	int16 w, h;
-	getStringExtent(font, text.c_str(), maxWidth, &w, &h);
-
-	w += 10;
-	h += 12;
-
-	_textLine.clear();
-	_textSurf = dest;
-	_textFont = font;
-	_textX = 0;
-	_textY = (_textSurf->h - h) / 2;
-	_textColor = color;
-	_textLines = 0;
-	_textWidth = 0;
-}
-
-void BalloonManager_br::textEmitCenteredLine() {
-	if (_textLine.empty()) {
-		return;
-	}
-	uint16 rx = _textX + (_textSurf->w - _textWidth) / 2;
-	uint16 ry = _textY + _textLines * _textFont->height();	// y
-	_gfx->drawText(_textFont, _textSurf, rx, ry, _textLine.c_str(), _textColor);
-}
-
-void BalloonManager_br::textAccum(const Common::String &token, uint16 width) {
-	if (token.empty()) {
-		return;
-	}
-
-	_textWidth += width;
-	_textLine += token;
-}
-
-void BalloonManager_br::textNewLine() {
-	_textLines++;
-	_textWidth = 0;
-	_textLine.clear();
-}
-
-
-// TODO: really, base this and getStringExtent on some kind of LineTokenizer, instead of
-// repeating the algorithm and changing a couple of lines.
-void BalloonManager_br::drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapWidth) {
-	textSetupRendering(text, surf, font, color);
-
-	wrapWidth = 216;
-
-	Common::StringTokenizer	tokenizer(text, " ");
-	Common::String token;
-	Common::String blank(" ");
-

@@ 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