[Scummvm-cvs-logs] SF.net SVN: scummvm: [22221] scummvm/trunk/engines/simon

kirben at users.sourceforge.net kirben at users.sourceforge.net
Sat Apr 29 06:39:05 CEST 2006


Revision: 22221
Author:   kirben
Date:     2006-04-29 06:38:07 -0700 (Sat, 29 Apr 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=22221&view=rev

Log Message:
-----------
Split more functions of simon.cpp into separate files

Modified Paths:
--------------
    scummvm/trunk/engines/simon/items.cpp
    scummvm/trunk/engines/simon/module.mk
    scummvm/trunk/engines/simon/simon.cpp
    scummvm/trunk/engines/simon/string.cpp

Added Paths:
-----------
    scummvm/trunk/engines/simon/event.cpp
    scummvm/trunk/engines/simon/subroutine.cpp
    scummvm/trunk/engines/simon/window.cpp
Added: scummvm/trunk/engines/simon/event.cpp
===================================================================
--- scummvm/trunk/engines/simon/event.cpp	                        (rev 0)
+++ scummvm/trunk/engines/simon/event.cpp	2006-04-29 13:38:07 UTC (rev 22221)
@@ -0,0 +1,290 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "simon/simon.h"
+#include "simon/intern.h"
+
+namespace Simon {
+
+void SimonEngine::addTimeEvent(uint timeout, uint subroutine_id) {
+	TimeEvent *te = (TimeEvent *)malloc(sizeof(TimeEvent)), *first, *last = NULL;
+	time_t cur_time;
+
+	time(&cur_time);
+
+	te->time = cur_time + timeout - _gameStoppedClock;
+	if (_clockStopped)
+		te->time -= ((uint32)time(NULL) - _clockStopped);
+	te->subroutine_id = subroutine_id;
+
+	first = _firstTimeStruct;
+	while (first) {
+		if (te->time <= first->time) {
+			if (last) {
+				last->next = te;
+				te->next = first;
+				return;
+			}
+			te->next = _firstTimeStruct;
+			_firstTimeStruct = te;
+			return;
+		}
+
+		last = first;
+		first = first->next;
+	}
+
+	if (last) {
+		last->next = te;
+		te->next = NULL;
+	} else {
+		_firstTimeStruct = te;
+		te->next = NULL;
+	}
+}
+
+void SimonEngine::delTimeEvent(TimeEvent *te) {
+	TimeEvent *cur;
+
+	if (te == _pendingDeleteTimeEvent)
+		_pendingDeleteTimeEvent = NULL;
+
+	if (te == _firstTimeStruct) {
+		_firstTimeStruct = te->next;
+		free(te);
+		return;
+	}
+
+	cur = _firstTimeStruct;
+	if (cur == NULL)
+		error("delTimeEvent: none available");
+
+	for (;;) {
+		if (cur->next == NULL)
+			error("delTimeEvent: no such te");
+		if (te == cur->next) {
+			cur->next = te->next;
+			free(te);
+			return;
+		}
+		cur = cur->next;
+	}
+}
+
+void SimonEngine::invokeTimeEvent(TimeEvent *te) {
+	Subroutine *sub;
+
+	_scriptVerb = 0;
+
+	if (_runScriptReturn1)
+		return;
+
+	sub = getSubroutineByID(te->subroutine_id);
+	if (sub != NULL)
+		startSubroutineEx(sub);
+
+	_runScriptReturn1 = false;
+}
+
+void SimonEngine::killAllTimers() {
+	TimeEvent *cur, *next;
+
+	for (cur = _firstTimeStruct; cur; cur = next) {
+		next = cur->next;
+		delTimeEvent(cur);
+	}
+}
+
+bool SimonEngine::kickoffTimeEvents() {
+	time_t cur_time;
+	TimeEvent *te;
+	bool result = false;
+
+	if (_clockStopped)
+		return result;
+
+	time(&cur_time);
+	cur_time -= _gameStoppedClock;
+
+	while ((te = _firstTimeStruct) != NULL && te->time <= (uint32)cur_time) {
+		result = true;
+		_pendingDeleteTimeEvent = te;
+		invokeTimeEvent(te);
+		if (_pendingDeleteTimeEvent) {
+			_pendingDeleteTimeEvent = NULL;
+			delTimeEvent(te);
+		}
+	}
+
+	return result;
+}
+
+void SimonEngine::addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum, int32 param) {
+	VgaTimerEntry *vte;
+
+	// When Simon talks to the Golum about stew in French version of
+	// Simon the Sorcerer 1 the code_ptr is at wrong location for
+	// sprite 200. This  was a bug in the original game, which
+	// caused several glitches in this scene.
+	// We work around the problem by correcting the code_ptr for sprite
+	// 200 in this scene, if it is wrong.
+	if (getGameType() == GType_SIMON1 && _language == Common::FR_FRA &&
+		(code_ptr - _vgaBufferPointers[curZoneNum].vgaFile1 == 4) && (cur_sprite == 200) && (curZoneNum == 2))
+		code_ptr += 0x66;
+
+	_lockWord |= 1;
+
+	for (vte = _vgaTimerList; vte->delay; vte++) {
+	}
+
+	vte->delay = num;
+	vte->script_pointer = code_ptr;
+	vte->sprite_id = cur_sprite;
+	vte->cur_vga_file = curZoneNum;
+	vte->param = param;
+
+	_lockWord &= ~1;
+}
+
+void SimonEngine::deleteVgaEvent(VgaTimerEntry * vte) {
+	_lockWord |= 1;
+
+	if (vte + 1 <= _nextVgaTimerToProcess) {
+		_nextVgaTimerToProcess--;
+	}
+
+	do {
+		memcpy(vte, vte + 1, sizeof(VgaTimerEntry));
+		vte++;
+	} while (vte->delay);
+
+	_lockWord &= ~1;
+}
+
+void SimonEngine::processVgaEvents() {
+	VgaTimerEntry *vte = _vgaTimerList;
+	uint timer = (getGameType() == GType_FF) ? 5 : 1;
+
+	_vgaTickCounter++;
+
+	while (vte->delay) {
+		vte->delay -= timer;
+		if (vte->delay <= 0) {
+			uint16 curZoneNum = vte->cur_vga_file;
+			uint16 cur_sprite = vte->sprite_id;
+			const byte *script_ptr = vte->script_pointer;
+			int32 param = vte->param;
+
+			_nextVgaTimerToProcess = vte + 1;
+			deleteVgaEvent(vte);
+
+			if (getGameType() == GType_FF && script_ptr == NULL) {
+				panEvent(curZoneNum, cur_sprite, param);
+			} else if (getGameType() == GType_SIMON2 && script_ptr == NULL) {
+				scrollEvent();
+			} else {
+				animateEvent(script_ptr, curZoneNum, cur_sprite);
+			}
+			vte = _nextVgaTimerToProcess;
+		} else {
+			vte++;
+		}
+	}
+}
+
+void SimonEngine::animateEvent(const byte *code_ptr, uint16 curZoneNum, uint16 cur_sprite) {
+	VgaPointersEntry *vpe;
+
+	_vgaCurSpriteId = cur_sprite;
+
+	_vgaCurZoneNum = curZoneNum;
+	_zoneNumber = curZoneNum;
+	vpe = &_vgaBufferPointers[curZoneNum];
+
+	_curVgaFile1 = vpe->vgaFile1;
+	_curVgaFile2 = vpe->vgaFile2;
+	_curSfxFile = vpe->sfxFile;
+
+	_vcPtr = code_ptr;
+
+	runVgaScript();
+}
+
+void SimonEngine::panEvent(uint16 curZoneNum, uint16 cur_sprite, int32 param) {
+	_vgaCurSpriteId = cur_sprite;
+	_vgaCurZoneNum = curZoneNum;
+
+	VgaSprite *vsp = findCurSprite();
+
+	param &= 0x10;
+
+	int32 pan = (vsp->x - _scrollX + param) * 8 - 2560;
+	if (pan < -10000)
+		pan = -10000;
+	if (pan > 10000)
+		pan = 10000;
+
+	//setSfxPan(param, pan);
+
+	if (pan != 0)
+		addVgaEvent(10, NULL, _vgaCurSpriteId, _vgaCurZoneNum); /* pan event */
+	debug(0, "panEvent: param %d pan %d", param, pan);
+}
+
+void SimonEngine::scrollEvent() {
+	if (_scrollCount == 0)
+		return;
+
+	if (getGameType() == GType_FF) {
+		if (_scrollCount < 0) {
+			if (_scrollFlag != -8) {
+				_scrollFlag = -8;
+				_scrollCount += 8;
+			}
+		} else {
+			if (_scrollFlag != 8) {
+				_scrollFlag = 8;
+				_scrollCount -= 8;
+			}
+		}
+	} else {
+		if (_scrollCount < 0) {
+			if (_scrollFlag != -1) {
+				_scrollFlag = -1;
+				if (++_scrollCount == 0)
+					return;
+			}
+		} else {
+			if (_scrollFlag != 1) {
+				_scrollFlag = 1;
+				if (--_scrollCount == 0)
+					return;
+			}
+		}
+
+		addVgaEvent(6, NULL, 0, 0); /* scroll event */
+	}
+}
+
+} // End of namespace Simon


