[Scummvm-cvs-logs] SF.net SVN: scummvm: [28198] scummvm/branches/branch-0-10-0/engines/ parallaction

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Wed Jul 25 21:01:58 CEST 2007


Revision: 28198
          http://scummvm.svn.sourceforge.net/scummvm/?rev=28198&view=rev
Author:   peres001
Date:     2007-07-25 12:01:58 -0700 (Wed, 25 Jul 2007)

Log Message:
-----------
Backporting changes in revisions range 27457:28106. 

Modified Paths:
--------------
    scummvm/branches/branch-0-10-0/engines/parallaction/animation.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/archive.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/callables.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/defs.h
    scummvm/branches/branch-0-10-0/engines/parallaction/detection.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/dialogue.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/disk.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/disk.h
    scummvm/branches/branch-0-10-0/engines/parallaction/graphics.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/graphics.h
    scummvm/branches/branch-0-10-0/engines/parallaction/intro.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/inventory.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/inventory.h
    scummvm/branches/branch-0-10-0/engines/parallaction/location.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/menu.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/menu.h
    scummvm/branches/branch-0-10-0/engines/parallaction/parallaction.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/parallaction.h
    scummvm/branches/branch-0-10-0/engines/parallaction/parser.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/parser.h
    scummvm/branches/branch-0-10-0/engines/parallaction/saveload.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/zone.cpp
    scummvm/branches/branch-0-10-0/engines/parallaction/zone.h

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/animation.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/animation.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/animation.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -166,15 +166,19 @@
 		if ((v18->_flags & kFlagsActive) && ((v18->_flags & kFlagsRemove) == 0))   {
 			v14._width = v18->width();
 			v14._height = v18->height();
-			v14._data0 = v18->getFrameData(v18->_frame);
-//			v14._data1 = v18->_cnv->field_8[v18->_frame];
 
+			int16 frame = CLIP((int)v18->_frame, 0, v18->getFrameNum()-1);
+
+			v14._data0 = v18->getFrameData(frame);
+//			v14._data1 = v18->_cnv->field_8[frame];
+
 			if (v18->_flags & kFlagsNoMasked)
 				_si = 3;
 			else
 				_si = _vm->_gfx->queryMask(v18->_top + v18->height());
 
-			debugC(9, kDebugLocation, "jobDisplayAnimations(%s, x:%i, y:%i, z:%i, w:%i, h:%i, %p)", v18->_label._text, v18->_left, v18->_top, _si, v14._width, v14._height, v14._data0);
+			debugC(9, kDebugLocation, "jobDisplayAnimations(%s, x:%i, y:%i, z:%i, w:%i, h:%i, f:%i/%i, %p)", v18->_label._text, v18->_left, v18->_top, _si, v14._width, v14._height,
+				frame, v18->getFrameNum(), v14._data0);
 			_vm->_gfx->blitCnv(&v14, v18->_left, v18->_top, _si, Gfx::kBitBack);
 
 		}

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/archive.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/archive.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/archive.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -22,7 +22,9 @@
  * $Id$
  *
  */
+#include "common/stdafx.h"
 
+#include "common/endian.h"
 #include "common/file.h"
 
 #include "parallaction/disk.h"
@@ -31,11 +33,16 @@
 
 namespace Parallaction {
 
-//	HACK: one archive ('fr') in Nippon Safes Demo for Amiga uses different
-//  internal offsets than all the other archives. When an archive is opened
-//  its size if checked against SIZEOF_SMALL_ARCHIVE ('fr' size) so Archive
-//  can behave properly.
+//  HACK: Several archives ('de', 'en', 'fr' and 'disk0') in the multi-lingual
+//  Amiga version of Nippon Safes, and one archive ('fr') in the Amiga Demo of
+//  Nippon Safes used different internal offsets than all the other archives.
 //
+//  When an archive is opened in the Amiga demo, its size is checked against
+//  SIZEOF_SMALL_ARCHIVE to detect when the smaller archive is used.
+//
+//  When an archive is opened in Amiga multi-lingual version, the header is
+//  checked again NDOS to detect when a smaller archive is used.
+//
 #define SIZEOF_SMALL_ARCHIVE      	12778
 
 #define ARCHIVE_FILENAMES_OFS		0x16
@@ -54,7 +61,7 @@
 }
 
 void Archive::open(const char *file) {
-	debugC(3, kDebugDisk, "Archive::open(%s)", file);
+	debugC(1, kDebugDisk, "Archive::open(%s)", file);
 
 	if (_archive.isOpen())
 		close();
@@ -65,8 +72,17 @@
 	if (!_archive.open(path))
 		error("archive '%s' not found", path);
 
-	bool isSmallArchive = _archive.size() == SIZEOF_SMALL_ARCHIVE;
+	_archiveName = file;
 
+	bool isSmallArchive = false;
+	if (_vm->getPlatform() == Common::kPlatformAmiga) {
+		if (_vm->getFeatures() & GF_DEMO) {
+			isSmallArchive = _archive.size() == SIZEOF_SMALL_ARCHIVE;
+		} else if (_vm->getFeatures() & GF_LANG_MULT) {
+			isSmallArchive = (_archive.readUint32BE() != MKID_BE('NDOS'));
+		}
+	}
+
 	_numFiles = (isSmallArchive) ? SMALL_ARCHIVE_FILES_NUM : NORMAL_ARCHIVE_FILES_NUM;
 
 	_archive.seek(ARCHIVE_FILENAMES_OFS);
@@ -91,10 +107,16 @@
 	resetArchivedFile();
 
 	_archive.close();
+	_archiveName.clear();
 }
 
+Common::String Archive::name() const {
+	return _archiveName;
+}
 
 bool Archive::openArchivedFile(const char *filename) {
+	debugC(3, kDebugDisk, "Archive::openArchivedFile(%s)", filename);
+
 	resetArchivedFile();
 
 	debugC(3, kDebugDisk, "Archive::openArchivedFile(%s)", filename);

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/callables.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/callables.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/callables.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -68,17 +68,18 @@
 }
 
 void _c_fade(void *parm) {
-	
+
 	_vm->_gfx->setBlackPalette();
 
 	Gfx::Palette pal;
 	memset(pal, 0, sizeof(Gfx::Palette));
-	
+
 	for (uint16 _di = 0; _di < 64; _di++) {
 		_vm->_gfx->fadePalette(pal);
 		_vm->_gfx->setPalette(pal);
 
-		_vm->waitTime( 1 );
+		g_system->delayMillis(20);
+		_vm->_gfx->updateScreen();
 	}
 
 	return;
@@ -187,14 +188,14 @@
 }
 
 void _c_offMouse(void *parm) {
-	_mouseHidden = 1;
-	_engineFlags |= kEngineMouse;
+	_vm->showCursor(false);
+	_engineFlags |= kEngineBlockInput;
 	return;
 }
 
 void _c_onMouse(void *parm) {
-	_engineFlags &= ~kEngineMouse;
-	_mouseHidden = 0;
+	_engineFlags &= ~kEngineBlockInput;
+	_vm->showCursor(true);
 	return;
 }
 
@@ -253,7 +254,7 @@
 	_vm->_gfx->floodFill(Gfx::kBitFront, r, 1);
 
 	_vm->_gfx->setFont(kFontDialogue);
-	_vm->_gfx->displayWrappedString(_vm->_location._endComment, 3, 5, 130, 0);
+	_vm->_gfx->displayWrappedString(_vm->_location._endComment, 3, 5, 0, 130);
 	_vm->_gfx->updateScreen();
 
 	uint32 di = 0;
@@ -292,6 +293,9 @@
 		}
 
 		_vm->_gfx->setPalette(_enginePal);
+		g_system->delayMillis(20);
+		_vm->_gfx->updateScreen();
+
 	}
 
 	waitUntilLeftClick();
@@ -300,7 +304,7 @@
 }
 
 void _c_frankenstein(void *parm) {
-	
+
 	Gfx::Palette pal0;
 	Gfx::Palette pal1;
 
@@ -308,7 +312,7 @@
 		pal0[(i+FIRST_BASE_COLOR)] = _vm->_gfx->_palette[i];
 		pal0[(i+FIRST_BASE_COLOR)*3+1] = 0;
 		pal0[(i+FIRST_BASE_COLOR)*3+2] = 0;
-		
+
 		pal1[(i+FIRST_BASE_COLOR)*3+1] = 0;
 		pal1[(i+FIRST_BASE_COLOR)*3+2] = 0;
 	}
@@ -316,11 +320,14 @@
 	for (uint16 _di = 0; _di < 30; _di++) {
 		g_system->delayMillis(20);
 		_vm->_gfx->setPalette(pal0, FIRST_BASE_COLOR, BASE_PALETTE_COLORS);
+		_vm->_gfx->updateScreen();
 		g_system->delayMillis(20);
 		_vm->_gfx->setPalette(pal1, FIRST_BASE_COLOR, BASE_PALETTE_COLORS);
+		_vm->_gfx->updateScreen();
 	}
 
 	_vm->_gfx->setPalette(_vm->_gfx->_palette);
+	_vm->_gfx->updateScreen();
 
 	return;
 }