Property changes on: scummvm/trunk/engines/simon/event.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:eol-style
   + native

Modified: scummvm/trunk/engines/simon/items.cpp
===================================================================
--- scummvm/trunk/engines/simon/items.cpp	2006-04-29 13:17:22 UTC (rev 22220)
+++ scummvm/trunk/engines/simon/items.cpp	2006-04-29 13:38:07 UTC (rev 22221)
@@ -2203,75 +2203,6 @@
 	return getScriptReturn();
 }
 
-int SimonEngine::startSubroutine(Subroutine *sub) {
-	int result = -1;
-	SubroutineLine *sl;
-	const byte *old_code_ptr;
-
-	if (_startMainScript)
-		dumpSubroutine(sub);
-
-	old_code_ptr = _codePtr;
-
-	if (++_recursionDepth > 40)
-		error("Recursion error");
-
-	sl = (SubroutineLine *)((byte *)sub + sub->first);
-
-	while ((byte *)sl != (byte *)sub) {
-		if (checkIfToRunSubroutineLine(sl, sub)) {
-			result = 0;
-			_codePtr = (byte *)sl;
-			if (sub->id)
-				_codePtr += 2;
-			else
-				_codePtr += 8;
-
-			if (_continousMainScript)
-				fprintf(_dumpFile, "; %d\n", sub->id);
-			result = runScript();
-			if (result != 0) {
-				/* result -10 means restart subroutine */
-				if (result == -10) {
-					delay(0);							/* maybe leave control to the VGA */
-					sl = (SubroutineLine *)((byte *)sub + sub->first);
-					continue;
-				}
-				break;
-			}
-		}
-		sl = (SubroutineLine *)((byte *)sub + sl->next);
-	}
-
-	_codePtr = old_code_ptr;
-
-	_recursionDepth--;
-	return result;
-}
-
-int SimonEngine::startSubroutineEx(Subroutine *sub) {
-	return startSubroutine(sub);
-}
-
-bool SimonEngine::checkIfToRunSubroutineLine(SubroutineLine *sl, Subroutine *sub) {
-	if (sub->id)
-		return true;
-
-	if (sl->verb != -1 && sl->verb != _scriptVerb &&
-			(sl->verb != -2 || _scriptVerb != -1))
-		return false;
-
-	if (sl->noun1 != -1 && sl->noun1 != _scriptNoun1 &&
-			(sl->noun1 != -2 || _scriptNoun1 != -1))
-		return false;
-
-	if (sl->noun2 != -1 && sl->noun2 != _scriptNoun2 &&
-			(sl->noun2 != -2 || _scriptNoun2 != -1))
-		return false;
-
-	return true;
-}
-
 void SimonEngine::scriptMouseOn() {
 	if (getGameType() == GType_FF && _mouseCursor != 5) {
 		resetVerbs();

Modified: scummvm/trunk/engines/simon/module.mk
===================================================================
--- scummvm/trunk/engines/simon/module.mk	2006-04-29 13:17:22 UTC (rev 22220)
+++ scummvm/trunk/engines/simon/module.mk	2006-04-29 13:38:07 UTC (rev 22221)
@@ -6,6 +6,7 @@
 	cursor.o \
 	debug.o \
 	debugger.o \
+	event.o \
 	game.o \
 	icons.o \
 	items.o \
@@ -17,8 +18,10 @@
 	simon.o \
 	sound.o \
 	string.o \
+	subroutine.o \
 	verb.o \
 	vga.o \
+	window.o \
 
 MODULE_DIRS += \
 	engines/simon

Modified: scummvm/trunk/engines/simon/simon.cpp
===================================================================
--- scummvm/trunk/engines/simon/simon.cpp	2006-04-29 13:17:22 UTC (rev 22220)
+++ scummvm/trunk/engines/simon/simon.cpp	2006-04-29 13:38:07 UTC (rev 22221)
@@ -649,27 +649,6 @@
 	return org;
 }
 
-void SimonEngine::alignTableMem() {
-	if ((unsigned long)_tablesHeapPtr & 3) {
-		_tablesHeapPtr += 2;
-		_tablesHeapCurPos += 2;
-	}
-}
-
-byte *SimonEngine::allocateTable(uint size) {
-	byte *org = _tablesHeapPtr;
-
-	size = (size + 1) & ~1;
-
-	_tablesHeapPtr += size;
-	_tablesHeapCurPos += size;
-
-	if (_tablesHeapCurPos > _tablesHeapSize)
-		error("Tablesheap overflow");
-
-	return org;
-}
-
 int SimonEngine::allocGamePcVars(File *in) {
 	uint item_array_size, item_array_inited, stringtable_num;
 	uint32 version;
@@ -730,117 +709,6 @@
 	setUserFlag(_currentPlayer, 0, 0);
 }
 
-void SimonEngine::allocateStringTable(int num) {
-	_stringTabPtr = (byte **)calloc(num, sizeof(byte *));
-	_stringTabPos = 0;
-	_stringtab_numalloc = num;
-}
-
-void SimonEngine::setupStringTable(byte *mem, int num) {
-	int i = 0;
-	for (;;) {
-		_stringTabPtr[i++] = mem;
-		if (--num == 0)
-			break;
-		for (; *mem; mem++);
-		mem++;
-	}
-
-	_stringTabPos = i;
-}
-
-void SimonEngine::setupLocalStringTable(byte *mem, int num) {
-	int i = 0;
-	for (;;) {
-		_localStringtable[i++] = mem;
-		if (--num == 0)
-			break;
-		for (; *mem; mem++);
-		mem++;
-	}
-}
-
-void SimonEngine::readSubroutineLine(File *in, SubroutineLine *sl, Subroutine *sub) {
-	byte line_buffer[1024], *q = line_buffer;
-	int size;
-
-	if (sub->id == 0) {
-		sl->verb = in->readUint16BE();
-		sl->noun1 = in->readUint16BE();
-		sl->noun2 = in->readUint16BE();
-	}
-
-	while ((*q = in->readByte()) != 0xFF) {
-		if (*q == 87) {
-			in->readUint16BE();
-		} else {
-			q = readSingleOpcode(in, q);
-		}
-	}
-
-	size = q - line_buffer + 1;
-
-	memcpy(allocateTable(size), line_buffer, size);
-}
-
-SubroutineLine *SimonEngine::createSubroutineLine(Subroutine *sub, int where) {
-	SubroutineLine *sl, *cur_sl = NULL, *last_sl = NULL;
-
-	if (sub->id == 0)
-		sl = (SubroutineLine *)allocateTable(SUBROUTINE_LINE_BIG_SIZE);
-	else
-		sl = (SubroutineLine *)allocateTable(SUBROUTINE_LINE_SMALL_SIZE);
-
-	// where is what offset to insert the line at, locate the proper beginning line
-	if (sub->first != 0) {
-		cur_sl = (SubroutineLine *)((byte *)sub + sub->first);
-		while (where) {
-			last_sl = cur_sl;
-			cur_sl = (SubroutineLine *)((byte *)sub + cur_sl->next);
-			if ((byte *)cur_sl == (byte *)sub)
-				break;
-			where--;
-		}
-	}
-
-	if (last_sl != NULL) {
-		// Insert the subroutine line in the middle of the link
-		last_sl->next = (byte *)sl - (byte *)sub;
-		sl->next = (byte *)cur_sl - (byte *)sub;
-	} else {
-		// Insert the subroutine line at the head of the link
-		sl->next = sub->first;
-		sub->first = (byte *)sl - (byte *)sub;
-	}
-
-	return sl;
-}
-
-void SimonEngine::readSubroutine(File *in, Subroutine *sub) {
-	while (in->readUint16BE() == 0) {
-		readSubroutineLine(in, createSubroutineLine(sub, 0xFFFF), sub);
-	}
-}
-
-Subroutine *SimonEngine::createSubroutine(uint id) {
-	Subroutine *sub;
-
-	alignTableMem();
-
-	sub = (Subroutine *)allocateTable(sizeof(Subroutine));
-	sub->id = id;
-	sub->first = 0;
-	sub->next = _subroutineList;
-	_subroutineList = sub;
-	return sub;
-}
-
-void SimonEngine::readSubroutineBlock(File *in) {
-	while (in->readUint16BE() == 0) {
-		readSubroutine(in, createSubroutine(in->readUint16BE()));
-	}
-}
-
 Child *SimonEngine::findChildOfType(Item *i, uint type) {
 	Child *child = i->children;
 	for (; child; child = child->next)
@@ -1108,141 +976,6 @@
 	}
 }
 
-const byte *SimonEngine::getStringPtrByID(uint stringId) {
-	const byte *string_ptr;
-	byte *dst;
-
-	_freeStringSlot ^= 1;
-
-	if (stringId < 0x8000) {
-		string_ptr = _stringTabPtr[stringId];
-	} else {
-		string_ptr = getLocalStringByID(stringId);
-	}
-
-	dst = _stringReturnBuffer[_freeStringSlot];
-	strcpy((char *)dst, (const char *)string_ptr);
-	return dst;
-}
-
-const byte *SimonEngine::getLocalStringByID(uint stringId) {
-	if (stringId < _stringIdLocalMin || stringId >= _stringIdLocalMax) {
-		loadTextIntoMem(stringId);
-	}
-	return _localStringtable[stringId - _stringIdLocalMin];
-}
-
-void SimonEngine::loadTextIntoMem(uint stringId) {
-	byte *p;
-	char filename[30];
-	int i;
-	uint base_min = 0x8000, base_max, size;
-
-	_tablesHeapPtr = _tablesheapPtrNew;
-	_tablesHeapCurPos = _tablesHeapCurPosNew;
-
-	p = _strippedTxtMem;
-
-	// get filename
-	while (*p) {
-		for (i = 0; *p; p++, i++)
-			filename[i] = *p;
-		filename[i] = 0;
-		p++;
-
-		base_max = (p[0] * 256) | p[1];
-		p += 2;
-
-		if (stringId < base_max) {
-			_stringIdLocalMin = base_min;
-			_stringIdLocalMax = base_max;
-
-			_localStringtable = (byte **)_tablesHeapPtr;
-
-			size = (base_max - base_min + 1) * sizeof(byte *);
-			_tablesHeapPtr += size;
-			_tablesHeapCurPos += size;
-
-			size = loadTextFile(filename, _tablesHeapPtr);
-
-			setupLocalStringTable(_tablesHeapPtr, base_max - base_min + 1);
-
-			_tablesHeapPtr += size;
-			_tablesHeapCurPos += size;
-
-			if (_tablesHeapCurPos > _tablesHeapSize) {
-				error("loadTextIntoMem: Out of table memory");
-			}
-			return;
-		}
-
-		base_min = base_max;
-	}
-
-	error("loadTextIntoMem: didn't find %d", stringId);
-}
-
-void SimonEngine::loadTablesIntoMem(uint subr_id) {
-	byte *p;
-	int i;
-	uint min_num, max_num;
-	char filename[30];
-	File *in;
-
-	p = _tblList;
-	if (p == NULL)
-		return;
-
-	while (*p) {
-		for (i = 0; *p; p++, i++)
-			filename[i] = *p;
-		filename[i] = 0;
-		p++;
-
-		for (;;) {
-			min_num = (p[0] * 256) | p[1];
-			p += 2;
-
-			if (min_num == 0)
-				break;
-
-			max_num = (p[0] * 256) | p[1];
-			p += 2;
-
-			if (subr_id >= min_num && subr_id <= max_num) {
-				_subroutineList = _subroutineListOrg;
-				_tablesHeapPtr = _tablesHeapPtrOrg;
-				_tablesHeapCurPos = _tablesHeapCurPosOrg;
-				_stringIdLocalMin = 1;
-				_stringIdLocalMax = 0;
-
-				in = openTablesFile(filename);
-				readSubroutineBlock(in);
-				closeTablesFile(in);
-				if (getGameType() == GType_FF) {
-					// TODO
-				} else if (getGameType() == GType_SIMON2) {
-					_sound->loadSfxTable(_gameFile, _gameOffsetsPtr[atoi(filename + 6) - 1 + SOUND_INDEX_BASE]);
-				} else if (getPlatform() == Common::kPlatformWindows) {
-					memcpy(filename, "SFXXXX", 6);
-					_sound->readSfxFile(filename);
-				}
-
-				alignTableMem();
-
-				_tablesheapPtrNew = _tablesHeapPtr;
-				_tablesHeapCurPosNew = _tablesHeapCurPos;
-
-				if (_tablesHeapCurPos > _tablesHeapSize)
-					error("loadTablesIntoMem: Out of table memory");
-				return;
-			}
-		}
-	}
-
-	debug(1,"loadTablesIntoMem: didn't find %d", subr_id);
-}
-
 void SimonEngine::playSting(uint a) {
 	if (!midi._enable_sfx)
 		return;
@@ -1269,212 +1002,6 @@
 	midi.startTrack(0);
 }
 