@@ -427,6 +434,8 @@
 
 void _c_testResult(void *parm) {
 	_vm->_gfx->swapBuffers();
+
+	_vm->_disk->selectArchive("disk1");
 	_vm->parseLocation("common");
 
 	_vm->_gfx->setFont(kFontMenu);

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/defs.h
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/defs.h	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/defs.h	2007-07-25 19:01:58 UTC (rev 28198)
@@ -28,6 +28,7 @@
 
 #include "common/stdafx.h"
 #include "common/list.h"
+#include "common/rect.h"
 
 namespace Parallaction {
 

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/detection.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/detection.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/detection.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -58,7 +58,7 @@
 	{
 		{
 			"nippon",
-			"",
+			"Multi-lingual",
 			{
 				{ "disk1",	0, "610363308258e926dbabd5a9e7bb769f", 1060142},
 				{ "disk2",	0, "bfdd7bcfbc226f4acf3f67fa9efa2826", 907205},
@@ -70,19 +70,41 @@
 				{ "it", 	0, "89964aef04d2c53a615ee8983caf2775", 410624},
 				{ NULL, 0, NULL, 0}
 			},
-			Common::EN_ANY,
+			Common::UNK_LANG,
 			Common::kPlatformPC,
 			Common::ADGF_NO_FLAGS
 		},
 		GType_Nippon,
-		0,
+		GF_LANG_EN | GF_LANG_FR | GF_LANG_DE | GF_LANG_IT | GF_LANG_MULT,
 	},
 
+	{
+		{
+			"nippon",
+			"Multi-lingual",
+			{
+				{ "disk0", 	0, "16cca8724fdf4ec8234385497a0c728a", 208437},
+				{ "disk1", 	0, "6b29987cfe2298d3745b6d99a0080c44", 901120},
+				{ "disk2", 	0, "2db40bf8198a57d18e4471a6deaab970", 901120},
+				{ "disk3", 	0, "0486972962b2bfc230e789b9f88f9ec8", 901120},
+				{ "disk4", 	0, "6f625e7f05da4a2f57d6b62d57013614", 901120},
+				{ "en", 	0, "c9ec4f2267d736eef4877c5133e1c6e1", 174074},
+				{ "ge", 	0, "42d6f10a4ebdadb25a6161d53ea4f450", 182298},
+				{ "fr", 	0, "cf17defc24f143d1a9acb52eaa5c2406", 179958},
+				{ NULL, 0, NULL, 0}
+			},
+			Common::UNK_LANG,
+			Common::kPlatformAmiga,
+			Common::ADGF_NO_FLAGS
+		},
+		GType_Nippon,
+		GF_LANG_EN | GF_LANG_FR | GF_LANG_DE | GF_LANG_MULT,
+	},
 
 	{
 		{
 			"nippon",
-			"",
+			"Demo",
 			{
 				{ "disk0",	0, "6fed2e18a6bfe5e8bb49144fcc95fd11", 624640},
 				{ "fr", 	0, "72f04be4320dfac719431419ec2b9a0d", 12778},
@@ -93,10 +115,31 @@
 			Common::ADGF_DEMO
 		},
 		GType_Nippon,
-		GF_DEMO,
+		GF_LANG_EN | GF_DEMO,
 	},
 
 
+	{
+		{
+			"nippon",
+			"",
+			{
+				{"disk0", 	0, "bfee75d8015f1fb97e75dbe08df4bef7", 354304},
+				{"disk1", 	0, "f339dd108c1a1f5cd4853d9966e5d01f", 901120},
+				{"disk2", 	0, "2db40bf8198a57d18e4471a6deaab970", 901120},
+				{"disk3", 	0, "0486972962b2bfc230e789b9f88f9ec8", 901120},
+				{"disk4", 	0, "6f625e7f05da4a2f57d6b62d57013614", 901120},
+				{"it", 		0, "746088eb8de2b2713685d243a4e4678f", 185344},
+				{ NULL, 0, NULL, 0}
+			},
+			Common::IT_ITA,
+			Common::kPlatformAmiga,
+			Common::ADGF_NO_FLAGS
+		},
+		GType_Nippon,
+		GF_LANG_IT,
+	},
+
 	{ AD_TABLE_END_MARKER, 0, 0 }
 };
 
@@ -131,7 +174,9 @@
 namespace Parallaction {
 
 bool Parallaction::detectGame() {
-	_gameDescription = (const PARALLACTIONGameDescription *)Common::AdvancedDetector::detectBestMatchingGame(detectionParams);
+	Common::EncapsulatedADGameDesc encapsulatedDesc = Common::AdvancedDetector::detectBestMatchingGame(detectionParams);
+	_gameDescription = (const PARALLACTIONGameDescription *)(encapsulatedDesc.realDesc);
+
 	return (_gameDescription != 0);
 }
 

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/dialogue.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/dialogue.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/dialogue.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -46,10 +46,6 @@
 #define ANSWER_CHARACTER_X			10
 #define ANSWER_CHARACTER_Y			80
 
-
-void enterDialogue();
-void exitDialogue();
-
 int16 selectAnswer(Question *q, StaticCnv*);
 int16 getHoverAnswer(int16 x, int16 y, Question *q);
 
@@ -62,110 +58,109 @@
 
 Dialogue *Parallaction::parseDialogue(Script &script) {
 //	printf("parseDialogue()\n");
-	uint16 num_questions = 0;
-	uint16 v50[20];
-	Table _questions_names(20);
-	Question *_questions[20];
+	uint16 numQuestions = 0;
 
-	for (uint16 _si = 0; _si < 20; _si++) {
-		v50[_si] = 0;
-	}
+	Dialogue *dialogue = new Dialogue;
 
+	Table forwards(20);
+
 	fillBuffers(script, true);
 
 	while (scumm_stricmp(_tokens[0], "enddialogue")) {
 		if (scumm_stricmp(_tokens[0], "Question")) continue;
 
-		_questions[num_questions] = new Dialogue;
-		Dialogue *vB4 = _questions[num_questions];
+		Question *question = new Question;
+		dialogue->_questions[numQuestions] = question;
 
-		_questions_names.addData(_tokens[1]);
+		forwards.addData(_tokens[1]);
 
-		vB4->_text = parseDialogueString(script);
-//		printf("Question: '%s'\n", vB4->_text);
+		question->_text = parseDialogueString(script);
 
 		fillBuffers(script, true);
-		vB4->_mood = atoi(_tokens[0]);
+		question->_mood = atoi(_tokens[0]);
 
-		uint16 _di = 0;
+		uint16 numAnswers = 0;
 
 		fillBuffers(script, true);
 		while (scumm_stricmp(_tokens[0], "endquestion")) {	// parse answers
 
-			vB4->_answers[_di] = new Answer;
+			Answer *answer = new Answer;
+			question->_answers[numAnswers] = answer;
 
 			if (_tokens[1][0]) {
 
-				Table* v60 = _localFlagNames;
-				uint16 v56 = 1;
+				Table* flagNames;
+				uint16 token;
 
 				if (!scumm_stricmp(_tokens[1], "global")) {
-					v56 = 2;
-					v60 = _globalTable;
-					vB4->_answers[_di]->_yesFlags |= kFlagsGlobal;
+					token = 2;
+					flagNames = _globalTable;
+					answer->_yesFlags |= kFlagsGlobal;
+				} else {
+					token = 1;
+					flagNames = _localFlagNames;
 				}
 
 				do {
 
-					if (!scumm_strnicmp(_tokens[v56], "no", 2)) {
-						byte _al = v60->lookup(_tokens[v56]+2);
-						vB4->_answers[_di]->_noFlags |= 1 << (_al - 1);
+					if (!scumm_strnicmp(_tokens[token], "no", 2)) {
+						byte _al = flagNames->lookup(_tokens[token]+2);
+						answer->_noFlags |= 1 << (_al - 1);
 					} else {
-						byte _al = v60->lookup(_tokens[v56]);
-						vB4->_answers[_di]->_yesFlags |= 1 << (_al - 1);
+						byte _al = flagNames->lookup(_tokens[token]);
+						answer->_yesFlags |= 1 << (_al - 1);
 					}
 
-					v56++;
+					token++;
 
-				} while (!scumm_stricmp(_tokens[v56++], "|"));
+				} while (!scumm_stricmp(_tokens[token++], "|"));
 
 			}
 
-			vB4->_answers[_di]->_text = parseDialogueString(script);
+			answer->_text = parseDialogueString(script);
 
-//			printf("answer[%i]: '%s'\n", _di, vB4->_answers[_di]);
-
 			fillBuffers(script, true);
-			vB4->_answers[_di]->_mood = atoi(_tokens[0]);
-			vB4->_answers[_di]->_following._name = parseDialogueString(script);
+			answer->_mood = atoi(_tokens[0]);
+			answer->_following._name = parseDialogueString(script);
 
 			fillBuffers(script, true);
 			if (!scumm_stricmp(_tokens[0], "commands")) {
-				parseCommands(script, vB4->_answers[_di]->_commands);
+				parseCommands(script, answer->_commands);
 				fillBuffers(script, true);
 			}
 
-			_di++;
+			numAnswers++;
 		}
 
 		fillBuffers(script, true);
-		num_questions++;
+		numQuestions++;
 
 	}
 
-	for (uint16 _si = 0; _si <num_questions; _si++) {
+	// link questions
+	byte v50[20];
+	memset(v50, 0, 20);
 
-		for (uint16 v5A = 0; v5A < 5; v5A++) {
-			if (_questions[_si]->_answers[v5A] == 0) continue;
+	for (uint16 i = 0; i < numQuestions; i++) {
+		Question *question = dialogue->_questions[i];
 
-			int16 v58 = _questions_names.lookup(_questions[_si]->_answers[v5A]->_following._name);
-			free(_questions[_si]->_answers[v5A]->_following._name);
+		for (uint16 j = 0; j < NUM_ANSWERS; j++) {
+			Answer *answer = question->_answers[j];
+			if (answer == 0) continue;
 
-			if (v58 == -1) {
-				_questions[_si]->_answers[v5A]->_following._question = 0;
-			} else {
-				_questions[_si]->_answers[v5A]->_following._question = _questions[v58-1];
+			int16 index = forwards.lookup(answer->_following._name);
+			free(answer->_following._name);
 
-				if (v50[v58]) {
-					_questions[_si]->_answers[v5A]->_mood |= 0x10;
-				}
+			if (index == -1)
+				answer->_following._question = 0;
+			else
+				answer->_following._question = dialogue->_questions[index - 1];
 
-				v50[v58] = 1;
-			}
+
 		}
 	}
 
-	return _questions[0];
+	return dialogue;
 }
 
 
@@ -183,7 +178,7 @@
 	} while (strlen(vD0) == 0);
 
 	vD0[strlen(vD0)-1] = '\0';	// deletes the trailing '0xA'
-								// this is critical for Gfx::displayBalloonString to work properly
+								// this is critical for Gfx::displayWrappedString to work properly
 
 	char *vCC = (char*)malloc(strlen(vD0)+1);
 	strcpy(vCC, vD0);
@@ -191,26 +186,74 @@
 	return vCC;
 }
 
-uint16 Parallaction::askDialoguePassword(Dialogue *q, StaticCnv *face) {
+class DialogueManager {
+
+	Parallaction	*_vm;
+	SpeakData		*_data;
+	Dialogue		*_dialogue;
+
+	bool 			_askPassword;
+
+	bool 			isNpc;
+	Cnv				*_questioner;
+	Cnv				*_answerer;
+
+	Question		*_q;
+
+public:
+	DialogueManager(Parallaction *vm, SpeakData *data) : _vm(vm), _data(data) {
+		_dialogue = _data->_dialogue;
+		isNpc = scumm_stricmp(_data->_name, "yourself") && _data->_name[0] != '\0';
+		_questioner = isNpc ? _vm->_disk->loadTalk(_data->_name) : _vm->_char._talk;
+		_answerer = _vm->_char._talk;
+	}
+
+	~DialogueManager() {
+		if (isNpc) {
+			delete _questioner;
+		}
+	}
+
+	void run();
+
+protected:
+	void clear() {
+		_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+	}
+
+	void displayQuestion();
+	bool displayAnswers();
+	bool displayAnswer(uint16 i);
+
+	uint16 getAnswer();
+	int16 selectAnswer();
+	uint16 askPassword();
+	int16 getHoverAnswer(int16 x, int16 y);
+
+};
+
+uint16 DialogueManager::askPassword() {
 	debugC(1, kDebugDialogue, "checkDialoguePassword()");
 
 	char password[100];
 	uint16 passwordLen = 0;
 
 	while (true) {
+		clear();
+
 		strcpy(password, ".......");
-		_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
 
 		Common::Rect r(_answerBalloonW[0], _answerBalloonH[0]);
 		r.moveTo(_answerBalloonX[0], _answerBalloonY[0]);
 
-		_gfx->drawBalloon(r, 1);
-		_gfx->displayWrappedString(q->_answers[0]->_text, _answerBalloonX[0], _answerBalloonY[0], MAX_BALLOON_WIDTH, 3);
-		_gfx->flatBlitCnv(face, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y,	Gfx::kBitFront);
-		_gfx->displayBalloonString(_answerBalloonX[0] + 5,	_answerBalloonY[0] + _answerBalloonH[0] - 15, "> ", 0);
+		_vm->_gfx->drawBalloon(r, 1);
+		_vm->_gfx->displayWrappedString(_q->_answers[0]->_text, _answerBalloonX[0], _answerBalloonY[0], 3, MAX_BALLOON_WIDTH);
+		_vm->_gfx->flatBlitCnv(_answerer, 0, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y,	Gfx::kBitFront);
+		_vm->_gfx->displayString(_answerBalloonX[0] + 5, _answerBalloonY[0] + _answerBalloonH[0] - 15, "> ", 0);
+		_vm->_gfx->updateScreen();
 
 		Common::Event e;
-		while (e.kbd.ascii != 0xD && passwordLen < MAX_PASSWORD_LENGTH) {
+		while (e.kbd.ascii != Common::KEYCODE_RETURN && passwordLen < MAX_PASSWORD_LENGTH) {
 
 			// FIXME: see comment for updateInput()
 			if (!g_system->getEventManager()->pollEvent(e)) continue;
@@ -223,15 +266,15 @@
 			passwordLen++;
 			password[passwordLen] = '\0';
 
-			_gfx->displayBalloonString(_answerBalloonX[0] + 5, _answerBalloonY[0] + _answerBalloonH[0] - 15, password, 0);
-			_gfx->updateScreen();
+			_vm->_gfx->displayString(_answerBalloonX[0] + 10, _answerBalloonY[0] + _answerBalloonH[0] - 15, password, 0);
+			_vm->_gfx->updateScreen();
 
 			g_system->delayMillis(20);
 		}
 
-		if ((!scumm_stricmp(_characterName, _doughName) && !scumm_strnicmp(password, "1732461", 7)) ||
-			(!scumm_stricmp(_characterName, _donnaName) && !scumm_strnicmp(password, "1622", 4)) ||
-			(!scumm_stricmp(_characterName, _dinoName) && !scumm_strnicmp(password, "179", 3))) {
+		if ((!scumm_stricmp(_vm->_characterName, _doughName) && !scumm_strnicmp(password, "1732461", 7)) ||
+			(!scumm_stricmp(_vm->_characterName, _donnaName) && !scumm_strnicmp(password, "1622", 4)) ||
+			(!scumm_stricmp(_vm->_characterName, _dinoName) && !scumm_strnicmp(password, "179", 3))) {
 
 			break;
 
@@ -243,165 +286,135 @@
 
 }
 
-bool _askPassword;
 
-bool Parallaction::displayAnswer(Dialogue *q, uint16 i) {
 
-	uint32 v28 = _localFlags[_currentLocationIndex];
-	if (q->_answers[i]->_yesFlags & kFlagsGlobal)
+bool DialogueManager::displayAnswer(uint16 i) {
+
+	uint32 v28 = _localFlags[_vm->_currentLocationIndex];
+	if (_q->_answers[i]->_yesFlags & kFlagsGlobal)
 		v28 = _commandFlags | kFlagsGlobal;
 
 	// display suitable answers
-	if (((q->_answers[i]->_yesFlags & v28) == q->_answers[i]->_yesFlags) && ((q->_answers[i]->_noFlags & ~v28) == q->_answers[i]->_noFlags)) {
+	if (((_q->_answers[i]->_yesFlags & v28) == _q->_answers[i]->_yesFlags) && ((_q->_answers[i]->_noFlags & ~v28) == _q->_answers[i]->_noFlags)) {
 
-		_gfx->getStringExtent(q->_answers[i]->_text, MAX_BALLOON_WIDTH, &_answerBalloonW[i], &_answerBalloonH[i]);
+		_vm->_gfx->getStringExtent(_q->_answers[i]->_text, MAX_BALLOON_WIDTH, &_answerBalloonW[i], &_answerBalloonH[i]);
 
 		Common::Rect r(_answerBalloonW[i], _answerBalloonH[i]);
 		r.moveTo(_answerBalloonX[i], _answerBalloonY[i]);
 
-		_gfx->drawBalloon(r, 1);
+		_vm->_gfx->drawBalloon(r, 1);
 
 		_answerBalloonY[i+1] = 10 + _answerBalloonY[i] + _answerBalloonH[i];
-		_askPassword = _gfx->displayWrappedString(q->_answers[i]->_text, _answerBalloonX[i], _answerBalloonY[i], MAX_BALLOON_WIDTH, 3);
+		_askPassword = _vm->_gfx->displayWrappedString(_q->_answers[i]->_text, _answerBalloonX[i], _answerBalloonY[i], 3, MAX_BALLOON_WIDTH);
 
 		return true;
 	}
 
+	_answerBalloonY[i+1] = _answerBalloonY[i];
+	_answerBalloonY[i] = SKIPPED_ANSWER;
+
 	return false;
 
 }
 
-bool Parallaction::displayAnswers(Dialogue *q) {
+bool DialogueManager::displayAnswers() {
 
 	bool displayed = false;
 
 	uint16 i = 0;
 
-	while (i < NUM_ANSWERS && q->_answers[i]) {
-		if (displayAnswer(q, i)) {
+	while (i < NUM_ANSWERS && _q->_answers[i]) {
+		if (displayAnswer(i))
 			displayed = true;
-		} else {
-			_answerBalloonY[i+1] = _answerBalloonY[i];
-			_answerBalloonY[i] = SKIPPED_ANSWER;
-		}
+
 		i++;
 	}
-	_gfx->updateScreen();
+	_vm->_gfx->updateScreen();
 
 	return displayed;
 }
 
-void Parallaction::displayQuestion(Dialogue *q, Cnv *cnv) {
+void DialogueManager::displayQuestion() {
 
 	int16 w = 0, h = 0;
 
-	if (!scumm_stricmp(q->_text, "NULL")) return;
+	if (!scumm_stricmp(_q->_text, "NULL")) return;
 
-	StaticCnv face;
-	face._width = cnv->_width;
-	face._height = cnv->_height;
-	face._data0 = cnv->getFramePtr(q->_mood & 0xF);
-	face._data1 = NULL; // cnv->field_8[v60->_mood & 0xF];
+	_vm->_gfx->flatBlitCnv(_questioner, _q->_mood & 0xF, QUESTION_CHARACTER_X, QUESTION_CHARACTER_Y, Gfx::kBitFront);
+	_vm->_gfx->getStringExtent(_q->_text, MAX_BALLOON_WIDTH, &w, &h);
 
-	_gfx->flatBlitCnv(&face, QUESTION_CHARACTER_X, QUESTION_CHARACTER_Y, Gfx::kBitFront);
-	_gfx->getStringExtent(q->_text, MAX_BALLOON_WIDTH, &w, &h);
-
 	Common::Rect r(w, h);
 	r.moveTo(QUESTION_BALLOON_X, QUESTION_BALLOON_Y);
 
-	_gfx->drawBalloon(r, q->_mood & 0x10);
-	_gfx->displayWrappedString(q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, MAX_BALLOON_WIDTH, 0);
-	_gfx->updateScreen();
+	_vm->_gfx->drawBalloon(r, _q->_mood & 0x10);
+	_vm->_gfx->displayWrappedString(_q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, 0, MAX_BALLOON_WIDTH);
+	_vm->_gfx->updateScreen();
 
 	waitUntilLeftClick();
 
-	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+	clear();
 
 	return;
 }
 
-uint16 Parallaction::getDialogueAnswer(Dialogue *q, Cnv *cnv) {
+uint16 DialogueManager::getAnswer() {
 
 	uint16 answer = 0;
 
-	StaticCnv face;
-	face._width = cnv->_width;
-	face._height = cnv->_height;
-	face._data0 = cnv->getFramePtr(0);
-	face._data1 = NULL; // cnv->field_8[0];
-
-	_gfx->flatBlitCnv(&face, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y, Gfx::kBitFront);
-
 	if (_askPassword == false) {
-		answer = selectAnswer(q, &face);
+		answer = selectAnswer();
 	} else {
-		answer = askDialoguePassword(q, &face);
+		answer = askPassword();
 	}
 
-	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);	// erase answer screen
+	clear();
 
 	debugC(1, kDebugDialogue, "runDialogue: user selected answer #%i", answer);
 
 	return answer;
 }
 
-void Parallaction::runDialogue(SpeakData *data) {
-	debugC(1, kDebugDialogue, "runDialogue: starting dialogue '%s'", data->_name);
+void DialogueManager::run() {
 
-	enterDialogue();
-
-	_gfx->setFont(kFontDialogue);
-
-	bool isNpc = scumm_stricmp(data->_name, "yourself") && data->_name[0] != '\0';
-	Cnv *face = isNpc ? _disk->loadTalk(data->_name) : _char._talk;
-
 	_askPassword = false;
 	CommandList *cmdlist = NULL;
 
-	uint16 answer;
-	Dialogue *q = data->_dialogue;
-	while (q) {
+	_q = _dialogue->_questions[0];
+	int16 answer;
 
+	while (_q) {
+
 		answer = 0;
 
-		displayQuestion(q, face);
-		if (q->_answers[0] == NULL) break;
+		displayQuestion();
+		if (_q->_answers[0] == NULL) break;
 
 		_answerBalloonY[0] = 10;
 
-		if (scumm_stricmp(q->_answers[0]->_text, "NULL")) {
-			if (!displayAnswers(q)) break;
-			answer = getDialogueAnswer(q, _char._talk);
-			cmdlist = &q->_answers[answer]->_commands;
+		if (scumm_stricmp(_q->_answers[0]->_text, "NULL")) {
+			if (!displayAnswers()) break;
+			answer = getAnswer();
+			cmdlist = &_q->_answers[answer]->_commands;
 		}
 
-		q = q->_answers[answer]->_following._question;
+		_q = _q->_answers[answer]->_following._question;
 	}
 
-	debugC(1, kDebugDialogue, "runDialogue: out of dialogue loop");
+	clear();
 
-	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
-
-	if (isNpc) {
-		delete face;
-	}
-
-	exitDialogue();
 	if (cmdlist)
-		runCommands(*cmdlist);
+		_vm->runCommands(*cmdlist);
 
-	return;
-
 }
 
-int16 Parallaction::selectAnswer(Question *q, StaticCnv *cnv) {
+int16 DialogueManager::selectAnswer() {
 
 	int16 numAvailableAnswers = 0;
 	int16 _si = 0;
 	int16 _di = 0;
 
 	int16 i = 0;
-	for (; q->_answers[i]; i++) {
+	for (; _q->_answers[i]; i++) {
 		if (_answerBalloonY[i] == SKIPPED_ANSWER) continue;
 
 		_di = i;
@@ -410,11 +423,9 @@
 	_answerBalloonY[i] = 2000;
 
 	if (numAvailableAnswers == 1) {
-		_gfx->displayWrappedString(q->_answers[_di]->_text, _answerBalloonX[_di], _answerBalloonY[_di], MAX_BALLOON_WIDTH, 0);
-		cnv->_data0 = _char._talk->getFramePtr(q->_answers[_di]->_mood & 0xF);
-//		cnv->_data1 = _char._talk->field_8[q->_answers[_di]->_mood & 0xF];
-		_gfx->flatBlitCnv(cnv, ANSWER_CHARACTER_X,	ANSWER_CHARACTER_Y, Gfx::kBitFront);
-		_gfx->updateScreen();
+		_vm->_gfx->displayWrappedString(_q->_answers[_di]->_text, _answerBalloonX[_di], _answerBalloonY[_di], 0, MAX_BALLOON_WIDTH);
+		_vm->_gfx->flatBlitCnv(_answerer, _q->_answers[_di]->_mood & 0xF, ANSWER_CHARACTER_X,	ANSWER_CHARACTER_Y, Gfx::kBitFront);
+		_vm->_gfx->updateScreen();
 		waitUntilLeftClick();
 		return _di;
 	}
@@ -424,20 +435,18 @@
 	_mouseButtons = kMouseNone;
 	while (_mouseButtons != kMouseLeftUp) {
 
-		updateInput();
-		_si = getHoverAnswer(_mousePos.x, _mousePos.y, q);
+		_vm->updateInput();
+		_si = getHoverAnswer(_vm->_mousePos.x, _vm->_mousePos.y);
 
 		if (_si != v2) {
 			if (v2 != -1)
-				_gfx->displayWrappedString(q->_answers[v2]->_text, _answerBalloonX[v2], _answerBalloonY[v2], MAX_BALLOON_WIDTH, 3);
+				_vm->_gfx->displayWrappedString(_q->_answers[v2]->_text, _answerBalloonX[v2], _answerBalloonY[v2], 3, MAX_BALLOON_WIDTH);
 
-			_gfx->displayWrappedString(q->_answers[_si]->_text, _answerBalloonX[_si],	_answerBalloonY[_si], MAX_BALLOON_WIDTH, 0);
-			cnv->_data0 = _char._talk->getFramePtr(q->_answers[_si]->_mood & 0xF);
-//			cnv->_data1 = _char._talk->field_8[q->_answers[_si]->_mood & 0xF];
-			_gfx->flatBlitCnv(cnv, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y, Gfx::kBitFront);
+			_vm->_gfx->displayWrappedString(_q->_answers[_si]->_text, _answerBalloonX[_si],	_answerBalloonY[_si], 0, MAX_BALLOON_WIDTH);
+			_vm->_gfx->flatBlitCnv(_answerer, _q->_answers[_si]->_mood & 0xF, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y, Gfx::kBitFront);
 		}
 
-		_gfx->updateScreen();
+		_vm->_gfx->updateScreen();
 		g_system->delayMillis(30);
 		v2 = _si;
 	}
@@ -449,13 +458,13 @@
 //
 //	finds out which answer is currently selected
 //
-int16 getHoverAnswer(int16 x, int16 y, Question *q) {
+int16 DialogueManager::getHoverAnswer(int16 x, int16 y) {
 
 	int16 top = 1000;
 	int16 bottom = 1000;
 
 	for (int16 _si = 0; _si < NUM_ANSWERS; _si++) {
-		if (q->_answers[_si] == NULL) break;
+		if (_q->_answers[_si] == NULL) break;
 
 		if (_answerBalloonY[_si] != SKIPPED_ANSWER) {
 			top = _answerBalloonY[_si];
@@ -476,17 +485,20 @@
 }
 
 
-void Parallaction::enterDialogue() {
 
-	return;
-}
+void Parallaction::runDialogue(SpeakData *data) {
+	debugC(1, kDebugDialogue, "runDialogue: starting dialogue '%s'", data->_name);
 
-//	rebuilds inventory
-//
-void Parallaction::exitDialogue() {
+	_gfx->setFont(kFontDialogue);
 
-	refreshInventory(_characterName);
+	if (_vm->getPlatform() == Common::kPlatformPC)
+		showCursor(false);
 
+	DialogueManager man(this, data);
+	man.run();
+
+	showCursor(true);
+
 	return;
 }
 
@@ -499,12 +511,8 @@
 }
 
 Answer::~Answer() {
-	if (_mood & 0x10)
-		delete _following._question;
-
 	if (_text)
 		free(_text);
-
 }
 
 Question::Question() {

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/disk.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/disk.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/disk.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -26,6 +26,8 @@
 #include "common/stdafx.h"
 
 #include "graphics/iff.h"
+#include "graphics/surface.h"
+
 #include "parallaction/parallaction.h"
 
 
@@ -90,11 +92,14 @@
 }
 
 
-void Disk::selectArchive(const char *name) {
-	_resArchive.open(name);
+Common::String Disk::selectArchive(const Common::String& name) {
+	Common::String oldName = _resArchive.name();
+	_resArchive.open(name.c_str());
+	return oldName;
 }
 
 void Disk::setLanguage(uint16 language) {
+	debugC(1, kDebugDisk, "setLanguage(%i)", language);
 
 	switch (language) {
 	case 0:
@@ -690,35 +695,108 @@
 
 #define NUM_PLANES		5
 
-// FIXME: no mask is loaded
-void AmigaDisk::unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 planeSize) {
+/*
+	unpackFrame transforms images from 5-bitplanes format to
+	8-bit color-index mode
+*/
+void AmigaDisk::unpackFrame(byte *dst, byte *src, uint16 planeSize) {
 
 	byte s0, s1, s2, s3, s4, mask, t0, t1, t2, t3, t4;
 
-	for (uint32 i = 0; i < numFrames; i++) {
-		for (uint32 j = 0; j < planeSize; j++) {
-			s0 = src[j];
-			s1 = src[j+planeSize];
-			s2 = src[j+planeSize*2];
-			s3 = src[j+planeSize*3];
-			s4 = src[j+planeSize*4];
+	for (uint32 j = 0; j < planeSize; j++) {
+		s0 = src[j];
+		s1 = src[j+planeSize];
+		s2 = src[j+planeSize*2];
+		s3 = src[j+planeSize*3];
+		s4 = src[j+planeSize*4];
 
-			for (uint32 k = 0; k < 8; k++) {
-				mask = 1 << (7 - k);
-				t0 = (s0 & mask ? 1 << 0 : 0);
-				t1 = (s1 & mask ? 1 << 1 : 0);
-				t2 = (s2 & mask ? 1 << 2 : 0);
-				t3 = (s3 & mask ? 1 << 3 : 0);
-				t4 = (s4 & mask ? 1 << 4 : 0);
-				*dst++ = t0 | t1 | t2 | t3 | t4;
+		for (uint32 k = 0; k < 8; k++) {
+			mask = 1 << (7 - k);
+			t0 = (s0 & mask ? 1 << 0 : 0);
+			t1 = (s1 & mask ? 1 << 1 : 0);
+			t2 = (s2 & mask ? 1 << 2 : 0);
+			t3 = (s3 & mask ? 1 << 3 : 0);
+			t4 = (s4 & mask ? 1 << 4 : 0);
+			*dst++ = t0 | t1 | t2 | t3 | t4;
+		}
+
+	}
+
+}
+
+/*
+	patchFrame applies DLTA data (dlta) to specified buffer (dst)
+*/
+void AmigaDisk::patchFrame(byte *dst, byte *dlta, uint16 bytesPerPlane, uint16 height) {
+
+	uint32 *dataIndex = (uint32*)dlta;
+	uint32 *ofslenIndex = (uint32*)dlta + 8;
+
+	uint16 *base = (uint16*)dlta;
+	uint16 wordsPerLine = bytesPerPlane >> 1;
+
+	for (uint j = 0; j < NUM_PLANES; j++) {
+		uint16 *dst16 = (uint16*)(dst + j * bytesPerPlane * height);
+
+		uint16 *data = base + READ_BE_UINT32(dataIndex);
+		dataIndex++;
+		uint16 *ofslen = base + READ_BE_UINT32(ofslenIndex);
+		ofslenIndex++;
+
+		while (*ofslen != 0xFFFF) {
+
+			uint16 ofs = READ_BE_UINT16(ofslen);
+			ofslen++;
+			uint16 size = READ_BE_UINT16(ofslen);
+			ofslen++;
+
+			while (size > 0) {
+				dst16[ofs] ^= *data++;
+				ofs += wordsPerLine;
+				size--;
 			}
 
 		}
 
-		src += planeSize * NUM_PLANES;
 	}
+
 }
 
+// FIXME: no mask is loaded
+void AmigaDisk::unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 bytesPerPlane, uint16 height) {
+
+	byte *baseFrame = src;
+	byte *tempBuffer = 0;
+
+	uint16 planeSize = bytesPerPlane * height;
+
+	for (uint32 i = 0; i < numFrames; i++) {
+		if (READ_BE_UINT32(src) == MKID_BE('DLTA')) {
+
+			uint size = READ_BE_UINT32(src + 4);
+
+			if (tempBuffer == 0)
+				tempBuffer = (byte*)malloc(planeSize * NUM_PLANES);
+
+			memcpy(tempBuffer, baseFrame, planeSize * NUM_PLANES);
+
+			patchFrame(tempBuffer, src + 8, bytesPerPlane, height);
+			unpackFrame(dst, tempBuffer, planeSize);
+
+			src += (size + 8);
+			dst += planeSize * 8;
+		} else {
+			unpackFrame(dst, src, planeSize);
+			src += planeSize * NUM_PLANES;
+			dst += planeSize * 8;
+		}
+	}
+
+	if (tempBuffer)
+		free(tempBuffer);
+
+}
+
 StaticCnv* AmigaDisk::makeStaticCnv(Common::SeekableReadStream &stream) {
 
 	stream.skip(1);
@@ -736,7 +814,7 @@
 	uint32 decsize = width * height;
 	byte *data = (byte*)calloc(decsize, 1);
 
-	unpackBitmap(data, buf, 1, height * bytesPerPlane);
+	unpackBitmap(data, buf, 1, bytesPerPlane, height);
 
 	free(buf);
 
@@ -766,7 +844,7 @@
 	uint32 decsize = numFrames * width * height;
 	byte *data = (byte*)calloc(decsize, 1);
 
-	unpackBitmap(data, buf, numFrames, height * bytesPerPlane);
+	unpackBitmap(data, buf, numFrames, bytesPerPlane, height);
 
 	free(buf);
 
@@ -775,10 +853,14 @@
 #undef NUM_PLANES
 
 Script* AmigaDisk::loadLocation(const char *name) {
-	debugC(1, kDebugDisk, "AmigaDisk::loadLocation '%s'", name);
+	debugC(1, kDebugDisk, "AmigaDisk()::loadLocation '%s'", name);
 
 	char path[PATH_LEN];
-	sprintf(path, "%s%s%s.loc.pp", _vm->_characterName, _languageDir, name);
+	if (IS_MINI_CHARACTER(_vm->_characterName)) {
+		sprintf(path, "%s%s%s.loc.pp", _vm->_characterName+4, _languageDir, name);
+	} else
+		sprintf(path, "%s%s%s.loc.pp", _vm->_characterName, _languageDir, name);
+
 	if (!_locArchive.openArchivedFile(path)) {
 		sprintf(path, "%s%s.loc.pp", _languageDir, name);
 		if (!_locArchive.openArchivedFile(path)) {
@@ -786,6 +868,8 @@
 		}
 	}
 
+	debugC(3, kDebugDisk, "location file found: %s", path);
+
 	return new Script(new PowerPackerStream(_locArchive), true);
 }
 
@@ -802,38 +886,6 @@
 	return new Script(new DummyArchiveStream(_resArchive), true);
 }
 
-Cnv* AmigaDisk::loadTalk(const char *name) {
-	debugC(1, kDebugDisk, "AmigaDisk::loadTalk '%s'", name);
-
-	Common::SeekableReadStream *s;
-
-	char path[PATH_LEN];
-	sprintf(path, "%s.talk", name);
-	s = openArchivedFile(path, false);
-	if (s == NULL) {
-		s = openArchivedFile(name, true);
-	}
-
-	Cnv *cnv = makeCnv(*s);
-	delete s;
-
-	return cnv;
-}
-
-Cnv* AmigaDisk::loadObjects(const char *name) {
-	debugC(1, kDebugDisk, "AmigaDisk::loadObjects");
-
-	char path[PATH_LEN];
-	sprintf(path, "%s.objs", name);
-	Common::SeekableReadStream *s = openArchivedFile(path, true);
-
-	Cnv *cnv = makeCnv(*s);
-	delete s;
-
-	return cnv;
-}
-
-
 StaticCnv* AmigaDisk::loadPointer() {
 	debugC(1, kDebugDisk, "AmigaDisk::loadPointer");
 
@@ -844,32 +896,6 @@
 	return makeStaticCnv(stream);
 }
 
-StaticCnv* AmigaDisk::loadHead(const char* name) {
-	debugC(1, kDebugDisk, "AmigaDisk::loadHead '%s'", name);
-
-	char path[PATH_LEN];
-	sprintf(path, "%s.head", name);
-
-	Common::SeekableReadStream *s = openArchivedFile(path, true);
-	StaticCnv *cnv = makeStaticCnv(*s);
-
-	delete s;
-
-	return cnv;
-}
-
-Font* AmigaDisk::loadFont(const char* name) {
-	debugC(1, kDebugDisk, "AmigaDisk::loadFont '%s'", name);
-
-	char path[PATH_LEN];
-	sprintf(path, "%sfont", name);
-
-	if (!_resArchive.openArchivedFile(path))
-		errorFileNotFound(path);
-
-	return createFont(name, _resArchive);
-}
-
 StaticCnv* AmigaDisk::loadStatic(const char* name) {
 	debugC(1, kDebugDisk, "AmigaDisk::loadStatic '%s'", name);
 
@@ -882,6 +908,7 @@
 }
 
 Common::SeekableReadStream *AmigaDisk::openArchivedFile(const char* name, bool errorOnFileNotFound) {
+	debugC(3, kDebugDisk, "AmigaDisk::openArchivedFile(%s)", name);
 
 	if (_resArchive.openArchivedFile(name)) {
 		return new DummyArchiveStream(_resArchive);
@@ -905,22 +932,6 @@
 	return NULL;
 }
 
-Cnv* AmigaDisk::loadFrames(const char* name) {
-	debugC(1, kDebugDisk, "AmigaDisk::loadFrames '%s'", name);
-
-	Common::SeekableReadStream *s = openArchivedFile(name, true);
-	Cnv *cnv = makeCnv(*s);
-	delete s;
-
-	return cnv;
-}
-
-void AmigaDisk::loadSlide(const char *name) {
-	debugC(1, kDebugDisk, "AmigaDisk::loadSlide '%s'", name);
-	loadBackground(name);
-	return;
-}
-
 // FIXME: mask values are not computed correctly for level 1 and 2
 void buildMask(byte* buf) {
 
@@ -1019,7 +1030,10 @@
 	char path[PATH_LEN];
 	sprintf(path, "%s.mask", name);
 
-	Common::SeekableReadStream *s = openArchivedFile(path, true);
+	Common::SeekableReadStream *s = openArchivedFile(path, false);
+	if (s == NULL)
+		return;	// no errors if missing mask files: not every location has one
+
 	s->seek(0x30, SEEK_SET);
 
 	byte r, g, b;
@@ -1082,6 +1096,93 @@
 	return;
 }
 
+void AmigaDisk::loadSlide(const char *name) {
+	debugC(1, kDebugDisk, "AmigaDisk::loadSlide '%s'", name);
+
+	char path[PATH_LEN];
+	sprintf(path, "slides/%s", name);
+	Common::SeekableReadStream *s = openArchivedFile(path, false);
+	if (s)
+		loadBackground(path);
+	else
+		loadBackground(name);
+
+	return;
+}
+
+Cnv* AmigaDisk::loadFrames(const char* name) {
+	debugC(1, kDebugDisk, "AmigaDisk::loadFrames '%s'", name);
+
+	Common::SeekableReadStream *s;
+
+	char path[PATH_LEN];
+	sprintf(path, "anims/%s", name);
+
+	s = openArchivedFile(path, false);
+	if (!s)
+		s = openArchivedFile(name, true);
+
+	Cnv *cnv = makeCnv(*s);
+	delete s;
+
+	return cnv;
+}
+
+StaticCnv* AmigaDisk::loadHead(const char* name) {
+	debugC(1, kDebugDisk, "AmigaDisk::loadHead '%s'", name);
+
+	char path[PATH_LEN];
+	sprintf(path, "%s.head", name);
+
+	Common::SeekableReadStream *s = openArchivedFile(path, true);
+	StaticCnv *cnv = makeStaticCnv(*s);
+
+	delete s;
+
+	return cnv;
+}
+
+
+Cnv* AmigaDisk::loadObjects(const char *name) {
+	debugC(1, kDebugDisk, "AmigaDisk::loadObjects");
+
+	char path[PATH_LEN];
+	if (_vm->getFeatures() & GF_DEMO)
+		sprintf(path, "%s.objs", name);
+	else
+		sprintf(path, "objs/%s.objs", name);
+
+	Common::SeekableReadStream *s = openArchivedFile(path, true);
+
+	Cnv *cnv = makeCnv(*s);
+	delete s;
+
+	return cnv;
+}
+
+
+Cnv* AmigaDisk::loadTalk(const char *name) {
+	debugC(1, kDebugDisk, "AmigaDisk::loadTalk '%s'", name);
+
+	Common::SeekableReadStream *s;
+
+	char path[PATH_LEN];
+	if (_vm->getFeatures() & GF_DEMO)
+		sprintf(path, "%s.talk", name);
+	else
+		sprintf(path, "talk/%s.talk", name);
+
+	s = openArchivedFile(path, false);
+	if (s == NULL) {
+		s = openArchivedFile(name, true);
+	}
+
+	Cnv *cnv = makeCnv(*s);
+	delete s;
+
+	return cnv;
+}
+
 Table* AmigaDisk::loadTable(const char* name) {
 	debugC(1, kDebugDisk, "AmigaDisk::loadTable '%s'", name);
 
@@ -1100,6 +1201,8 @@
 		dispose = true;
 		stream = s;
 	} else {
+		if (!(_vm->getFeatures() & GF_DEMO))
+			sprintf(path, "objs/%s.table", name);
 		if (!_resArchive.openArchivedFile(path))
 			errorFileNotFound(path);
 
@@ -1120,6 +1223,28 @@
 	return t;
 }
 
+Font* AmigaDisk::loadFont(const char* name) {
+	debugC(1, kDebugDisk, "AmigaFullDisk::loadFont '%s'", name);
+
+	char path[PATH_LEN];
+	sprintf(path, "%sfont", name);
+
+	if (_vm->getFeatures() & GF_LANG_IT) {
+		// Italian version has separate font files
+		Common::File stream;
+		if (!stream.open(path))
+			errorFileNotFound(path);
+
+		return createFont(name, stream);
+	} else {
+		if (!_resArchive.openArchivedFile(path))
+			errorFileNotFound(path);
+
+		return createFont(name, _resArchive);
+	}
+}
+
+
 Common::ReadStream* AmigaDisk::loadMusic(const char* name) {
 	return openArchivedFile(name);
 }
@@ -1133,5 +1258,4 @@
 	return new DummyArchiveStream(_resArchive);
 }
 
-
 } // namespace Parallaction

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/disk.h
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/disk.h	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/disk.h	2007-07-25 19:01:58 UTC (rev 28198)
@@ -60,6 +60,7 @@
 	uint32			_fileCursor;
 	uint32			_fileEndOffset;
 
+	Common::String	_archiveName;
 	char 			_archiveDir[MAX_ARCHIVE_ENTRIES][32];
 	uint32			_archiveLenghts[MAX_ARCHIVE_ENTRIES];
 	uint32			_archiveOffsets[MAX_ARCHIVE_ENTRIES];
@@ -74,9 +75,11 @@
 public:
 	Archive();
 
-	void open(const char *file);
+	void open(const char* file);
 	void close();
 
+	Common::String name() const;
+
 	bool openArchivedFile(const char *name);
 	void closeArchivedFile();
 
@@ -103,7 +106,7 @@
 	Disk(Parallaction *vm);
 	virtual ~Disk();
 
-	void selectArchive(const char *name);
+	Common::String selectArchive(const Common::String &name);
 	void setLanguage(uint16 language);
 
 	virtual Script* loadLocation(const char *name) = 0;
@@ -163,7 +166,9 @@
 protected:
 	Cnv* makeCnv(Common::SeekableReadStream &stream);
 	StaticCnv* makeStaticCnv(Common::SeekableReadStream &stream);
-	void unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 planeSize);
+	void patchFrame(byte *dst, byte *dlta, uint16 bytesPerPlane, uint16 height);
+	void unpackFrame(byte *dst, byte *src, uint16 planeSize);
+	void unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 bytesPerPlane, uint16 height);
 	Common::SeekableReadStream *openArchivedFile(const char* name, bool errorOnFileNotFound = false);
 	Font *createFont(const char *name, Common::SeekableReadStream &stream);
 	void loadMask(const char *name);

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/graphics.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/graphics.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/graphics.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -30,9 +30,6 @@
 #include "parallaction/parallaction.h"
 
 
-
-extern OSystem *g_system;
-
 namespace Parallaction {
 
 byte *		Gfx::_buffers[];
@@ -142,7 +139,7 @@
 	if (_vm->getPlatform() == Common::kPlatformAmiga)
 		g_system->setPalette(sysExtraPal, first+FIRST_EHB_COLOR, num);
 
-	g_system->updateScreen();
+//	g_system->updateScreen();
 
 	return;
 }
@@ -288,7 +285,7 @@
 void Gfx::copyScreen(Gfx::Buffers srcbuffer, Gfx::Buffers dstbuffer) {
 	memcpy(_buffers[dstbuffer], _buffers[srcbuffer], SCREEN_WIDTH*SCREEN_HEIGHT);
 
-	if (dstbuffer == kBitFront) updateScreen();
+//	if (dstbuffer == kBitFront) updateScreen();
 
 	return;
 }
@@ -306,8 +303,6 @@
 		d += SCREEN_WIDTH;
 	}
 
-	if (buffer == kBitFront) updateScreen();
-
 	return;
 }
 
@@ -350,8 +345,6 @@
 		d += (SCREEN_WIDTH - q.width());
 	}
 
-	if (buffer == kBitFront) updateScreen();
-
 	return;
 
 }
@@ -389,8 +382,6 @@
 		d += (SCREEN_WIDTH - q.right + q.left);
 	}
 
-	if (buffer == kBitFront) updateScreen();
-
 	return;
 
 }
@@ -444,8 +435,8 @@
 
 	_mouseComposedArrow = _vm->_disk->loadPointer();
 
-	byte temp[16*16];
-	memcpy(temp, _mouseArrow, 16*16);
+	byte temp[MOUSEARROW_WIDTH*MOUSEARROW_HEIGHT];
+	memcpy(temp, _mouseArrow, MOUSEARROW_WIDTH*MOUSEARROW_HEIGHT);
 
 	uint16 k = 0;
 	for (uint16 i = 0; i < 4; i++) {
@@ -455,20 +446,30 @@
 	return;
 }
 
+
 void Gfx::setMousePointer(int16 index) {
 
 	if (index == kCursorArrow) {		// standard mouse pointer
 
-		g_system->setMouseCursor(_mouseArrow, 16, 16, 0, 0, 0);
+		g_system->setMouseCursor(_mouseArrow, MOUSEARROW_WIDTH, MOUSEARROW_HEIGHT, 0, 0, 0);
 		g_system->showMouse(true);
 
 	} else {
 		// inventory item pointer
 		byte *v8 = _mouseComposedArrow->_data0;
 
-		// FIXME: target offseting is not clear
-		extractInventoryGraphics(index, v8 + 7 + 32 * 7);
-		g_system->setMouseCursor(v8, 32, 32, 0, 0, 0);
+		// FIXME: destination offseting is not clear
+		byte* s = _vm->_char._objs->getFramePtr(getInventoryItemIndex(index));
+		byte* d = v8 + 7 + MOUSECOMBO_WIDTH * 7;
+
+		for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) {
+			memcpy(d, s, INVENTORYITEM_WIDTH);
+
+			s += INVENTORYITEM_PITCH;
+			d += MOUSECOMBO_WIDTH;
+		}
+
+		g_system->setMouseCursor(v8, MOUSECOMBO_WIDTH, MOUSECOMBO_HEIGHT, 0, 0, 0);
 	}
 
 	return;
@@ -480,6 +481,18 @@
 //
 //	Cnv management
 //
+void Gfx::flatBlitCnv(Cnv *cnv, uint16 frame, int16 x, int16 y, Gfx::Buffers buffer) {
+
+	StaticCnv scnv;
+
+	scnv._width = cnv->_width;
+	scnv._height = cnv->_height;
+	scnv._data0 = cnv->getFramePtr(frame);
+	scnv._data1 = NULL; // _questioner->field_8[v60->_mood & 0xF];
+
+	flatBlitCnv(&scnv, x, y, buffer);
+}
+
 void Gfx::flatBlitCnv(StaticCnv *cnv, int16 x, int16 y, Gfx::Buffers buffer) {
 	Common::Rect r(cnv->_width, cnv->_height);
 	r.moveTo(x, y);
@@ -577,31 +590,20 @@
 
 }
 
-void Gfx::displayString(uint16 x, uint16 y, const char *text) {
-	assert(_font == _fonts[kFontMenu]);
-
+void Gfx::displayString(uint16 x, uint16 y, const char *text, byte color) {
 	byte *dst = _buffers[kBitFront] + x + y*SCREEN_WIDTH;
-	_font->setColor(1);
+	_font->setColor(color);
 	_font->drawString(dst, SCREEN_WIDTH, text);
 }
 
 void Gfx::displayCenteredString(uint16 y, const char *text) {
 	uint16 x = (SCREEN_WIDTH - getStringWidth(text)) / 2;
-	displayString(x, y, text);
+	displayString(x, y, text, 1);
 }
 
-void Gfx::displayBalloonString(uint16 x, uint16 y, const char *text, byte color) {
-	assert(_font == _fonts[kFontDialogue]);
+bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, byte color, uint16 wrapwidth) {
+//	printf("Gfx::displayWrappedString(%s, %i, %i, %i, %i)...", text, x, y, color, wrapwidth);
 
-	byte *dst = _buffers[kBitFront] + x + y*SCREEN_WIDTH;
-
-	_font->setColor(color);
-	_font->drawString(dst, SCREEN_WIDTH, text);
-}
-
-bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, uint16 maxwidth, byte color) {
-//	printf("Gfx::displayWrappedString(%s, %i, %i, %i, %i)...", text, x, y, maxwidth, color);
-
 	uint16 lines = 0;
 	bool rv = false;
 	uint16 linewidth = 0;
@@ -613,10 +615,10 @@
 
 	while (strlen(text) > 0) {
 
-		text = parseNextToken(text, token, 40, "   ");
+		text = parseNextToken(text, token, 40, "   ", true);
 		linewidth += getStringWidth(token);
 
-		if (linewidth > maxwidth) {
+		if (linewidth > wrapwidth) {
 			// wrap line
 			lines++;
 			rx = x + 10;			// x
@@ -630,7 +632,7 @@
 		if (!scumm_stricmp(token, "%p")) {
 			rv = true;
 		} else
-			displayBalloonString(rx, ry, token, color);
+			displayString(rx, ry, token, color);
 
 		rx += getStringWidth(token) + getStringWidth(" ");
 		linewidth += getStringWidth(" ");
@@ -658,7 +660,7 @@
 
 	while (strlen(text) != 0) {
 
-		text = parseNextToken(text, token, 40, "   ");
+		text = parseNextToken(text, token, 40, "   ", true);
 		w += getStringWidth(token);
 
 		if (w > maxwidth) {
@@ -857,7 +859,7 @@
 
 	freeStaticCnv(_mouseComposedArrow);
 	delete _mouseComposedArrow;
-	
+
 	return;
 }
 

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/graphics.h
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/graphics.h	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/graphics.h	2007-07-25 19:01:58 UTC (rev 28198)
@@ -57,6 +57,12 @@
 #define BASE_PALETTE_SIZE		BASE_PALETTE_COLORS*3
 #define PALETTE_SIZE			PALETTE_COLORS*3
 
+#define MOUSEARROW_WIDTH		16
+#define MOUSEARROW_HEIGHT		16
+
+#define MOUSECOMBO_WIDTH		32	// sizes for cursor + selected inventory item
+#define MOUSECOMBO_HEIGHT		32
+
 #include "common/pack-start.h"	// START STRUCT PACKING
 
 struct PaletteFxRange {
@@ -67,7 +73,7 @@
 	byte	_first;
 	byte	_last;
 
-};
+} PACKED_STRUCT;
 
 #include "common/pack-end.h"	// END STRUCT PACKING
 
@@ -165,10 +171,9 @@
 
 	// dialogue and text
 	void drawBalloon(const Common::Rect& r, uint16 arg_8);
-	void displayBalloonString(uint16 x, uint16 y, const char *text, byte color);
-	void displayString(uint16 x, uint16 y, const char *text);
+	void displayString(uint16 x, uint16 y, const char *text, byte color);
 	void displayCenteredString(uint16 y, const char *text);
-	bool displayWrappedString(char *text, uint16 x, uint16 y, uint16 maxwidth, byte color);
+	bool displayWrappedString(char *text, uint16 x, uint16 y, byte color, uint16 wrapwidth = SCREEN_WIDTH);
 	uint16 getStringWidth(const char *text);
 	void getStringExtent(char *text, uint16 maxwidth, int16* width, int16* height);
 
@@ -204,7 +209,9 @@
 	// DOS version didn't make use of it, but it is probably needed for Amiga stuff.
 	void flatBlitCnv(StaticCnv *cnv, int16 x, int16 y, Gfx::Buffers buffer);
 	void blitCnv(StaticCnv *cnv, int16 x, int16 y, uint16 z, Gfx::Buffers buffer);
+	void flatBlitCnv(Cnv *cnv, uint16 frame, int16 x, int16 y, Gfx::Buffers buffer);
 
+
 	// palette
 	void setPalette(Palette palette, uint32 first = FIRST_BASE_COLOR, uint32 num = BASE_PALETTE_COLORS);
 	void setBlackPalette();

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/intro.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/intro.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/intro.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -134,7 +134,7 @@
 		_vm->_soundMan->playMusic();
 	}
 
-	_engineFlags |= kEngineMouse;
+	_engineFlags |= kEngineBlockInput;
 
 	return;
 }
@@ -170,7 +170,7 @@
 
 		waitUntilLeftClick();
 
-		_engineFlags &= ~kEngineMouse;
+		_engineFlags &= ~kEngineBlockInput;
 		_vm->_menu->selectCharacter();
 	} else {
 		waitUntilLeftClick();

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/inventory.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/inventory.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/inventory.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -42,10 +42,6 @@
 #define INVENTORY_MAX_ITEMS 		30
 #define INVENTORY_FIRST_ITEM		4		// first four entries are used up by verbs
 
-#define INVENTORYITEM_PITCH 		32
-#define INVENTORYITEM_WIDTH 		24
-#define INVENTORYITEM_HEIGHT		24
-
 #define INVENTORY_ITEMS_PER_LINE	5
 #define INVENTORY_LINES 			6
 
@@ -89,59 +85,69 @@
 	{ 0,	0 }
 };
 
-void drawInventoryItem(uint16 pos, InventoryItem *item);
 
+int16 getNumUsedSlots() {
+	int16 num = 0;
+	while (num < INVENTORY_MAX_ITEMS && _inventory[num]._id != 0)
+		num++;
+	return num;
+}
 
+
 //	get inventory item index at position (x,y)
 //	in screen coordinates
 //
 int16 Parallaction::getHoverInventoryItem(int16 x, int16 y) {
 
-	int16 slot = -1;
-	do {
-		slot++;
-	} while (_inventory[slot]._id != 0);
-
+	int16 slot = getNumUsedSlots();
 	slot = (slot + 4) / INVENTORY_ITEMS_PER_LINE;
 
-	if (_invPosition.x >= x) return -1;
-	if ((_invPosition.x + INVENTORY_WIDTH) <= x) return -1;
+	Common::Rect r(INVENTORY_WIDTH, _numInvLines * INVENTORYITEM_HEIGHT);
+	r.moveTo(_invPosition);
 
-	if (_invPosition.y >= y) return -1;
-	if ((slot * INVENTORYITEM_HEIGHT + _invPosition.y) <= y) return -1;
+	if (!r.contains(Common::Point(x,y)))
+		return -1;
 
 	return ((x - _invPosition.x) / INVENTORYITEM_WIDTH) + (INVENTORY_ITEMS_PER_LINE * ((y - _invPosition.y) / INVENTORYITEM_HEIGHT));
 
 }
 
+void drawInventoryItem(uint16 pos, InventoryItem *item) {
 
-void refreshInventory(const char *character) {
-	for (uint16 i = 0; i < INVENTORY_MAX_ITEMS; i++) {
-		drawInventoryItem(i, &_inventory[i]);
+	uint16 line = pos / INVENTORY_ITEMS_PER_LINE;
+	uint16 col = pos % INVENTORY_ITEMS_PER_LINE;
+
+	// FIXME: this will end up in a general blit function
+	byte* s = _vm->_char._objs->getFramePtr(item->_index);
+	byte* d = _buffer + col * INVENTORYITEM_WIDTH + line * _vm->_char._objs->_height * INVENTORY_WIDTH;
+	for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) {
+		memcpy(d, s, INVENTORYITEM_WIDTH);
+
+		d += INVENTORY_WIDTH;
+		s += INVENTORYITEM_PITCH;
 	}
+
 	return;
 }
 
 
-void refreshInventoryItem(const char *character, uint16 index) {
-	drawInventoryItem(index, &_inventory[index]);
+
+void refreshInventory() {
+	for (uint16 i = 0; i < INVENTORY_MAX_ITEMS; i++)
+		drawInventoryItem(i, &_inventory[i]);
+
 	return;
 }
 
 int Parallaction::addInventoryItem(uint16 item) {
 
-	uint16 slot = 0;
-	while (_inventory[slot]._id != 0)
-		slot++;
-
+	int16 slot = getNumUsedSlots();
 	if (slot == INVENTORY_MAX_ITEMS)
 		return -1;
 
 	_inventory[slot]._id = MAKE_INVENTORY_ID(item);
 	_inventory[slot]._index = item;
 
-	refreshInventoryItem(_characterName, slot);
-
 	return 0;
 }
 
@@ -160,8 +166,6 @@
 		memcpy(&_inventory[slot], &_inventory[slot+1], sizeof(InventoryItem));
 	}
 
-	refreshInventory(_characterName);
-
 	return;
 }
 
@@ -177,28 +181,6 @@
 }
 
 
-
-
-
-
-void drawInventoryItem(uint16 pos, InventoryItem *item) {
-
-	uint16 line = pos / INVENTORY_ITEMS_PER_LINE;
-	uint16 col = pos % INVENTORY_ITEMS_PER_LINE;
-
-	// FIXME: this will end up in a general blit function
-	byte* s = _vm->_char._objs->getFramePtr(item->_index);
-	byte* d = _buffer + col * INVENTORYITEM_WIDTH + line * _vm->_char._objs->_height * INVENTORY_WIDTH;
-	for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) {
-		memcpy(d, s, INVENTORYITEM_WIDTH);
-
-		d += INVENTORY_WIDTH;
-		s += INVENTORYITEM_PITCH;
-	}
-
-	return;
-}
-
 void drawBorder(const Common::Rect& r, byte *buffer, byte color) {
 
 	byte *d = buffer + r.left + INVENTORY_WIDTH * r.top;
@@ -237,33 +219,20 @@
 }
 
 
+int16 getInventoryItemIndex(int16 pos) {
+	// TODO: should assert against the number of items actually contained,
+	// not the theoretical limit.
+	assert(pos >= 0 && pos < INVENTORY_MAX_ITEMS);
+	return _inventory[pos]._index;
+}
 
 
-void extractInventoryGraphics(int16 pos, byte *dst) {
-//	printf("extractInventoryGraphics(%i)\n", pos);
 
-	int16 line = pos / INVENTORY_ITEMS_PER_LINE;
-	int16 col = pos % INVENTORY_ITEMS_PER_LINE;
-
-	// FIXME: this will end up in a general blit function
-	byte* d = dst;
-	byte* s = _buffer + col * INVENTORYITEM_WIDTH + line * _vm->_char._objs->_height * INVENTORY_WIDTH;
-	for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) {
-		memcpy(d, s, INVENTORYITEM_WIDTH);
-
-		s += INVENTORY_WIDTH;
-		d += INVENTORYITEM_PITCH;
-	}
-
-	return;
-}
-
 void jobShowInventory(void *parm, Job *j) {
 //	printf("job_showInventory()...");
 
-	_numInvLines = 0;
-	while (_inventory[_numInvLines]._id != 0) _numInvLines++;
-	_numInvLines = (_numInvLines + 4) / INVENTORY_ITEMS_PER_LINE;
+	int16 slot = getNumUsedSlots();
+	_numInvLines = (slot + 4) / INVENTORY_ITEMS_PER_LINE;
 
 	Common::Rect r(INVENTORY_WIDTH, _numInvLines * INVENTORYITEM_HEIGHT);
 
@@ -286,13 +255,13 @@
 
 	static uint16 count = 0;
 
-	_engineFlags |= kEngineMouse;
+	_engineFlags |= kEngineBlockInput;
 
 	count++;
 	if (count == 2) {
 		count = 0;
 		j->_finished = 1;
-		_engineFlags &= ~kEngineMouse;
+		_engineFlags &= ~kEngineBlockInput;
 	}
 
 	Common::Rect r(INVENTORY_WIDTH, _numInvLines * INVENTORYITEM_HEIGHT);
@@ -308,26 +277,14 @@
 void openInventory() {
 	_engineFlags |= kEngineInventory;
 
-	uint16 slot = 0;
-	while (_inventory[slot]._id != 0)
-		slot++;
-
+	int16 slot = getNumUsedSlots();
 	uint16 lines = (slot + 4) / INVENTORY_ITEMS_PER_LINE;
 
-	_invPosition.x = _vm->_mousePos.x - (INVENTORY_WIDTH / 2);
-	if (_invPosition.x < 0)
-		_invPosition.x = 0;
+	_invPosition.x = CLIP(_vm->_mousePos.x - (INVENTORY_WIDTH / 2), 0, SCREEN_WIDTH - INVENTORY_WIDTH);
+	_invPosition.y = CLIP(_vm->_mousePos.y - 2 - (lines * INVENTORYITEM_HEIGHT), 0, SCREEN_HEIGHT - lines * INVENTORYITEM_HEIGHT);
 
-	if ((_invPosition.x + INVENTORY_WIDTH) > SCREEN_WIDTH)
-		_invPosition.x = SCREEN_WIDTH - INVENTORY_WIDTH;
+	refreshInventory();
 
-	_invPosition.y = _vm->_mousePos.y - 2 - (lines * INVENTORYITEM_HEIGHT);
-	if (_invPosition.y < 0)
-		_invPosition.y = 0;
-
-	if (_invPosition.y > SCREEN_HEIGHT - lines * INVENTORYITEM_HEIGHT)
-		_invPosition.y = SCREEN_HEIGHT - lines * INVENTORYITEM_HEIGHT;
-
 	return;
 
 }

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/inventory.h
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/inventory.h	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/inventory.h	2007-07-25 19:01:58 UTC (rev 28198)
@@ -34,10 +34,14 @@
 struct Cnv;
 
 struct InventoryItem {
-	uint32		_id;            // lowest 16 bits are always zero
-	uint16		_index;
+	uint32		_id;            // object name (lowest 16 bits are always zero)
+	uint16		_index;			// index to frame in objs file
 };
 
+#define INVENTORYITEM_PITCH 		32
+#define INVENTORYITEM_WIDTH 		24
+#define INVENTORYITEM_HEIGHT		24
+
 #define MAKE_INVENTORY_ID(x) (((x) & 0xFFFF) << 16)
 
 
@@ -47,16 +51,13 @@
 void destroyInventory();
 void openInventory();
 void closeInventory();
-int16 isItemInInventory(int32 v);
 void cleanInventory();
 void addInventoryItem(uint16 item);
 
+int16 getInventoryItemIndex(int16 pos);
 void highlightInventoryItem(int16 pos, byte color);
-void refreshInventory(const char *character);
 
-void extractInventoryGraphics(int16 pos, byte *dst);
 
-
 } // namespace Parallaction
 
 #endif

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/location.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/location.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/location.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -25,6 +25,8 @@
 
 #include "common/stdafx.h"
 
+#include "common/system.h"
+
 #include "parallaction/parallaction.h"
 #include "parallaction/sound.h"
 
@@ -38,6 +40,7 @@
 	_gfx->setFont(kFontLabel);
 
 	Script *_locationScript = _disk->loadLocation(filename);
+	_hasLocationSound = false;
 
 	fillBuffers(*_locationScript, true);
 	while (scumm_stricmp(_tokens[0], "ENDLOCATION")) {
@@ -140,16 +143,15 @@
 			parseAnimation(*_locationScript, _animations, _tokens[1]);
 		}
 		if (!scumm_stricmp(_tokens[0], "SOUND")) {
-			strcpy(_soundFile, _tokens[1]);
+			if (getPlatform() == Common::kPlatformAmiga) {
+				strcpy(_locationSound, _tokens[1]);
+				_hasLocationSound = true;
+			}
 		}
 		if (!scumm_stricmp(_tokens[0], "MUSIC")) {
 			if (getPlatform() == Common::kPlatformAmiga)
 				_soundMan->setMusicFile(_tokens[1]);
 		}
-		if (!scumm_stricmp(_tokens[0], "SOUND")) {
-//			if (getPlatform() == Common::kPlatformAmiga)
-//				_soundMan->loadSfx(_tokens[1], atoi(_tokens[2]));
-		}
 		fillBuffers(*_locationScript, true);
 	}
 
@@ -182,14 +184,14 @@
 
 	if (_localFlagNames)
 		delete _localFlagNames;
-	
+
 	// HACK: prevents leakage. A routine like this
 	// should allocate memory at all, though.
 	if ((_engineFlags & kEngineQuit) == 0) {
 		_localFlagNames = new Table(120);
 		_localFlagNames->addData("visited");
 	}
-		
+
 	_location._walkNodes.clear();
 
 	// TODO (LIST): helperNode should be rendered useless by the use of a Common::List<>
@@ -249,7 +251,9 @@
 			_si += 3;
 		}
 
+		g_system->delayMillis(20);
 		_gfx->setPalette(pal);
+		_gfx->updateScreen();
 	}
 
 	_disk->loadScenery(background, mask);
@@ -316,7 +320,7 @@
 
 
 	_hoverZone = NULL;
-	if (_engineFlags & kEngineMouse) {
+	if (_engineFlags & kEngineBlockInput) {
 		changeCursor( kCursorArrow );
 	}
 
@@ -371,6 +375,7 @@
 	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
 	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);
 	_gfx->setBlackPalette();
+	_gfx->updateScreen();
 
 	if (_location._commands.size() > 0) {
 		runCommands(_location._commands);
@@ -379,11 +384,11 @@
 		runJobs();
 		_gfx->swapBuffers();
 	}
-	
+
 	if (_location._comment) {
 		doLocationEnterTransition();
 	}
-	
+
 	runJobs();
 	_gfx->swapBuffers();
 
@@ -392,7 +397,8 @@
 		runCommands(_location._aCommands);
 	}
 
-//	_soundMan->playSfx(0);
+	if (_hasLocationSound)
+		_soundMan->playSfx(_locationSound, 0, true);
 
 	debugC(1, kDebugLocation, "changeLocation() done");
 
@@ -416,7 +422,7 @@
         debugC(3, kDebugLocation, "skipping location transition");
         return; // visited
     }
- 
+
 	byte pal[PALETTE_SIZE];
 	_gfx->buildBWPalette(pal);
 	_gfx->setPalette(pal);
@@ -437,7 +443,7 @@
 	_gfx->floodFill(Gfx::kBitFront, r, 0);
 	r.grow(-1);
 	_gfx->floodFill(Gfx::kBitFront, r, 1);
-	_gfx->displayWrappedString(_location._comment, 3, 5, 130, 0);
+	_gfx->displayWrappedString(_location._comment, 3, 5, 0, 130);
 
 	_gfx->updateScreen();
 	waitUntilLeftClick();
@@ -449,6 +455,7 @@
 		_gfx->quickFadePalette(pal);
 		_gfx->setPalette(pal);
 		waitTime( 1 );
+		_gfx->updateScreen();
 	}
 
 	debugC(1, kDebugLocation, "doLocationEnterTransition completed");

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/menu.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/menu.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/menu.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -87,12 +87,17 @@
 #define SLOT_Y			64
 #define SLOT_WIDTH		(BLOCK_WIDTH+2)
 
+#define PASSWORD_LEN	6
 
-static uint16 _dinoKey[] = { 5, 3, 6, 1, 4, 7 }; //
-static uint16 _donnaKey[] = { 0, 2, 8, 5, 5, 1 };
-static uint16 _doughKey[] = { 1, 7 ,7, 2, 2, 6 };
+static uint16 _amigaDinoKey[PASSWORD_LEN] = { 5, 3, 6, 2, 2, 7 };
+static uint16 _amigaDonnaKey[PASSWORD_LEN] = { 0, 3, 6, 2, 2, 6 };
+static uint16 _amigaDoughKey[PASSWORD_LEN] = { 1, 3 ,7, 2, 4, 6 };
 
+static uint16 _pcDinoKey[PASSWORD_LEN] = { 5, 3, 6, 1, 4, 7 };
+static uint16 _pcDonnaKey[PASSWORD_LEN] = { 0, 2, 8, 5, 5, 1 };
+static uint16 _pcDoughKey[PASSWORD_LEN] = { 1, 7 ,7, 2, 2, 6 };
 
+
 Menu::Menu(Parallaction *vm) {
 	_vm = vm;
 
@@ -105,10 +110,12 @@
 
 void Menu::start() {
 
-	_vm->_disk->selectArchive((_vm->getPlatform() == Common::kPlatformPC) ? "disk1" : "disk0");
+	_vm->_disk->selectArchive((_vm->getFeatures() & GF_LANG_MULT) ? "disk1" : "disk0");
 
 	splash();
 
+	_vm->_gfx->setFont(kFontMenu);
+
 	_language = chooseLanguage();
 	_vm->_disk->setLanguage(_language);
 
@@ -124,11 +131,13 @@
 	_vm->_disk->loadSlide("intro");
 	_vm->_gfx->setPalette(_vm->_gfx->_palette);
 	_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+	_vm->_gfx->updateScreen();
 	g_system->delayMillis(2000);
 
 	_vm->_disk->loadSlide("minintro");
 	_vm->_gfx->setPalette(_vm->_gfx->_palette);
 	_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+	_vm->_gfx->updateScreen();
 	g_system->delayMillis(2000);
 
 }
@@ -144,6 +153,8 @@
 
 	const char **v14 = introMsg3;
 
+	_vm->_disk->selectArchive("disk1");
+
 	_vm->_disk->loadScenery("test", NULL);
 	_vm->_gfx->setPalette(_vm->_gfx->_palette);
 	_vm->_gfx->swapBuffers();
@@ -153,16 +164,17 @@
 	_vm->_gfx->displayCenteredString(100, v14[2]);
 	_vm->_gfx->displayCenteredString(120, v14[3]);
 
+	_vm->showCursor(false);
+
 	_vm->_gfx->updateScreen();
-	_vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
 
 	_mouseButtons = kMouseNone;
-
-	for (; _mouseButtons != kMouseLeftUp; ) {
+	do {
 		_vm->updateInput();
-		if (_mouseButtons == kMouseRightUp) break;
-	}
+	} while (_mouseButtons != kMouseLeftUp && _mouseButtons != kMouseRightUp);
 
+	_vm->showCursor(true);
+
 	if (_mouseButtons != kMouseRightUp) {
 		strcpy(_vm->_location._name, "fogne");
 		return;    // show intro
@@ -179,45 +191,59 @@
 uint16 Menu::chooseLanguage() {
 
 	if (_vm->getPlatform() == Common::kPlatformAmiga) {
-		// TODO: should return the language ID supported by this version
-		// this can be done with some flags in the detection structures
-		return 1;
+		if (!(_vm->getFeatures() & GF_LANG_MULT)) {
+			if (_vm->getFeatures() & GF_DEMO)
+				return 1;		// Amiga Demo supports English
+			else
+				return 0;		// The only other non multi-lingual version just supports Italian
+		}
 	}
 
 	// user can choose language in dos version
 
-	_vm->_gfx->setFont(kFontMenu);
-
 	_vm->_disk->loadSlide("lingua");
 	_vm->_gfx->setPalette(_vm->_gfx->_palette);
 	_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
 
-	_vm->_gfx->displayString(60, 30, "SELECT LANGUAGE");
+	_vm->_gfx->displayString(60, 30, "SELECT LANGUAGE", 1);
 
-	_vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
-	_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);
-
 	_vm->changeCursor(kCursorArrow);
 
 	do {
 		_vm->updateInput();
-		_vm->_gfx->swapBuffers();
 
 		if (_mouseButtons == kMouseLeftUp) {
 			for (uint16 _si = 0; _si < 4; _si++) {
 
-				if (80 + _si*49 >= _vm->_mousePos.x) continue;
-				if (110 - _si*25 >= _vm->_mousePos.y) continue;
+				if (80 + _si * 49 >= _vm->_mousePos.x) continue;
+				if (110 - _si * 25 >= _vm->_mousePos.y) continue;
 
-				if (128 + _si*49 <= _vm->_mousePos.x) continue;
-				if (180 - _si*25 <=_vm->_mousePos.y) continue;
+				if (128 + _si * 49 <= _vm->_mousePos.x) continue;
+				if (180 - _si * 25 <= _vm->_mousePos.y) continue;
 
 //				beep();
+
+				switch (_si) {
+				case 0:
+					if (!(_vm->getFeatures() & GF_LANG_IT))
+						continue;
+				case 1:
+					if (!(_vm->getFeatures() & GF_LANG_FR))
+						continue;
+				case 2:
+					if (!(_vm->getFeatures() & GF_LANG_EN))
+						continue;
+				case 3:
+					if (!(_vm->getFeatures() & GF_LANG_DE))
+						continue;
+				}
+
 				return _si;
 			}
 		}
 
-		_vm->waitTime( 1 );
+		g_system->delayMillis(30);
+		_vm->_gfx->updateScreen();
 
 	} while (true);
 
@@ -236,41 +262,33 @@
 
 	_vm->_disk->loadSlide("restore");
 	_vm->_gfx->setPalette(_vm->_gfx->_palette);
-	_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
 
-	_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);
-
-
 	uint16 _si = 0;
 	uint16 _di = 3;
 
-	_vm->updateInput();
+	_mouseButtons = kMouseNone;
 	while (_mouseButtons != kMouseLeftUp) {
 
 		_vm->updateInput();
-		_vm->_gfx->swapBuffers();
-		_vm->waitTime( 1 );
 
-		_si = 0;
-		if (_vm->_mousePos.x > 160)
-			_si = 1;
+		_si = (_vm->_mousePos.x > 160) ? 1 : 0;
 
-		if (_si == _di) continue;
+		if (_si != _di) {
+			_di = _si;
 
-		_di = _si;
-		_vm->_gfx->copyScreen(Gfx::kBit2, Gfx::kBitFront);
+			_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+			if (_si != 0) {
+				// load a game
+				_vm->_gfx->displayString(60, 30, loadGameMsg[_language], 1);
+			} else {
+				// new game
+				_vm->_gfx->displayString(60, 30, newGameMsg[_language], 1);
+			}
 
-		if (_si != 0) {
-			// load a game
-			_vm->_gfx->displayString(60, 30, loadGameMsg[_language]);
-		} else {
-			// new game
-			_vm->_gfx->displayString(60, 30, newGameMsg[_language]);
 		}
 
+		g_system->delayMillis(30);
 		_vm->_gfx->updateScreen();
-		_vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
-
 	}
 
 	if (_si == 0) return 0; // new game
@@ -291,6 +309,30 @@
 }
 
 
+int Menu::getSelectedBlock(const Common::Point &p, Common::Rect &r) {
+
+	for (uint16 _si = 0; _si < 9; _si++) {
+
+		Common::Rect q(
+			_si * BLOCK_X_OFFSET + BLOCK_SELECTION_X,
+			BLOCK_SELECTION_Y - _si * BLOCK_Y_OFFSET,
+			(_si + 1) * BLOCK_X_OFFSET + BLOCK_SELECTION_X,
+			BLOCK_SELECTION_Y + BLOCK_HEIGHT - _si * BLOCK_Y_OFFSET
+		);
+
+		if (q.contains(p)) {
+			r.setWidth(BLOCK_WIDTH);
+			r.setHeight(BLOCK_HEIGHT);
+			r.moveTo(_si * BLOCK_X_OFFSET + BLOCK_X, BLOCK_Y - _si * BLOCK_Y_OFFSET);
+			return _si;
+		}
+
+	}
+
+	return -1;
+}
+
+
 //
 //	character selection and protection
 //
@@ -298,11 +340,8 @@
 	debugC(1, kDebugMenu, "Menu::selectCharacter()");
 
 	uint16 _di = 0;
-	bool askPassword = true;
 
-	uint16 _donna_points = 0;
-	uint16 _dino_points = 0;
-	uint16 _dough_points = 0;
+	uint16 _donna_points, _dino_points, _dough_points;
 
 	StaticCnv v14;
 
@@ -315,88 +354,84 @@
 
 	_vm->_gfx->setFont(kFontMenu);
 
-	_vm->_disk->selectArchive((_vm->getPlatform() == Common::kPlatformPC) ? "disk1" : "disk0");
+	_vm->_disk->selectArchive((_vm->getFeatures() & GF_LANG_MULT) ? "disk1" : "disk0");
 
 	_vm->_disk->loadSlide("password");	// loads background into kBitBack buffer
+	_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);	//
 
-	_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);	//
-	_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);		//
 	_vm->_gfx->setPalette(_vm->_gfx->_palette);
 
-	while (askPassword == true) {
+	while (true) {
 
-		askPassword = false;
 		_di = 0;
 
-		_vm->_gfx->displayString(60, 30, introMsg1[_language]);			// displays message
-		_vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack);
+		_vm->_gfx->displayString(60, 30, introMsg1[_language], 1);			// displays message
 
-		while (_di < 6) {
+		_donna_points = 0;
+		_dino_points = 0;
+		_dough_points = 0;
 
+		while (_di < PASSWORD_LEN) {
+
 			_mouseButtons = kMouseNone;
 			do {
 				_vm->updateInput();
-				_vm->_gfx->swapBuffers();
-				_vm->waitTime(1);
+				g_system->delayMillis(30);
+				_vm->_gfx->updateScreen();
 			} while (_mouseButtons != kMouseLeftUp);	// waits for left click
 
-			for (uint16 _si = 0; _si < 9; _si++) {
-
-				Common::Rect r(
-					_si * BLOCK_X_OFFSET + BLOCK_SELECTION_X,
-					BLOCK_SELECTION_Y - _si * BLOCK_Y_OFFSET,
-					(_si + 1) * BLOCK_X_OFFSET + BLOCK_SELECTION_X,
-					BLOCK_SELECTION_Y + BLOCK_HEIGHT - _si * BLOCK_Y_OFFSET
-				);
-
-				if (!r.contains(_vm->_mousePos)) continue;
-
-				r.setWidth(BLOCK_WIDTH);
-				r.setHeight(BLOCK_HEIGHT);
-				r.moveTo(_si * BLOCK_X_OFFSET + BLOCK_X, BLOCK_Y - _si * BLOCK_Y_OFFSET);
+			Common::Rect r;
+			int _si = getSelectedBlock(_vm->_mousePos, r);
+			if (_si != -1) {
 				_vm->_gfx->grabRect(v14._data0, r, Gfx::kBitFront, BLOCK_WIDTH);
-
-				_vm->_gfx->flatBlitCnv(&v14, _di * SLOT_WIDTH + SLOT_X, SLOT_Y, Gfx::kBitBack);
 				_vm->_gfx->flatBlitCnv(&v14, _di * SLOT_WIDTH + SLOT_X, SLOT_Y, Gfx::kBitFront);
-
 //				beep();
 
-				if (_dinoKey[_di] == _si)
-					_dino_points++;  // dino
-				if (_donnaKey[_di] == _si)
-					_donna_points++;  // donna
-				if (_doughKey[_di] == _si)
-					_dough_points++;  // dough
+				if (_vm->getPlatform() == Common::kPlatformAmiga && (_vm->getFeatures() & GF_LANG_MULT)) {
+					if (_amigaDinoKey[_di] == _si)
+						_dino_points++;  // dino
+					if (_amigaDonnaKey[_di] == _si)
+						_donna_points++;  // donna
+					if (_amigaDoughKey[_di] == _si)
+						_dough_points++;  // dough
+				} else {
+					if (_pcDinoKey[_di] == _si)
+						_dino_points++;  // dino
+					if (_pcDonnaKey[_di] == _si)
+						_donna_points++;  // donna
+					if (_pcDoughKey[_di] == _si)
+						_dough_points++;  // dough
+				}
 
 				_di++;
 			}
+		}
 
-			askPassword = (_dino_points < 6 && _donna_points < 6 && _dough_points < 6);
+		if (_dino_points == PASSWORD_LEN || _donna_points == PASSWORD_LEN || _dough_points == PASSWORD_LEN) {
+			break;
 		}
 
-		if (askPassword == false) break;
-
-		_vm->_gfx->copyScreen(Gfx::kBit2, Gfx::kBitFront);
-		_vm->_gfx->displayString(60, 30, introMsg2[_language]);
+		_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+		_vm->_gfx->displayString(60, 30, introMsg2[_language], 1);
 		_vm->_gfx->updateScreen();
 
 		g_system->delayMillis(2000);
 
-		_vm->_gfx->copyScreen(Gfx::kBit2, Gfx::kBitFront);
+		_vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
 	}
 
-
-	if (_dino_points > _donna_points && _dino_points > _dough_points) {
+	if (_dino_points == PASSWORD_LEN) {
 		sprintf(_vm->_location._name, "test.%s", _dinoName);
-	} else {
-		if (_donna_points > _dino_points && _donna_points > _dough_points) {
-			sprintf(_vm->_location._name, "test.%s", _donnaName);
-		} else {
-			sprintf(_vm->_location._name, "test.%s", _doughName);
-		}
+	} else
+	if (_donna_points == PASSWORD_LEN) {
+		sprintf(_vm->_location._name, "test.%s", _donnaName);
+	} else
+	if (_dough_points == PASSWORD_LEN) {
+		sprintf(_vm->_location._name, "test.%s", _doughName);
 	}
 
 	_vm->_gfx->setBlackPalette();
+	_vm->_gfx->updateScreen();
 
 	_engineFlags |= kEngineChangeLocation;
 

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/menu.h
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/menu.h	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/menu.h	2007-07-25 19:01:58 UTC (rev 28198)
@@ -48,6 +48,7 @@
 	void		newGame();
 	uint16		chooseLanguage();
 	uint16		selectGame();
+	int			getSelectedBlock(const Common::Point &p, Common::Rect& r);
 
 public:
 

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/parallaction.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/parallaction.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -84,10 +84,7 @@
 
 char		_forwardedAnimationNames[20][20];
 uint16		_numForwards = 0;
-char		_soundFile[20];
 
-byte		_mouseHidden = 0;
-
 uint32		_commandFlags = 0;
 uint16		_introSarcData3 = 200;
 uint16		_introSarcData2 = 1;
@@ -107,8 +104,8 @@
 	// FIXME
 	_vm = this;
 
+	_mouseHidden = false;
 
-
 	Common::File::addDefaultDirectory( _gameDataPath );
 
 	Common::addSpecialDebugLevel(kDebugDialogue, "dialogue", "Dialogues debug level");
@@ -135,15 +132,15 @@
 	delete _zoneFlagNames;
 
 	_animations.remove(&_char._ani);
-	
+
 	freeLocation();
-	
+
 	freeCharacter();
 	destroyInventory();
 
 	delete _gfx;
 	delete _soundMan;
-	delete _disk;	
+	delete _disk;
 }
 
 
@@ -160,6 +157,8 @@
 	_localFlagNames = NULL;
 	initResources();
 
+	_hasLocationSound = false;
+
 	_skipMenu = false;
 
 	_transCurrentHoverItem = 0;
@@ -175,11 +174,14 @@
 
 	_baseTime = 0;
 
-	if (getPlatform() == Common::kPlatformPC)
+	if (getPlatform() == Common::kPlatformPC) {
 		_disk = new DosDisk(this);
-	else {
+	} else {
+		if (getFeatures() & GF_DEMO) {
+			strcpy(_location._name, "fognedemo");
+		}
 		_disk = new AmigaDisk(this);
-		_disk->selectArchive("disk0");
+		_disk->selectArchive((_vm->getFeatures() & GF_DEMO) ? "disk0" : "disk1");
 	}
 
 	_engineFlags = 0;
@@ -281,10 +283,11 @@
 
 		switch (e.type) {
 		case Common::EVENT_KEYDOWN:
-			if (e.kbd.ascii == 'l') KeyDown = kEvLoadGame;
-			if (e.kbd.ascii == 's') KeyDown = kEvSaveGame;
 			if (e.kbd.flags == Common::KBD_CTRL && e.kbd.keycode == 'd')
 				_debugger->attach();
+			if (getFeatures() & GF_DEMO) break;
+			if (e.kbd.keycode == Common::KEYCODE_l) KeyDown = kEvLoadGame;
+			if (e.kbd.keycode == Common::KEYCODE_s) KeyDown = kEvSaveGame;
 			break;
 
 		case Common::EVENT_LBUTTONDOWN:
@@ -367,6 +370,9 @@
 	if (_location._comment)
 		doLocationEnterTransition();
 
+	if (_hasLocationSound)
+		_soundMan->playSfx(_locationSound, 0, true);
+
 	changeCursor(kCursorArrow);
 
 	if (_location._aCommands.size() > 0)
@@ -376,8 +382,8 @@
 		_keyDown = updateInput();
 
 		debugC(3, kDebugInput, "runGame: input flags (%i, %i, %i, %i)",
-			_mouseHidden == 0,
-			(_engineFlags & kEngineMouse) == 0,
+			!_mouseHidden,
+			(_engineFlags & kEngineBlockInput) == 0,
 			(_engineFlags & kEngineWalking) == 0,
 			(_engineFlags & kEngineChangeLocation) == 0
 		);
@@ -388,7 +394,7 @@
 		// Skipping input processing when kEngineChangeLocation is set solves the issue. It's
 		// noteworthy that the programmers added this very check in Big Red Adventure's engine,
 		// so it should be ok here in Nippon Safes too.
-		if ((_mouseHidden == 0) && ((_engineFlags & kEngineMouse) == 0) && ((_engineFlags & kEngineWalking) == 0) && ((_engineFlags & kEngineChangeLocation) == 0)) {
+		if ((!_mouseHidden) && ((_engineFlags & kEngineBlockInput) == 0) && ((_engineFlags & kEngineWalking) == 0) && ((_engineFlags & kEngineChangeLocation) == 0)) {
 			InputData *v8 = translateInput();
 			if (v8) processInput(v8);
 		}
@@ -506,14 +512,14 @@
 
 	case kEvSaveGame:
 		_hoverZone = NULL;
+		saveGame();
 		changeCursor(kCursorArrow);
-		saveGame();
 		break;
 
 	case kEvLoadGame:
 		_hoverZone = NULL;
+		loadGame();
 		changeCursor(kCursorArrow);
-		loadGame();
 		break;
 
 	}
@@ -673,8 +679,11 @@
 }
 
 
+void Parallaction::showCursor(bool visible) {
+	_mouseHidden = !visible;
+	g_system->showMouse(visible);
+}
 
-
 //	changes the mouse pointer
 //	index 0 means standard pointer (from pointer.cnv)
 //	index > 0 means inventory item
@@ -754,21 +763,26 @@
 		// character for sanity before memory is freed
 		freeCharacter();
 
-		_disk->selectArchive((_vm->getPlatform() == Common::kPlatformPC) ? "disk1" : "disk0");
+		Common::String oldArchive = _disk->selectArchive((_vm->getFeatures() & GF_LANG_MULT) ? "disk1" : "disk0");
 		_vm->_char._ani._cnv = _disk->loadFrames(fullName);
 
 		if (!IS_DUMMY_CHARACTER(name)) {
+			if (_vm->getPlatform() == Common::kPlatformAmiga && (_vm->getFeatures() & GF_LANG_MULT))
+				_disk->selectArchive("disk0");
+
 			_vm->_char._head = _disk->loadHead(baseName);
 			_vm->_char._talk = _disk->loadTalk(baseName);
 			_vm->_char._objs = _disk->loadObjects(baseName);
 			_objectsNames = _disk->loadTable(baseName);
-			refreshInventory(baseName);
 
 			_soundMan->playCharacterMusic(name);
 
-			if ((getFeatures() & GF_DEMO) == 0)
+			if (!(getFeatures() & GF_DEMO))
 				parseLocation("common");
 		}
+
+		if (!oldArchive.empty())
+			_disk->selectArchive(oldArchive);
 	}
 
 	strcpy(_characterName1, fullName);
@@ -856,13 +870,13 @@
 
 	debugC(3, kDebugJobs, "jobWaitRemoveJob: count = %i", count);
 
-	_engineFlags |= kEngineMouse;
+	_engineFlags |= kEngineBlockInput;
 
 	count++;
 	if (count == 2) {
 		count = 0;
 		_vm->removeJob(arg);
-		_engineFlags &= ~kEngineMouse;
+		_engineFlags &= ~kEngineBlockInput;
 		j->_finished = 1;
 	}
 

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/parallaction.h
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/parallaction.h	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/parallaction.h	2007-07-25 19:01:58 UTC (rev 28198)
@@ -27,9 +27,8 @@
 #define PARALLACTION_H
 
 #include "common/str.h"
-#include "gui/dialog.h"
-#include "gui/widget.h"
 
+
 #include "engines/engine.h"
 
 #include "parallaction/defs.h"
@@ -44,6 +43,7 @@
 	class CommandSender;
 }
 
+extern OSystem *g_system;
 
 namespace Parallaction {
 
@@ -60,7 +60,12 @@
 };
 
 enum {
-	GF_DEMO = 1 << 0
+	GF_DEMO = 1 << 0,
+	GF_LANG_EN = 1 << 1,
+	GF_LANG_FR = 1 << 2,
+	GF_LANG_DE = 1 << 3,
+	GF_LANG_IT = 1 << 4,
+	GF_LANG_MULT = 1 << 5
 };
 
 
@@ -105,7 +110,7 @@
 	kEngineInventory		= (1 << 2),
 	kEngineWalking			= (1 << 3),
 	kEngineChangeLocation	= (1 << 4),
-	kEngineMouse			= (1 << 5),
+	kEngineBlockInput		= (1 << 5),
 	kEngineDragging 		= (1 << 6),
 	kEngineTransformedDonna		= (1 << 7)
 };
@@ -172,12 +177,10 @@
 extern Command 		*_forwardedCommands[];
 extern char 		_forwardedAnimationNames[][20];
 extern uint16 		_numForwards;
-extern char 		_soundFile[];
 extern char 		_slideText[][40];
 extern uint16 		_introSarcData3;		 // sarcophagus stuff to be saved
 extern uint16 		_introSarcData2;		 // sarcophagus stuff to be saved
 extern char 		_saveData1[];
-extern byte 		_mouseHidden;
 extern uint32 		_commandFlags;
 extern const char 	*_instructionNamesRes[];
 extern const char 	*_commandsNamesRes[];
@@ -306,6 +309,7 @@
 
 	void 		parseLocation(const char *filename);
 	void 		changeCursor(int32 index);
+	void		showCursor(bool visible);
 	void 		changeCharacter(const char *name);
 
 	char   		*parseComment(Script &script);
@@ -392,6 +396,8 @@
 
 	bool		_skipMenu;
 
+	bool 		_mouseHidden;
+
 	// input-only
 	InputData	 _input;
 	bool		_actionAfterWalk;  // actived when the character needs to move before taking an action
@@ -410,7 +416,10 @@
 
 	Common::String      _saveFileName;
 
+	bool		_hasLocationSound;
+	char		_locationSound[50];
 
+
 protected:		// members
 	bool detectGame(void);
 
@@ -454,15 +463,6 @@
 
 	void 		freeCharacter();
 
-	uint16 		askDialoguePassword(Dialogue *q, StaticCnv *face);
-	bool 		displayAnswer(Dialogue *q, uint16 i);
-	bool 		displayAnswers(Dialogue *q);
-	void 		displayQuestion(Dialogue *q, Cnv *cnv);
-	uint16 		getDialogueAnswer(Dialogue *q, Cnv *cnv);
-	int16 		selectAnswer(Question *q, StaticCnv *cnv);
-	void 		enterDialogue();
-	void 		exitDialogue();
-
 	int 		addInventoryItem(uint16 item);
 	void 		dropItem(uint16 item);
 	int16 		pickupItem(Zone *z);
@@ -473,34 +473,7 @@
 // FIXME: remove global
 extern Parallaction *_vm;
 
-class SaveLoadChooser : public GUI::Dialog {
-	typedef Common::String String;
-	typedef Common::StringList StringList;
-protected:
-	GUI::ListWidget		*_list;
-	GUI::ButtonWidget	*_chooseButton;
-	GUI::GraphicsWidget	*_gfxWidget;
-	GUI::StaticTextWidget	*_date;
-	GUI::StaticTextWidget	*_time;
-	GUI::StaticTextWidget	*_playtime;
-	GUI::ContainerWidget	*_container;
-	Parallaction			*_vm;
 
-	uint8 _fillR, _fillG, _fillB;
-
-public:
-	SaveLoadChooser(const String &title, const String &buttonLabel, Parallaction *engine);
-	~SaveLoadChooser();
-
-	virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
-	const String &getResultString() const;
-	void setList(const StringList& list);
-	int runModal();
-
-	virtual void reflowLayout();
-};
-
-
 } // namespace Parallaction
 
 

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/parser.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/parser.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/parser.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -119,24 +119,72 @@
 
 }
 
-//	looks for next token in a string
 //
-//	scans 's' until one of the stop-chars in 'brk' is found
-//	builds a token and return the part of the string which hasn't been parsed
+//	Scans 's' until one of the stop-chars in 'brk' is found, building a token.
+//	If the routine encounters quotes, it will extract the contained text and
+//  make a proper token. When scanning inside quotes, 'brk' is ignored and
+//  only newlines are considered stop-chars.
+//
+//	The routine returns the unparsed portion of the input string 's'.
+//
+char *parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes) {
 
-char *parseNextToken(char *s, char *tok, uint16 count, const char *brk) {
+	enum STATES { NORMAL, QUOTED };
 
-	while (*s != '\0') {
+	STATES state = NORMAL;
 
-		if (brk[0] == *s) break;
-		if (brk[1] == *s) break;
-		if (brk[2] == *s) break;
+	char *t = s;
 
-		*tok++ = *s++;
+	while (count > 0) {
+
+		switch (state) {
+		case NORMAL:
+			if (*s == '\0') {
+				*tok = '\0';
+				return s;
+			}
+
+			if (strchr(brk, *s)) {
+				*tok = '\0';
+				return ++s;
+			}
+
+			if (*s == '"') {
+				if (ignoreQuotes) {
+					*tok++ = *s++;
+					count--;
+				} else {
+					state = QUOTED;
+					s++;
+				}
+			} else {
+				*tok++ = *s++;
+				count--;
+			}
+			break;
+
+		case QUOTED:
+			if (*s == '\0') {
+				*tok = '\0';
+				return s;
+			}
+			if (*s == '"' || *s == '\n' || *s == '\t') {
+				*tok = '\0';
+				return ++s;
+			}
+
+			*tok++ = *s++;
+			count--;
+			break;
+		}
+
 	}
 
 	*tok = '\0';
-	return s;
+	warning("token was truncated from line '%s'", t);
+
+	return tok;
+
 }
 
 uint16 fillTokens(char* line) {
@@ -144,15 +192,6 @@
 	uint16 i = 0;
 	while (strlen(line) > 0 && i < 20) {
 		line = parseNextToken(line, _tokens[i], 40, " \t\n");
-		if (_tokens[i][0] == '"' && _tokens[i][strlen(_tokens[i]) - 1] != '"') {
-
-			line = parseNextToken(line, _tokens[i+1], 40, "\"");
-			strcat(_tokens[i], _tokens[i+1]);
-			_tokens[i][0] = ' ';
-			line++;
-
-		}
-
 		line = Common::ltrim(line);
 		i++;
 	}

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/parser.h
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/parser.h	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/parser.h	2007-07-25 19:01:58 UTC (rev 28198)
@@ -33,7 +33,7 @@
 namespace Parallaction {
 
 uint16 fillBuffers(Common::SeekableReadStream &stream, bool errorOnEOF = false);
-char   *parseNextToken(char *s, char *tok, uint16 count, const char *brk);
+char   *parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes = false);
 
 extern char _tokens[][40];
 

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/saveload.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/saveload.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/saveload.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -26,6 +26,7 @@
 #include "common/stdafx.h"
 #include "common/savefile.h"
 
+#include "gui/dialog.h"
 #include "gui/widget.h"
 #include "gui/ListWidget.h"
 #include "gui/message.h"
@@ -48,6 +49,37 @@
 
 extern char _gameNames[][20];
 
+
+class SaveLoadChooser : public GUI::Dialog {
+	typedef Common::String String;
+	typedef Common::StringList StringList;
+protected:
+	GUI::ListWidget		*_list;
+	GUI::ButtonWidget	*_chooseButton;
+	GUI::GraphicsWidget	*_gfxWidget;
+	GUI::StaticTextWidget	*_date;
+	GUI::StaticTextWidget	*_time;
+	GUI::StaticTextWidget	*_playtime;
+	GUI::ContainerWidget	*_container;
+	Parallaction			*_vm;
+
+	uint8 _fillR, _fillG, _fillB;
+
+public:
+	SaveLoadChooser(const String &title, const String &buttonLabel, Parallaction *engine);
+	~SaveLoadChooser();
+
+	virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
+	const String &getResultString() const;
+	void setList(const StringList& list);
+	int runModal();
+
+	virtual void reflowLayout();
+};
+
+
+
+
 void Parallaction::doLoadGame(uint16 slot) {
 
 	_introSarcData3 = 200;
@@ -134,8 +166,6 @@
 //	freeTable(_objectsNames);
 //	initTable(filename, _objectsNames);
 
-//	refreshInventory(_vm->_characterName);
-
 //	parseLocation("common");
 
 	// force reload of character to solve inventory
@@ -206,11 +236,7 @@
 
 	delete f;
 
-	refreshInventory(_characterName);
-
 	return;
-
-
 }
 
 enum {

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/zone.cpp
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/zone.cpp	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/zone.cpp	2007-07-25 19:01:58 UTC (rev 28198)
@@ -216,22 +216,13 @@
 
 				strcpy(vC8, _tokens[1]);
 
-				StaticCnv vE0;
 				u->door->_cnv = _disk->loadFrames(vC8);
-
-				vE0._width = u->door->_cnv->_width;
-				vE0._height = u->door->_cnv->_height;
-
 				uint16 _ax = (z->_flags & kFlagsClosed ? 0 : 1);
-				vE0._data0 = u->door->_cnv->getFramePtr(_ax);
 
-//				_ax = (z->_flags & kFlagsClosed ? 0 : 1);
-//				vE0._data1 = doorcnv->field_8[_ax];
-
-				u->door->_background = (byte*)malloc(vE0._width*vE0._height);
+				u->door->_background = (byte*)malloc(u->door->_cnv->_width * u->door->_cnv->_height);
 				_gfx->backupDoorBackground(u->door, z->_left, z->_top);
 
-				_gfx->flatBlitCnv(&vE0, z->_left, z->_top, Gfx::kBitBack);
+				_gfx->flatBlitCnv(u->door->_cnv, _ax, z->_left, z->_top, Gfx::kBitBack);
 			}
 
 			if (!scumm_stricmp(_tokens[0],	"startpos")) {
@@ -304,27 +295,22 @@
 void Parallaction::displayCharacterComment(ExamineData *data) {
 	if (data->_description == NULL) return;
 
-	StaticCnv v3C;
-	v3C._width = _char._talk->_width;
-	v3C._height = _char._talk->_height;
-	v3C._data0 = _char._talk->getFramePtr(0);
-	v3C._data1 = NULL; //_talk->field_8[0];
-
 	_gfx->setFont(kFontDialogue);
-	_gfx->flatBlitCnv(&v3C, 190, 80, Gfx::kBitFront);
+	_gfx->flatBlitCnv(_char._talk, 0, 190, 80, Gfx::kBitFront);
 
 	int16 v26, v28;
 	_gfx->getStringExtent(data->_description, 130, &v28, &v26);
 	Common::Rect r(v28, v26);
 	r.moveTo(140, 10);
 	_gfx->drawBalloon(r, 0);
-	_gfx->displayWrappedString(data->_description, 140, 10, 130, 0);
+	_gfx->displayWrappedString(data->_description, 140, 10, 0, 130);
 
 	_gfx->updateScreen();
 
 	waitUntilLeftClick();
 
 	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+	_gfx->updateScreen();
 
 	return;
 }
@@ -359,7 +345,7 @@
 	r.moveTo(0, 90);
 	_gfx->drawBalloon(r, 0);
 	_gfx->flatBlitCnv(_vm->_char._head, 100, 152, Gfx::kBitFront);
-	_gfx->displayWrappedString(data->_description, 0, 90, 130, 0);
+	_gfx->displayWrappedString(data->_description, 0, 90, 0, 130);
 
 	jobEraseAnimations((void*)1, NULL);
 	_gfx->updateScreen();
@@ -368,6 +354,7 @@
 
 	_gfx->setHalfbriteMode(false);
 	_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+	_gfx->updateScreen();
 
 	return;
 }
@@ -441,10 +428,8 @@
 
 		uint16 _ax = (z->_flags & kFlagsClosed ? 0 : 1);
 
-		v14._data0 = z->u.door->_cnv->getFramePtr(_ax);
-
-		_vm->_gfx->flatBlitCnv(&v14, z->_left, z->_top, Gfx::kBitBack);
-		_vm->_gfx->flatBlitCnv(&v14, z->_left, z->_top, Gfx::kBit2);
+		_vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBitBack);
+		_vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBit2);
 	}
 
 	count++;

Modified: scummvm/branches/branch-0-10-0/engines/parallaction/zone.h
===================================================================
--- scummvm/branches/branch-0-10-0/engines/parallaction/zone.h	2007-07-25 16:12:19 UTC (rev 28197)
+++ scummvm/branches/branch-0-10-0/engines/parallaction/zone.h	2007-07-25 19:01:58 UTC (rev 28198)
@@ -68,7 +68,8 @@
 };
 
 
-#define NUM_ANSWERS		 5
+#define NUM_QUESTIONS		20
+#define NUM_ANSWERS		 	5
 
 struct Command;
 struct Question;
@@ -97,7 +98,9 @@
 	~Question();
 };
 
-typedef Question Dialogue;
+struct Dialogue {
+	Question	*_questions[NUM_QUESTIONS];
+};
 
 struct GetData {	// size = 24
 	uint32			_icon;


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