-Subroutine *SimonEngine::getSubroutineByID(uint subroutine_id) {
-	Subroutine *cur;
-
-	_subroutine = subroutine_id;
-
-	for (cur = _subroutineList; cur; cur = cur->next) {
-		if (cur->id == subroutine_id)
-			return cur;
-	}
-
-	loadTablesIntoMem(subroutine_id);
-
-	for (cur = _subroutineList; cur; cur = cur->next) {
-		if (cur->id == subroutine_id)
-			return cur;
-	}
-
-	if (subroutine_id != 160)
-		debug(0,"getSubroutineByID: subroutine %d not found", subroutine_id);
-	return NULL;
-}
-
-uint SimonEngine::loadTextFile_gme(const char *filename, byte *dst) {
-	uint res;
-	uint32 offs;
-	uint32 size;
-
-	res = atoi(filename + 4) + TEXT_INDEX_BASE - 1;
-	offs = _gameOffsetsPtr[res];
-	size = _gameOffsetsPtr[res + 1] - offs;
-
-	readGameFile(dst, offs, size);
-
-	return size;
-}
-
-File *SimonEngine::openTablesFile_gme(const char *filename) {
-	uint res;
-	uint32 offs;
-
-	res = atoi(filename + 6) + TABLE_INDEX_BASE - 1;
-	offs = _gameOffsetsPtr[res];
-
-	_gameFile->seek(offs, SEEK_SET);
-	return _gameFile;
-}
-
-uint SimonEngine::loadTextFile_simon1(const char *filename, byte *dst) {
-	File fo;
-	fo.open(filename);
-	uint32 size;
-
-	if (fo.isOpen() == false)
-		error("loadTextFile: Can't open '%s'", filename);
-
-	size = fo.size();
-
-	if (fo.read(dst, size) != size)
-		error("loadTextFile: fread failed");
-	fo.close();
-
-	return size;
-}
-
-File *SimonEngine::openTablesFile_simon1(const char *filename) {
-	File *fo = new File();
-	fo->open(filename);
-	if (fo->isOpen() == false)
-		error("openTablesFile: Can't open '%s'", filename);
-	return fo;
-}
-
-uint SimonEngine::loadTextFile(const char *filename, byte *dst) {
-	if (getFeatures() & GF_OLD_BUNDLE)
-		return loadTextFile_simon1(filename, dst);
-	else
-		return loadTextFile_gme(filename, dst);
-}
-
-File *SimonEngine::openTablesFile(const char *filename) {
-	if (getFeatures() & GF_OLD_BUNDLE)
-		return openTablesFile_simon1(filename);
-	else
-		return openTablesFile_gme(filename);
-}
-
-void SimonEngine::closeTablesFile(File *in) {
-	if (getFeatures() & GF_OLD_BUNDLE) {
-		in->close();
-		delete in;
-	}
-}
-
-void SimonEngine::addTimeEvent(uint timeout, uint subroutine_id) {
-	TimeEvent *te = (TimeEvent *)malloc(sizeof(TimeEvent)), *first, *last = NULL;
-	time_t cur_time;
-
-	time(&cur_time);
-
-	te->time = cur_time + timeout - _gameStoppedClock;
-	if (_clockStopped)
-		te->time -= ((uint32)time(NULL) - _clockStopped);
-	te->subroutine_id = subroutine_id;
-
-	first = _firstTimeStruct;
-	while (first) {
-		if (te->time <= first->time) {
-			if (last) {
-				last->next = te;
-				te->next = first;
-				return;
-			}
-			te->next = _firstTimeStruct;
-			_firstTimeStruct = te;
-			return;
-		}
-
-		last = first;
-		first = first->next;
-	}
-
-	if (last) {
-		last->next = te;
-		te->next = NULL;
-	} else {
-		_firstTimeStruct = te;
-		te->next = NULL;
-	}
-}
-
-void SimonEngine::delTimeEvent(TimeEvent *te) {
-	TimeEvent *cur;
-
-	if (te == _pendingDeleteTimeEvent)
-		_pendingDeleteTimeEvent = NULL;
-
-	if (te == _firstTimeStruct) {
-		_firstTimeStruct = te->next;
-		free(te);
-		return;
-	}
-
-	cur = _firstTimeStruct;
-	if (cur == NULL)
-		error("delTimeEvent: none available");
-
-	for (;;) {
-		if (cur->next == NULL)
-			error("delTimeEvent: no such te");
-		if (te == cur->next) {
-			cur->next = te->next;
-			free(te);
-			return;
-		}
-		cur = cur->next;
-	}
-}
-
-void SimonEngine::killAllTimers() {
-	TimeEvent *cur, *next;
-
-	for (cur = _firstTimeStruct; cur; cur = next) {
-		next = cur->next;
-		delTimeEvent(cur);
-	}
-}
-
-bool SimonEngine::kickoffTimeEvents() {
-	time_t cur_time;
-	TimeEvent *te;
-	bool result = false;
-
-	if (_clockStopped)
-		return result;
-
-	time(&cur_time);
-	cur_time -= _gameStoppedClock;
-
-	while ((te = _firstTimeStruct) != NULL && te->time <= (uint32)cur_time) {
-		result = true;
-		_pendingDeleteTimeEvent = te;
-		invokeTimeEvent(te);
-		if (_pendingDeleteTimeEvent) {
-			_pendingDeleteTimeEvent = NULL;
-			delTimeEvent(te);
-		}
-	}
-
-	return result;
-}
-
-void SimonEngine::invokeTimeEvent(TimeEvent *te) {
-	Subroutine *sub;
-
-	_scriptVerb = 0;
-
-	if (_runScriptReturn1)
-		return;
-
-	sub = getSubroutineByID(te->subroutine_id);
-	if (sub != NULL)
-		startSubroutineEx(sub);
-
-	_runScriptReturn1 = false;
-}
-
 void SimonEngine::setup_cond_c_helper() {
 	HitArea *last;
 	uint id;
@@ -1600,17 +1127,6 @@
 	_runScriptReturn1 = true;
 }
 
-uint SimonEngine::getWindowNum(WindowBlock *window) {
-	uint i;
-
-	for (i = 0; i != ARRAYSIZE(_windowArray); i++)
-		if (_windowArray[i] == window)
-			return i;
-
-	error("getWindowNum: not found");
-	return 0;
-}
-
 void SimonEngine::mouseOff() {
 	_mouseHideCount++;
 }
@@ -2337,153 +1853,6 @@
 	}
 }
 
-void SimonEngine::addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum, int32 param) {
-	VgaTimerEntry *vte;
-
-	// When Simon talks to the Golum about stew in French version of
-	// Simon the Sorcerer 1 the code_ptr is at wrong location for
-	// sprite 200. This  was a bug in the original game, which
-	// caused several glitches in this scene.
-	// We work around the problem by correcting the code_ptr for sprite
-	// 200 in this scene, if it is wrong.
-	if (getGameType() == GType_SIMON1 && _language == Common::FR_FRA &&
-		(code_ptr - _vgaBufferPointers[curZoneNum].vgaFile1 == 4) && (cur_sprite == 200) && (curZoneNum == 2))
-		code_ptr += 0x66;
-
-	_lockWord |= 1;
-
-	for (vte = _vgaTimerList; vte->delay; vte++) {
-	}
-
-	vte->delay = num;
-	vte->script_pointer = code_ptr;
-	vte->sprite_id = cur_sprite;
-	vte->cur_vga_file = curZoneNum;
-	vte->param = param;
-
-	_lockWord &= ~1;
-}
-
-void SimonEngine::deleteVgaEvent(VgaTimerEntry * vte) {
-	_lockWord |= 1;
-
-	if (vte + 1 <= _nextVgaTimerToProcess) {
-		_nextVgaTimerToProcess--;
-	}
-
-	do {
-		memcpy(vte, vte + 1, sizeof(VgaTimerEntry));
-		vte++;
-	} while (vte->delay);
-
-	_lockWord &= ~1;
-}
-
-void SimonEngine::processVgaEvents() {
-	VgaTimerEntry *vte = _vgaTimerList;
-	uint timer = (getGameType() == GType_FF) ? 5 : 1;
-
-	_vgaTickCounter++;
-
-	while (vte->delay) {
-		vte->delay -= timer;
-		if (vte->delay <= 0) {
-			uint16 curZoneNum = vte->cur_vga_file;
-			uint16 cur_sprite = vte->sprite_id;
-			const byte *script_ptr = vte->script_pointer;
-			int32 param = vte->param;
-
-			_nextVgaTimerToProcess = vte + 1;
-			deleteVgaEvent(vte);
-
-			if (getGameType() == GType_FF && script_ptr == NULL) {
-				panEvent(curZoneNum, cur_sprite, param);
-			} else if (getGameType() == GType_SIMON2 && script_ptr == NULL) {
-				scrollEvent();
-			} else {
-				animateEvent(script_ptr, curZoneNum, cur_sprite);
-			}
-			vte = _nextVgaTimerToProcess;
-		} else {
-			vte++;
-		}
-	}
-}
-
-void SimonEngine::animateEvent(const byte *code_ptr, uint16 curZoneNum, uint16 cur_sprite) {
-	VgaPointersEntry *vpe;
-
-	_vgaCurSpriteId = cur_sprite;
-
-	_vgaCurZoneNum = curZoneNum;
-	_zoneNumber = curZoneNum;
-	vpe = &_vgaBufferPointers[curZoneNum];
-
-	_curVgaFile1 = vpe->vgaFile1;
-	_curVgaFile2 = vpe->vgaFile2;
-	_curSfxFile = vpe->sfxFile;
-
-	_vcPtr = code_ptr;
-
-	runVgaScript();
-}
-
-void SimonEngine::panEvent(uint16 curZoneNum, uint16 cur_sprite, int32 param) {
-	_vgaCurSpriteId = cur_sprite;
-	_vgaCurZoneNum = curZoneNum;
-
-	VgaSprite *vsp = findCurSprite();
-
-	param &= 0x10;
-
-	int32 pan = (vsp->x - _scrollX + param) * 8 - 2560;
-	if (pan < -10000)
-		pan = -10000;
-	if (pan > 10000)
-		pan = 10000;
-
-	//setSfxPan(param, pan);
-
-	if (pan != 0)
-		addVgaEvent(10, NULL, _vgaCurSpriteId, _vgaCurZoneNum); /* pan event */
-	debug(0, "panEvent: param %d pan %d", param, pan);
-}
-
-void SimonEngine::scrollEvent() {
-	if (_scrollCount == 0)
-		return;
-
-	if (getGameType() == GType_FF) {
-		if (_scrollCount < 0) {
-			if (_scrollFlag != -8) {
-				_scrollFlag = -8;
-				_scrollCount += 8;
-			}
-		} else {
-			if (_scrollFlag != 8) {
-				_scrollFlag = 8;
-				_scrollCount -= 8;
-			}
-		}
-	} else {
-		if (_scrollCount < 0) {
-			if (_scrollFlag != -1) {
-				_scrollFlag = -1;
-				if (++_scrollCount == 0)
-					return;
-			}
-		} else {
-			if (_scrollFlag != 1) {
-				_scrollFlag = 1;
-				if (--_scrollCount == 0)
-					return;
-			}
-		}
-
-		addVgaEvent(6, NULL, 0, 0); /* scroll event */
-	}
-}
-
 void SimonEngine::waitForSync(uint a) {
 	const uint maxCount = (getGameType() == GType_SIMON1) ? 500 : 1000;
 
@@ -2842,57 +2211,6 @@
 	}
 }
 
-void SimonEngine::closeWindow(uint a) {
-	if (_windowArray[a] == NULL)
-		return;
-	removeIconArray(a);
-	resetWindow(_windowArray[a]);
-	_windowArray[a] = NULL;
-	if (_curWindow == a) {
-		_textWindow = NULL;
-		changeWindow(0);
-	}
-}
-
-void SimonEngine::changeWindow(uint a) {
-	a &= 7;
-
-	if (_windowArray[a] == NULL || _curWindow == a)
-		return;
-
-	_curWindow = a;
-	showmessage_print_char(0);
-	_textWindow = _windowArray[a];
-
-	if (getGameType() == GType_FF)
-		showmessage_helper_3(_textWindow->textColumn, _textWindow->width);
-	else
-		showmessage_helper_3(_textWindow->textLength, _textWindow->textMaxLength);
-}
-
-WindowBlock *SimonEngine::openWindow(uint x, uint y, uint w, uint h, uint flags, uint fill_color, uint text_color) {
-	WindowBlock *window;
-
-	window = _windowList;
-	while (window->mode != 0)
-		window++;
-
-	window->mode = 2;
-	window->x = x;
-	window->y = y;
-	window->width = w;
-	window->height = h;
-	window->flags = flags;
-	window->fill_color = fill_color;
-	window->text_color = text_color;
-	window->textColumn = 0;
-	window->textRow = 0;
-	window->textColumnOffset = 0;
-	window->textMaxLength = window->width * 8 / 6; // characters are 6 pixels
-	window->scrollY = 0;
-	return window;
-}
-
 Item *SimonEngine::derefItem(uint item) {
 	if (item >= _itemArraySize)
 		error("derefItem: invalid item %d", item);
@@ -2913,73 +2231,6 @@
 	_hitAreas[index].flags = 0;
 }
 
-void SimonEngine::windowPutChar(uint a) {
-	if (_textWindow != _windowArray[0])
-		windowPutChar(_textWindow, a);
-}
-
-void SimonEngine::clearWindow(WindowBlock *window) {
-	if (window->flags & 0x10)
-		restoreWindow(window);
-	else
-		colorWindow(window);
-
-	window->textColumn = 0;
-	window->textRow = 0;
-	window->textColumnOffset = 0;
-	window->textLength = 0;
-	window->scrollY = 0;
-}
-
-void SimonEngine::restoreWindow(WindowBlock *window) {
-	_lockWord |= 0x8000;
-
-	if (getGameType() == GType_FF) {
-		restoreBlock(window->y + window->height, window->x + window->width, window->y, window->x);
-	} else if (getGameType() == GType_SIMON2) {
-		if (_restoreWindow6 && _windowArray[2] == window) {
-			window = _windowArray[6];
-			_restoreWindow6 = 0;
-		}
-
-		restoreBlock(window->y + window->height * 8, (window->x + window->width) * 8, window->y, window->x * 8);
-	} else {
-		restoreBlock(window->y + window->height * 8 + ((window == _windowArray[2]) ? 1 : 0), (window->x + window->width) * 8, window->y, window->x * 8);
-	}
-
-	_lockWord &= ~0x8000;
-}
-
-void SimonEngine::colorWindow(WindowBlock *window) {
-	byte *dst;
-	uint h, w;
-
-	_lockWord |= 0x8000;
-
-	if (getGameType() == GType_FF) {
-		dst = getFrontBuf() + _dxSurfacePitch * window->y + window->x;
-
-		for (h = 0; h < window->height; h++) {
-			for (w = 0; w < window->width; w++) {
-				if (dst[w] == 113  || dst[w] == 116 || dst[w] == 252)
-					dst[w] = window->fill_color;
-			}
-			dst += _screenWidth;
-		}
-	} else {
-		dst = getFrontBuf() + _dxSurfacePitch * window->y + window->x * 8;
-		h = window->height * 8;
-		w = window->width * 8;
-
-		do {
-			memset(dst, window->fill_color, w);
-			dst += _dxSurfacePitch;
-		} while (--h);
-	}
-
-	_lockWord &= ~0x8000;
-}
-
 VgaSprite *SimonEngine::findCurSprite() {
 	VgaSprite *vsp = _vgaSprites;
 	while (vsp->id) {
@@ -3167,12 +2418,6 @@
 	_lockWord &= ~0x8000;
 }
 
-void SimonEngine::resetWindow(WindowBlock *window) {
-	if (window->flags & 8)
-		restoreWindow(window);
-	window->mode = 0;
-}
-
 void SimonEngine::loadSprite(uint windowNum, uint zoneNum, uint vgaSpriteId, uint x, uint y, uint palette) {
 	VgaSprite *vsp;
 	VgaPointersEntry *vpe;

Modified: scummvm/trunk/engines/simon/string.cpp
===================================================================
--- scummvm/trunk/engines/simon/string.cpp	2006-04-29 13:17:22 UTC (rev 22220)
+++ scummvm/trunk/engines/simon/string.cpp	2006-04-29 13:38:07 UTC (rev 22221)
@@ -25,8 +25,152 @@
 #include "simon/simon.h"
 #include "simon/intern.h"
 
+using Common::File;
+
 namespace Simon {
 
+const byte *SimonEngine::getStringPtrByID(uint stringId) {
+	const byte *string_ptr;
+	byte *dst;
+
+	_freeStringSlot ^= 1;
+
+	if (stringId < 0x8000) {
+		string_ptr = _stringTabPtr[stringId];
+	} else {
+		string_ptr = getLocalStringByID(stringId);
+	}
+
+	dst = _stringReturnBuffer[_freeStringSlot];
+	strcpy((char *)dst, (const char *)string_ptr);
+	return dst;
+}
+
+const byte *SimonEngine::getLocalStringByID(uint stringId) {
+	if (stringId < _stringIdLocalMin || stringId >= _stringIdLocalMax) {
+		loadTextIntoMem(stringId);
+	}
+	return _localStringtable[stringId - _stringIdLocalMin];
+}
+
+void SimonEngine::allocateStringTable(int num) {
+	_stringTabPtr = (byte **)calloc(num, sizeof(byte *));
+	_stringTabPos = 0;
+	_stringtab_numalloc = num;
+}
+
+void SimonEngine::setupStringTable(byte *mem, int num) {
+	int i = 0;
+	for (;;) {
+		_stringTabPtr[i++] = mem;
+		if (--num == 0)
+			break;
+		for (; *mem; mem++);
+		mem++;
+	}
+
+	_stringTabPos = i;
+}
+
+void SimonEngine::setupLocalStringTable(byte *mem, int num) {
+	int i = 0;
+	for (;;) {
+		_localStringtable[i++] = mem;
+		if (--num == 0)
+			break;
+		for (; *mem; mem++);
+		mem++;
+	}
+}
+
+uint SimonEngine::loadTextFile(const char *filename, byte *dst) {
+	if (getFeatures() & GF_OLD_BUNDLE)
+		return loadTextFile_simon1(filename, dst);
+	else
+		return loadTextFile_gme(filename, dst);
+}
+
+uint SimonEngine::loadTextFile_simon1(const char *filename, byte *dst) {
+	File fo;
+	fo.open(filename);
+	uint32 size;
+
+	if (fo.isOpen() == false)
+		error("loadTextFile: Can't open '%s'", filename);
+
+	size = fo.size();
+
+	if (fo.read(dst, size) != size)
+		error("loadTextFile: fread failed");
+	fo.close();
+
+	return size;
+}
+
+uint SimonEngine::loadTextFile_gme(const char *filename, byte *dst) {
+	uint res;
+	uint32 offs;
+	uint32 size;
+
+	res = atoi(filename + 4) + TEXT_INDEX_BASE - 1;
+	offs = _gameOffsetsPtr[res];
+	size = _gameOffsetsPtr[res + 1] - offs;
+
+	readGameFile(dst, offs, size);
+
+	return size;
+}
+
+void SimonEngine::loadTextIntoMem(uint stringId) {
+	byte *p;
+	char filename[30];
+	int i;
+	uint base_min = 0x8000, base_max, size;
+
+	_tablesHeapPtr = _tablesheapPtrNew;
+	_tablesHeapCurPos = _tablesHeapCurPosNew;
+
+	p = _strippedTxtMem;
+
+	// get filename
+	while (*p) {
+		for (i = 0; *p; p++, i++)
+			filename[i] = *p;
+		filename[i] = 0;
+		p++;
+
+		base_max = (p[0] * 256) | p[1];
+		p += 2;
+
+		if (stringId < base_max) {
+			_stringIdLocalMin = base_min;
+			_stringIdLocalMax = base_max;
+
+			_localStringtable = (byte **)_tablesHeapPtr;
+
+			size = (base_max - base_min + 1) * sizeof(byte *);
+			_tablesHeapPtr += size;
+			_tablesHeapCurPos += size;
+
+			size = loadTextFile(filename, _tablesHeapPtr);
+
+			setupLocalStringTable(_tablesHeapPtr, base_max - base_min + 1);
+
+			_tablesHeapPtr += size;
+			_tablesHeapCurPos += size;
+
+			if (_tablesHeapCurPos > _tablesHeapSize) {
+				error("loadTextIntoMem: Out of table memory");
+			}
+			return;
+		}
+
+		base_min = base_max;
+	}
+
+	error("loadTextIntoMem: didn't find %d", stringId);
+}
+
 static const byte charWidth[226] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

Added: scummvm/trunk/engines/simon/subroutine.cpp
===================================================================
--- scummvm/trunk/engines/simon/subroutine.cpp	                        (rev 0)
+++ scummvm/trunk/engines/simon/subroutine.cpp	2006-04-29 13:38:07 UTC (rev 22221)
@@ -0,0 +1,319 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "simon/simon.h"
+#include "simon/intern.h"
+
+using Common::File;
+
+namespace Simon {
+
+Subroutine *SimonEngine::getSubroutineByID(uint subroutine_id) {
+	Subroutine *cur;
+
+	_subroutine = subroutine_id;
+
+	for (cur = _subroutineList; cur; cur = cur->next) {
+		if (cur->id == subroutine_id)
+			return cur;
+	}
+
+	loadTablesIntoMem(subroutine_id);
+
+	for (cur = _subroutineList; cur; cur = cur->next) {
+		if (cur->id == subroutine_id)
+			return cur;
+	}
+
+	if (subroutine_id != 160)
+		debug(0,"getSubroutineByID: subroutine %d not found", subroutine_id);
+	return NULL;
+}
+
+void SimonEngine::alignTableMem() {
+	if ((unsigned long)_tablesHeapPtr & 3) {
+		_tablesHeapPtr += 2;
+		_tablesHeapCurPos += 2;
+	}
+}
+
+byte *SimonEngine::allocateTable(uint size) {
+	byte *org = _tablesHeapPtr;
+
+	size = (size + 1) & ~1;
+
+	_tablesHeapPtr += size;
+	_tablesHeapCurPos += size;
+
+	if (_tablesHeapCurPos > _tablesHeapSize)
+		error("Tablesheap overflow");
+
+	return org;
+}
+
+File *SimonEngine::openTablesFile(const char *filename) {
+	if (getFeatures() & GF_OLD_BUNDLE)
+		return openTablesFile_simon1(filename);
+	else
+		return openTablesFile_gme(filename);
+}
+
+File *SimonEngine::openTablesFile_simon1(const char *filename) {
+	File *fo = new File();
+	fo->open(filename);
+	if (fo->isOpen() == false)
+		error("openTablesFile: Can't open '%s'", filename);
+	return fo;
+}
+
+File *SimonEngine::openTablesFile_gme(const char *filename) {
+	uint res;
+	uint32 offs;
+
+	res = atoi(filename + 6) + TABLE_INDEX_BASE - 1;
+	offs = _gameOffsetsPtr[res];
+
+	_gameFile->seek(offs, SEEK_SET);
+	return _gameFile;
+}
+
+void SimonEngine::loadTablesIntoMem(uint subr_id) {
+	byte *p;
+	int i;
+	uint min_num, max_num;
+	char filename[30];
+	File *in;
+
+	p = _tblList;
+	if (p == NULL)
+		return;
+
+	while (*p) {
+		for (i = 0; *p; p++, i++)
+			filename[i] = *p;
+		filename[i] = 0;
+		p++;
+
+		for (;;) {
+			min_num = (p[0] * 256) | p[1];
+			p += 2;
+
+			if (min_num == 0)
+				break;
+
+			max_num = (p[0] * 256) | p[1];
+			p += 2;
+
+			if (subr_id >= min_num && subr_id <= max_num) {
+				_subroutineList = _subroutineListOrg;
+				_tablesHeapPtr = _tablesHeapPtrOrg;
+				_tablesHeapCurPos = _tablesHeapCurPosOrg;
+				_stringIdLocalMin = 1;
+				_stringIdLocalMax = 0;
+
+				in = openTablesFile(filename);
+				readSubroutineBlock(in);
+				closeTablesFile(in);
+				if (getGameType() == GType_FF) {
+					// TODO
+				} else if (getGameType() == GType_SIMON2) {
+					_sound->loadSfxTable(_gameFile, _gameOffsetsPtr[atoi(filename + 6) - 1 + SOUND_INDEX_BASE]);
+				} else if (getPlatform() == Common::kPlatformWindows) {
+					memcpy(filename, "SFXXXX", 6);
+					_sound->readSfxFile(filename);
+				}
+
+				alignTableMem();
+
+				_tablesheapPtrNew = _tablesHeapPtr;
+				_tablesHeapCurPosNew = _tablesHeapCurPos;
+
+				if (_tablesHeapCurPos > _tablesHeapSize)
+					error("loadTablesIntoMem: Out of table memory");
+				return;
+			}
+		}
+	}
+
+	debug(1,"loadTablesIntoMem: didn't find %d", subr_id);
+}
+
+void SimonEngine::closeTablesFile(File *in) {
+	if (getFeatures() & GF_OLD_BUNDLE) {
+		in->close();
+		delete in;
+	}
+}
+
+Subroutine *SimonEngine::createSubroutine(uint id) {
+	Subroutine *sub;
+
+	alignTableMem();
+
+	sub = (Subroutine *)allocateTable(sizeof(Subroutine));
+	sub->id = id;
+	sub->first = 0;
+	sub->next = _subroutineList;
+	_subroutineList = sub;
+	return sub;
+}
+
+SubroutineLine *SimonEngine::createSubroutineLine(Subroutine *sub, int where) {
+	SubroutineLine *sl, *cur_sl = NULL, *last_sl = NULL;
+
+	if (sub->id == 0)
+		sl = (SubroutineLine *)allocateTable(SUBROUTINE_LINE_BIG_SIZE);
+	else
+		sl = (SubroutineLine *)allocateTable(SUBROUTINE_LINE_SMALL_SIZE);
+
+	// where is what offset to insert the line at, locate the proper beginning line
+	if (sub->first != 0) {
+		cur_sl = (SubroutineLine *)((byte *)sub + sub->first);
+		while (where) {
+			last_sl = cur_sl;
+			cur_sl = (SubroutineLine *)((byte *)sub + cur_sl->next);
+			if ((byte *)cur_sl == (byte *)sub)
+				break;
+			where--;
+		}
+	}
+
+	if (last_sl != NULL) {
+		// Insert the subroutine line in the middle of the link
+		last_sl->next = (byte *)sl - (byte *)sub;
+		sl->next = (byte *)cur_sl - (byte *)sub;
+	} else {
+		// Insert the subroutine line at the head of the link
+		sl->next = sub->first;
+		sub->first = (byte *)sl - (byte *)sub;
+	}
+
+	return sl;
+}
+
+int SimonEngine::startSubroutine(Subroutine *sub) {
+	int result = -1;
+	SubroutineLine *sl;
+	const byte *old_code_ptr;
+
+	if (_startMainScript)
+		dumpSubroutine(sub);
+
+	old_code_ptr = _codePtr;
+
+	if (++_recursionDepth > 40)
+		error("Recursion error");
+
+	sl = (SubroutineLine *)((byte *)sub + sub->first);
+
+	while ((byte *)sl != (byte *)sub) {
+		if (checkIfToRunSubroutineLine(sl, sub)) {
+			result = 0;
+			_codePtr = (byte *)sl;
+			if (sub->id)
+				_codePtr += 2;
+			else
+				_codePtr += 8;
+
+			if (_continousMainScript)
+				fprintf(_dumpFile, "; %d\n", sub->id);
+			result = runScript();
+			if (result != 0) {
+				/* result -10 means restart subroutine */
+				if (result == -10) {
+					delay(0);							/* maybe leave control to the VGA */
+					sl = (SubroutineLine *)((byte *)sub + sub->first);
+					continue;
+				}
+				break;
+			}
+		}
+		sl = (SubroutineLine *)((byte *)sub + sl->next);
+	}
+
+	_codePtr = old_code_ptr;
+
+	_recursionDepth--;
+	return result;
+}
+
+int SimonEngine::startSubroutineEx(Subroutine *sub) {
+	return startSubroutine(sub);
+}
+
+bool SimonEngine::checkIfToRunSubroutineLine(SubroutineLine *sl, Subroutine *sub) {
+	if (sub->id)
+		return true;
+
+	if (sl->verb != -1 && sl->verb != _scriptVerb &&
+			(sl->verb != -2 || _scriptVerb != -1))
+		return false;
+
+	if (sl->noun1 != -1 && sl->noun1 != _scriptNoun1 &&
+			(sl->noun1 != -2 || _scriptNoun1 != -1))
+		return false;
+
+	if (sl->noun2 != -1 && sl->noun2 != _scriptNoun2 &&
+			(sl->noun2 != -2 || _scriptNoun2 != -1))
+		return false;
+
+	return true;
+}
+
+void SimonEngine::readSubroutine(File *in, Subroutine *sub) {
+	while (in->readUint16BE() == 0) {
+		readSubroutineLine(in, createSubroutineLine(sub, 0xFFFF), sub);
+	}
+}
+
+void SimonEngine::readSubroutineLine(File *in, SubroutineLine *sl, Subroutine *sub) {
+	byte line_buffer[1024], *q = line_buffer;
+	int size;
+
+	if (sub->id == 0) {
+		sl->verb = in->readUint16BE();
+		sl->noun1 = in->readUint16BE();
+		sl->noun2 = in->readUint16BE();
+	}
+
+	while ((*q = in->readByte()) != 0xFF) {
+		if (*q == 87) {
+			in->readUint16BE();
+		} else {
+			q = readSingleOpcode(in, q);
+		}
+	}
+
+	size = q - line_buffer + 1;
+
+	memcpy(allocateTable(size), line_buffer, size);
+}
+
+void SimonEngine::readSubroutineBlock(File *in) {
+	while (in->readUint16BE() == 0) {
+		readSubroutine(in, createSubroutine(in->readUint16BE()));
+	}
+}
+
+} // End of namespace Simon


Property changes on: scummvm/trunk/engines/simon/subroutine.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/simon/window.cpp
===================================================================
--- scummvm/trunk/engines/simon/window.cpp	                        (rev 0)
+++ scummvm/trunk/engines/simon/window.cpp	2006-04-29 13:38:07 UTC (rev 22221)
@@ -0,0 +1,165 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/simon/string.cpp $
+ * $Id: string.cpp 22062 2006-04-21 00:18:23Z kirben $
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "simon/simon.h"
+#include "simon/intern.h"
+
+namespace Simon {
+
+uint SimonEngine::getWindowNum(WindowBlock *window) {
+	uint i;
+
+	for (i = 0; i != ARRAYSIZE(_windowArray); i++)
+		if (_windowArray[i] == window)
+			return i;
+
+	error("getWindowNum: not found");
+	return 0;
+}
+
+WindowBlock *SimonEngine::openWindow(uint x, uint y, uint w, uint h, uint flags, uint fill_color, uint text_color) {
+	WindowBlock *window;
+
+	window = _windowList;
+	while (window->mode != 0)
+		window++;
+
+	window->mode = 2;
+	window->x = x;
+	window->y = y;
+	window->width = w;
+	window->height = h;
+	window->flags = flags;
+	window->fill_color = fill_color;
+	window->text_color = text_color;
+	window->textColumn = 0;
+	window->textRow = 0;
+	window->textColumnOffset = 0;
+	window->textMaxLength = window->width * 8 / 6; // characters are 6 pixels
+	window->scrollY = 0;
+	return window;
+}
+
+void SimonEngine::changeWindow(uint a) {
+	a &= 7;
+
+	if (_windowArray[a] == NULL || _curWindow == a)
+		return;
+
+	_curWindow = a;
+	showmessage_print_char(0);
+	_textWindow = _windowArray[a];
+
+	if (getGameType() == GType_FF)
+		showmessage_helper_3(_textWindow->textColumn, _textWindow->width);
+	else
+		showmessage_helper_3(_textWindow->textLength, _textWindow->textMaxLength);
+}
+
+void SimonEngine::closeWindow(uint a) {
+	if (_windowArray[a] == NULL)
+		return;
+	removeIconArray(a);
+	resetWindow(_windowArray[a]);
+	_windowArray[a] = NULL;
+	if (_curWindow == a) {
+		_textWindow = NULL;
+		changeWindow(0);
+	}
+}
+
+void SimonEngine::clearWindow(WindowBlock *window) {
+	if (window->flags & 0x10)
+		restoreWindow(window);
+	else
+		colorWindow(window);
+
+	window->textColumn = 0;
+	window->textRow = 0;
+	window->textColumnOffset = 0;
+	window->textLength = 0;
+	window->scrollY = 0;
+}
+
+void SimonEngine::colorWindow(WindowBlock *window) {
+	byte *dst;
+	uint h, w;
+
+	_lockWord |= 0x8000;
+
+	if (getGameType() == GType_FF) {
+		dst = getFrontBuf() + _dxSurfacePitch * window->y + window->x;
+
+		for (h = 0; h < window->height; h++) {
+			for (w = 0; w < window->width; w++) {
+				if (dst[w] == 113  || dst[w] == 116 || dst[w] == 252)
+					dst[w] = window->fill_color;
+			}
+			dst += _screenWidth;
+		}
+	} else {
+		dst = getFrontBuf() + _dxSurfacePitch * window->y + window->x * 8;
+		h = window->height * 8;
+		w = window->width * 8;
+
+		do {
+			memset(dst, window->fill_color, w);
+			dst += _dxSurfacePitch;
+		} while (--h);
+	}
+
+	_lockWord &= ~0x8000;
+}
+
+void SimonEngine::resetWindow(WindowBlock *window) {
+	if (window->flags & 8)
+		restoreWindow(window);
+	window->mode = 0;
+}
+
+void SimonEngine::restoreWindow(WindowBlock *window) {
+	_lockWord |= 0x8000;
+
+	if (getGameType() == GType_FF) {
+		restoreBlock(window->y + window->height, window->x + window->width, window->y, window->x);
+	} else if (getGameType() == GType_SIMON2) {
+		if (_restoreWindow6 && _windowArray[2] == window) {
+			window = _windowArray[6];
+			_restoreWindow6 = 0;
+		}
+
+		restoreBlock(window->y + window->height * 8, (window->x + window->width) * 8, window->y, window->x * 8);
+	} else {
+		restoreBlock(window->y + window->height * 8 + ((window == _windowArray[2]) ? 1 : 0), (window->x + window->width) * 8, window->y, window->x * 8);
+	}
+
+	_lockWord &= ~0x8000;
+}
+
+void SimonEngine::windowPutChar(uint a) {
+	if (_textWindow != _windowArray[0])
+		windowPutChar(_textWindow, a);
+}
+
+} // End of namespace Simon


Property changes on: scummvm/trunk/engines/simon/window.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:eol-style
   + native


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