[Scummvm-cvs-logs] SF.net SVN: scummvm: [20703] scummvm/trunk/engines/scumm

sev at users.sourceforge.net sev at users.sourceforge.net
Wed Feb 15 10:51:02 CET 2006


Revision: 20703
Author:   sev
Date:     2006-02-15 10:48:49 -0800 (Wed, 15 Feb 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm?rev=20703&view=rev

Log Message:
-----------
o Renamed script_v6he.cpp and script_v7he.cpp to script_v60he.cpp and
  script_v70he.cpp respectively since we use 2 digits for HE versioning.

o Also renamed resource_v7he.* to resource_he.* because it is actually not
  HE70-specific but is used by all HE70+ titles.

Modified Paths:
--------------
    scummvm/trunk/engines/scumm/cursor.cpp
    scummvm/trunk/engines/scumm/he/script_v100he.cpp
    scummvm/trunk/engines/scumm/he/script_v72he.cpp
    scummvm/trunk/engines/scumm/he/script_v80he.cpp
    scummvm/trunk/engines/scumm/he/script_v90he.cpp
    scummvm/trunk/engines/scumm/module.mk
    scummvm/trunk/engines/scumm/scumm.cpp

Added Paths:
-----------
    scummvm/trunk/engines/scumm/he/resource_he.cpp
    scummvm/trunk/engines/scumm/he/resource_he.h
    scummvm/trunk/engines/scumm/he/script_v60he.cpp
    scummvm/trunk/engines/scumm/he/script_v70he.cpp

Removed Paths:
-------------
    scummvm/trunk/engines/scumm/he/resource_v7he.cpp
    scummvm/trunk/engines/scumm/he/resource_v7he.h
    scummvm/trunk/engines/scumm/he/script_v6he.cpp
    scummvm/trunk/engines/scumm/he/script_v7he.cpp
Modified: scummvm/trunk/engines/scumm/cursor.cpp
===================================================================
--- scummvm/trunk/engines/scumm/cursor.cpp	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/cursor.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -28,7 +28,7 @@
 #include "scumm/intern.h"
 #include "scumm/he/intern_he.h"
 #include "scumm/object.h"
-#include "scumm/he/resource_v7he.h"
+#include "scumm/he/resource_he.h"
 #include "scumm/saveload.h"
 #include "scumm/scumm.h"
 

Copied: scummvm/trunk/engines/scumm/he/resource_he.cpp (from rev 20696, scummvm/trunk/engines/scumm/he/resource_v7he.cpp)
===================================================================
--- scummvm/trunk/engines/scumm/he/resource_he.cpp	                        (rev 0)
+++ scummvm/trunk/engines/scumm/he/resource_he.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -0,0 +1,1912 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004-2006 The ScummVM project
+ *
+ * Parts of code heavily based on:
+ * icoutils - A set of programs dealing with MS Windows icons and cursors.
+ * Copyright (C) 1998-2001 Oskar Liljeblad
+ *
+ * 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 "scumm/scumm.h"
+#include "scumm/he/intern_he.h"
+#include "scumm/resource.h"
+#include "scumm/he/resource_he.h"
+#include "scumm/sound.h"
+#include "scumm/util.h"
+#include "sound/wave.h"
+
+#include "common/stream.h"
+#include "common/system.h"
+
+namespace Scumm {
+
+ResExtractor::ResExtractor(ScummEngine_v70he *scumm)
+	: _vm(scumm) {
+
+	_fileName[0] = 0;
+	memset(_cursorCache, 0, sizeof(_cursorCache));
+}
+
+ResExtractor::~ResExtractor() {
+	for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
+		CachedCursor *cc = &_cursorCache[i];
+		if (cc->valid) {
+			free(cc->bitmap);
+			free(cc->palette);
+		}
+	}
+	memset(_cursorCache, 0, sizeof(_cursorCache));
+}
+
+ResExtractor::CachedCursor *ResExtractor::findCachedCursor(int id) {
+	for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
+		CachedCursor *cc = &_cursorCache[i];
+		if (cc->valid && cc->id == id) {
+			return cc;
+		}
+	}
+	return NULL;
+}
+
+ResExtractor::CachedCursor *ResExtractor::getCachedCursorSlot() {
+	uint32 min_last_used = 0;
+	CachedCursor *r = NULL;
+	for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
+		CachedCursor *cc = &_cursorCache[i];
+		if (!cc->valid) {
+			return cc;
+		} else {
+			if (min_last_used == 0 || cc->last_used < min_last_used) {
+				min_last_used = cc->last_used;
+				r = cc;
+			}
+		}
+	}
+	assert(r);
+	free(r->bitmap);
+	free(r->palette);
+	memset(r, 0, sizeof(CachedCursor));
+	return r;
+}
+
+void ResExtractor::setCursor(int id) {
+	byte *cursorRes = 0;
+	int cursorsize;
+	int keycolor = 0;
+	CachedCursor *cc = findCachedCursor(id);
+	if (cc != NULL) {
+		debug(7, "Found cursor %d in cache slot %d", id, cc - _cursorCache);
+	} else {
+		cc = getCachedCursorSlot();
+		assert(cc && !cc->valid);
+		cursorsize = extractResource(id, &cursorRes);
+		convertIcons(cursorRes, cursorsize, &cc->bitmap, &cc->w, &cc->h, &cc->hotspot_x, &cc->hotspot_y, &keycolor, &cc->palette, &cc->palSize);
+		debug(7, "Adding cursor %d to cache slot %d", id, cc - _cursorCache);
+		free(cursorRes);
+		cc->valid = true;
+		cc->id = id;
+		cc->last_used = g_system->getMillis();
+	}
+
+	if (_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette) && cc->palette)
+		_vm->_system->setCursorPalette(cc->palette, 0, cc->palSize);
+
+	_vm->setCursorHotspot(cc->hotspot_x, cc->hotspot_y);
+	_vm->setCursorFromBuffer(cc->bitmap, cc->w, cc->h, cc->w);
+}
+
+
+/*
+ * Static variables
+ */
+const char *res_types[] = {
+	/* 0x01: */
+	"cursor", "bitmap", "icon", "menu", "dialog", "string",
+	"fontdir", "font", "accelerator", "rcdata", "messagelist",
+	"group_cursor", NULL, "group_icon", NULL,
+	/* the following are not defined in winbase.h, but found in wrc. */
+	/* 0x10: */
+	"version", "dlginclude", NULL, "plugplay", "vxd",
+	"anicursor", "aniicon"
+};
+#define RES_TYPE_COUNT (sizeof(res_types)/sizeof(char *))
+
+Win32ResExtractor::Win32ResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {
+}
+
+int Win32ResExtractor::extractResource(int resId, byte **data) {
+	char buf[20];
+
+	snprintf(buf, sizeof(buf), "%d", resId);
+
+	return extractResource_("group_cursor", buf, data);
+}
+
+int Win32ResExtractor::extractResource_(const char *resType, char *resName, byte **data) {
+	char *arg_language = NULL;
+	const char *arg_type = resType;
+	char *arg_name = resName;
+	int arg_action = ACTION_LIST;
+	int ressize = 0;
+
+	_arg_raw = false;
+
+	/* translate --type option from resource type string to integer */
+	arg_type = res_type_string_to_id(arg_type);
+
+	WinLibrary fi;
+
+	/* initiate stuff */
+	fi.memory = NULL;
+	fi.file = new Common::File;
+
+	if (!_fileName[0]) { // We are running for the first time
+		snprintf(_fileName, 256, "%s.he3", _vm->getBaseName());
+
+		if (_vm->_substResFileNameIndex > 0) {
+			char buf1[128];
+
+			_vm->generateSubstResFileName(_fileName, buf1, sizeof(buf1));
+			strcpy(_fileName, buf1);
+		}
+	}
+
+
+	/* get file size */
+	fi.file->open(_fileName);
+	if (!fi.file->isOpen()) {
+		error("Cannot open file %s", _fileName);
+	}
+
+	fi.total_size = fi.file->size();
+	if (fi.total_size == -1) {
+		error("Cannot get size of file %s", fi.file->name());
+		goto cleanup;
+	}
+	if (fi.total_size == 0) {
+		error("%s: file has a size of 0", fi.file->name());
+		goto cleanup;
+	}
+
+	/* read all of file */
+	fi.memory = (byte *)malloc(fi.total_size);
+	if (fi.file->read(fi.memory, fi.total_size) == 0) {
+		error("Cannot read from file %s", fi.file->name());
+		goto cleanup;
+	}
+
+	/* identify file and find resource table */
+	if (!read_library(&fi)) {
+		/* error reported by read_library */
+		goto cleanup;
+	}
+
+	//	verbose_printf("file is a %s\n",
+	//		fi.is_PE_binary ? "Windows NT `PE' binary" : "Windows 3.1 `NE' binary");
+
+	/* errors will be printed by the callback */
+	ressize = do_resources(&fi, arg_type, arg_name, arg_language, arg_action, data);
+
+	/* free stuff and close file */
+	cleanup:
+	if (fi.file != NULL)
+		fi.file->close();
+	if (fi.memory != NULL)
+		free(fi.memory);
+
+	return ressize;
+}
+
+
+/* res_type_id_to_string:
+ *   Translate a numeric resource type to it's corresponding string type.
+ *   (For informative-ness.)
+ */
+const char *Win32ResExtractor::res_type_id_to_string(int id) {
+	if (id == 241)
+		return "toolbar";
+	if (id > 0 && id <= (int)RES_TYPE_COUNT)
+		return res_types[id-1];
+	return NULL;
+}
+
+/* res_type_string_to_id:
+ *   Translate a resource type string to integer.
+ *   (Used to convert the --type option.)
+ */
+const char *Win32ResExtractor::res_type_string_to_id(const char *type) {
+	static const char *res_type_ids[] = {
+		"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9", "-10",
+		"-11", "-12", NULL, "-14", NULL, "-16", "-17", NULL, "-19",
+		"-20", "-21", "-22"
+	};
+	int c;
+
+	if (type == NULL)
+		return NULL;
+
+	for (c = 0 ; c < (int)RES_TYPE_COUNT ; c++) {
+		if (res_types[c] != NULL && !scumm_stricmp(type, res_types[c]))
+			return res_type_ids[c];
+	}
+
+	return type;
+}
+
+int Win32ResExtractor::extract_resources(WinLibrary *fi, WinResource *wr,
+                            WinResource *type_wr, WinResource *name_wr,
+							WinResource *lang_wr, byte **data) {
+	int size;
+	bool free_it;
+	const char *type;
+	int32 id;
+
+	if (*data) {
+		error("Win32ResExtractor::extract_resources() more than one cursor");
+		return 0;
+	}
+
+	*data = extract_resource(fi, wr, &size, &free_it, type_wr->id, (lang_wr == NULL ? NULL : lang_wr->id), _arg_raw);
+
+	if (data == NULL) {
+		error("Win32ResExtractor::extract_resources() problem with resource extraction");
+		return 0;
+	}
+
+	/* get named resource type if possible */
+	type = NULL;
+	if ((id = strtol(type_wr->id, 0, 10)) != 0)
+		type = res_type_id_to_string(id);
+
+	debugC(DEBUG_RESOURCE, "extractCursor(). Found cursor name: %s%s%s [size=%d]",
+	  get_resource_id_quoted(name_wr),
+	  (lang_wr->id[0] != '\0' ? " language: " : ""),
+	  get_resource_id_quoted(lang_wr), size);
+
+	return size;
+}
+
+/* extract_resource:
+ *   Extract a resource, returning pointer to data.
+ */
+byte *Win32ResExtractor::extract_resource(WinLibrary *fi, WinResource *wr, int *size,
+                  bool *free_it, char *type, char *lang, bool raw) {
+	char *str;
+	int32 intval;
+
+	/* just return pointer to data if raw */
+	if (raw) {
+		*free_it = false;
+		/* get_resource_entry will print possible error */
+		return get_resource_entry(fi, wr, size);
+	}
+
+	/* find out how to extract */
+	str = type;
+	if (str != NULL && (intval = strtol(STRIP_RES_ID_FORMAT(str), 0, 10))) {
+		if (intval == (int)RT_GROUP_ICON) {
+			*free_it = true;
+			return extract_group_icon_cursor_resource(fi, wr, lang, size, true);
+		}
+		if (intval == (int)RT_GROUP_CURSOR) {
+			*free_it = true;
+			return extract_group_icon_cursor_resource(fi, wr, lang, size, false);
+		}
+	}
+
+	return NULL;
+}
+
+/* extract_group_icon_resource:
+ *   Create a complete RT_GROUP_ICON resource, that can be written to
+ *   an `.ico' file without modifications. Returns an allocated
+ *   memory block that should be freed with free() once used.
+ *
+ *   `root' is the offset in file that specifies the resource.
+ *   `base' is the offset that string pointers are calculated from.
+ *   `ressize' should point to an integer variable where the size of
+ *   the returned memory block will be placed.
+ *   `is_icon' indicates whether resource to be extracted is icon
+ *   or cursor group.
+ */
+byte *Win32ResExtractor::extract_group_icon_cursor_resource(WinLibrary *fi, WinResource *wr, char *lang,
+                                   int *ressize, bool is_icon) {
+	Win32CursorIconDir *icondir;
+	Win32CursorIconFileDir *fileicondir;
+	byte *memory;
+	int c, offset, skipped;
+	int size;
+
+	/* get resource data and size */
+	icondir = (Win32CursorIconDir *)get_resource_entry(fi, wr, &size);
+	if (icondir == NULL) {
+		/* get_resource_entry will print error */
+		return NULL;
+	}
+
+	/* calculate total size of output file */
+	RETURN_IF_BAD_POINTER(NULL, icondir->count);
+	skipped = 0;
+	for (c = 0 ; c < icondir->count ; c++) {
+		int level;
+		int iconsize;
+		char name[14];
+		WinResource *fwr;
+
+		RETURN_IF_BAD_POINTER(NULL, icondir->entries[c]);
+		/*printf("%d. bytes_in_res=%d width=%d height=%d planes=%d bit_count=%d\n", c,
+			icondir->entries[c].bytes_in_res,
+			(is_icon ? icondir->entries[c].res_info.icon.width : icondir->entries[c].res_info.cursor.width),
+			(is_icon ? icondir->entries[c].res_info.icon.height : icondir->entries[c].res_info.cursor.height),
+			icondir->entries[c].plane_count,
+			icondir->entries[c].bit_count);*/
+
+		/* find the corresponding icon resource */
+		snprintf(name, sizeof(name)/sizeof(char), "-%d", icondir->entries[c].res_id);
+		fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level);
+		if (fwr == NULL) {
+			error("%s: could not find `%s' in `%s' resource.",
+					fi->file->name(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
+			return NULL;
+		}
+
+		if (get_resource_entry(fi, fwr, &iconsize) != NULL) {
+		    if (iconsize == 0) {
+				debugC(DEBUG_RESOURCE, "%s: icon resource `%s' is empty, skipping", fi->file->name(), name);
+				skipped++;
+				continue;
+		    }
+		    if ((uint32)iconsize != icondir->entries[c].bytes_in_res) {
+				debugC(DEBUG_RESOURCE, "%s: mismatch of size in icon resource `%s' and group (%d != %d)",
+					fi->file->name(), name, iconsize, icondir->entries[c].bytes_in_res);
+		    }
+		    size += iconsize; /* size += icondir->entries[c].bytes_in_res; */
+
+		    /* cursor resources have two additional WORDs that contain
+		     * hotspot info */
+		    if (!is_icon)
+			size -= sizeof(uint16)*2;
+		}
+	}
+	offset = sizeof(Win32CursorIconFileDir) + (icondir->count-skipped) * sizeof(Win32CursorIconFileDirEntry);
+	size += offset;
+	*ressize = size;
+
+	/* allocate that much memory */
+	memory = (byte *)malloc(size);
+	fileicondir = (Win32CursorIconFileDir *)memory;
+
+	/* transfer Win32CursorIconDir structure members */
+	fileicondir->reserved = icondir->reserved;
+	fileicondir->type = icondir->type;
+	fileicondir->count = icondir->count - skipped;
+
+	/* transfer each cursor/icon: Win32CursorIconDirEntry and data */
+	skipped = 0;
+	for (c = 0 ; c < icondir->count ; c++) {
+		int level;
+		char name[14];
+		WinResource *fwr;
+		byte *data;
+
+		/* find the corresponding icon resource */
+		snprintf(name, sizeof(name)/sizeof(char), "-%d", icondir->entries[c].res_id);
+		fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level);
+		if (fwr == NULL) {
+			error("%s: could not find `%s' in `%s' resource.",
+				fi->file->name(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
+			return NULL;
+		}
+
+		/* get data and size of that resource */
+		data = (byte *)get_resource_entry(fi, fwr, &size);
+		if (data == NULL) {
+			/* get_resource_entry has printed error */
+			return NULL;
+		}
+    	    	if (size == 0) {
+		    skipped++;
+		    continue;
+		}
+
+		/* copy ICONDIRENTRY (not including last dwImageOffset) */
+		memcpy(&fileicondir->entries[c-skipped], &icondir->entries[c],
+			sizeof(Win32CursorIconFileDirEntry)-sizeof(uint32));
+
+		/* special treatment for cursors */
+		if (!is_icon) {
+			fileicondir->entries[c-skipped].width = icondir->entries[c].res_info.cursor.width;
+			fileicondir->entries[c-skipped].height = icondir->entries[c].res_info.cursor.height / 2;
+			fileicondir->entries[c-skipped].color_count = 0;
+			fileicondir->entries[c-skipped].reserved = 0;
+		}
+
+		/* set image offset and increase it */
+		fileicondir->entries[c-skipped].dib_offset = offset;
+
+		/* transfer resource into file memory */
+		if (is_icon) {
+			memcpy(&memory[offset], data, icondir->entries[c].bytes_in_res);
+		} else {
+			fileicondir->entries[c-skipped].hotspot_x = ((uint16 *) data)[0];
+			fileicondir->entries[c-skipped].hotspot_y = ((uint16 *) data)[1];
+			memcpy(&memory[offset], data+sizeof(uint16)*2,
+				   icondir->entries[c].bytes_in_res-sizeof(uint16)*2);
+			offset -= sizeof(uint16)*2;
+		}
+
+		/* increase the offset pointer */
+		offset += icondir->entries[c].bytes_in_res;
+	}
+
+	return memory;
+}
+
+/* check_offset:
+ *   Check if a chunk of data (determined by offset and size)
+ *   is within the bounds of the WinLibrary file.
+ *   Usually not called directly.
+ */
+bool Win32ResExtractor::check_offset(byte *memory, int total_size, const char *name, void *offset, int size) {
+	int need_size = (int)((byte *)offset - memory + size);
+
+	debugC(DEBUG_RESOURCE, "check_offset: size=%x vs %x offset=%x size=%x",
+		need_size, total_size, (byte *)offset - memory, size);
+
+	if (need_size < 0 || need_size > total_size) {
+		error("%s: premature end", name);
+		return false;
+	}
+
+	return true;
+}
+
+
+/* do_resources:
+ *   Do something for each resource matching type, name and lang.
+ */
+int Win32ResExtractor::do_resources(WinLibrary *fi, const char *type, char *name, char *lang, int action, byte **data) {
+	WinResource *type_wr;
+	WinResource *name_wr;
+	WinResource *lang_wr;
+	int size;
+
+	type_wr = (WinResource *)calloc(sizeof(WinResource)*3, 1);
+	name_wr = type_wr + 1;
+	lang_wr = type_wr + 2;
+
+	size = do_resources_recurs(fi, NULL, type_wr, name_wr, lang_wr, type, name, lang, action, data);
+
+	free(type_wr);
+
+	return size;
+}
+
+/* what is each entry in this directory level for? type, name or language? */
+#define WINRESOURCE_BY_LEVEL(x) ((x)==0 ? type_wr : ((x)==1 ? name_wr : lang_wr))
+
+/* does the id of this entry match the specified id? */
+#define LEVEL_MATCHES(x) (x == NULL || x ## _wr->id[0] == '\0' || compare_resource_id(x ## _wr, x))
+
+int Win32ResExtractor::do_resources_recurs(WinLibrary *fi, WinResource *base,
+		  WinResource *type_wr, WinResource *name_wr, WinResource *lang_wr,
+		  const char *type, char *name, char *lang, int action, byte **data) {
+	int c, rescnt;
+	WinResource *wr;
+	uint32 size = 0;
+
+	/* get a list of all resources at this level */
+	wr = list_resources(fi, base, &rescnt);
+	if (wr == NULL)
+		if (size != 0)
+			return size;
+		else
+			return 0;
+
+	/* process each resource listed */
+	for (c = 0 ; c < rescnt ; c++) {
+		/* (over)write the corresponding WinResource holder with the current */
+		memcpy(WINRESOURCE_BY_LEVEL(wr[c].level), wr+c, sizeof(WinResource));
+
+		/* go deeper unless there is something that does NOT match */
+		if (LEVEL_MATCHES(type) && LEVEL_MATCHES(name) && LEVEL_MATCHES(lang)) {
+			if (wr->is_directory)
+				size = do_resources_recurs(fi, wr+c, type_wr, name_wr, lang_wr, type, name, lang, action, data);
+			else
+				size = extract_resources(fi, wr+c, type_wr, name_wr, lang_wr, data);
+		}
+	}
+
+	/* since we're moving back one level after this, unset the
+	 * WinResource holder used on this level */
+	memset(WINRESOURCE_BY_LEVEL(wr[0].level), 0, sizeof(WinResource));
+
+	return size;
+}
+
+/* return the resource id quoted if it's a string, otherwise just return it */
+char *Win32ResExtractor::get_resource_id_quoted(WinResource *wr) {
+	static char tmp[WINRES_ID_MAXLEN+2];
+
+	if (wr->numeric_id || wr->id[0] == '\0')
+		return wr->id;
+
+	sprintf(tmp, "'%s'", wr->id);
+	return tmp;
+}
+
+bool Win32ResExtractor::compare_resource_id(WinResource *wr, const char *id) {
+	if (wr->numeric_id) {
+		int32 cmp1, cmp2;
+		if (id[0] == '+')
+			return false;
+		if (id[0] == '-')
+			id++;
+		if (!(cmp1 = strtol(wr->id, 0, 10)) || !(cmp2 = strtol(id, 0, 10)) || cmp1 != cmp2)
+			return false;
+	} else {
+		if (id[0] == '-')
+			return false;
+		if (id[0] == '+')
+			id++;
+		if (strcmp(wr->id, id))
+			return false;
+	}
+
+	return true;
+}
+
+bool Win32ResExtractor::decode_pe_resource_id(WinLibrary *fi, WinResource *wr, uint32 value) {
+	if (value & IMAGE_RESOURCE_NAME_IS_STRING) {	/* numeric id */
+		int c, len;
+		uint16 *mem = (uint16 *)
+		  (fi->first_resource + (value & ~IMAGE_RESOURCE_NAME_IS_STRING));
+
+		/* copy each char of the string, and terminate it */
+		RETURN_IF_BAD_POINTER(false, *mem);
+		len = mem[0];
+		RETURN_IF_BAD_OFFSET(false, &mem[1], sizeof(uint16) * len);
+
+		len = MIN(mem[0], (uint16)WINRES_ID_MAXLEN);
+		for (c = 0 ; c < len ; c++)
+			wr->id[c] = mem[c+1] & 0x00FF;
+		wr->id[len] = '\0';
+	} else {					/* Unicode string id */
+		/* translate id into a string */
+		snprintf(wr->id, WINRES_ID_MAXLEN, "%d", value);
+	}
+
+	wr->numeric_id = (value & IMAGE_RESOURCE_NAME_IS_STRING ? false:true);
+	return true;
+}
+
+byte *Win32ResExtractor::get_resource_entry(WinLibrary *fi, WinResource *wr, int *size) {
+	if (fi->is_PE_binary) {
+		Win32ImageResourceDataEntry *dataent;
+
+		dataent = (Win32ImageResourceDataEntry *) wr->children;
+		RETURN_IF_BAD_POINTER(NULL, *dataent);
+		*size = dataent->size;
+		RETURN_IF_BAD_OFFSET(NULL, fi->memory + dataent->offset_to_data, *size);
+
+		return fi->memory + dataent->offset_to_data;
+	} else {
+		Win16NENameInfo *nameinfo;
+		int sizeshift;
+
+		nameinfo = (Win16NENameInfo *) wr->children;
+		sizeshift = *((uint16 *) fi->first_resource - 1);
+		*size = nameinfo->length << sizeshift;
+		RETURN_IF_BAD_OFFSET(NULL, fi->memory + (nameinfo->offset << sizeshift), *size);
+
+		return fi->memory + (nameinfo->offset << sizeshift);
+	}
+}
+
+bool Win32ResExtractor::decode_ne_resource_id(WinLibrary *fi, WinResource *wr, uint16 value) {
+	if (value & NE_RESOURCE_NAME_IS_NUMERIC) {		/* numeric id */
+		/* translate id into a string */
+		snprintf(wr->id, WINRES_ID_MAXLEN, "%d", value & ~NE_RESOURCE_NAME_IS_NUMERIC);
+	} else {					/* ASCII string id */
+		int len;
+		char *mem = (char *)NE_HEADER(fi->memory)
+		                     + NE_HEADER(fi->memory)->rsrctab
+		                     + value;
+
+		/* copy each char of the string, and terminate it */
+		RETURN_IF_BAD_POINTER(false, *mem);
+		len = mem[0];
+		RETURN_IF_BAD_OFFSET(false, &mem[1], sizeof(char) * len);
+		memcpy(wr->id, &mem[1], len);
+		wr->id[len] = '\0';
+	}
+
+	wr->numeric_id = (value & NE_RESOURCE_NAME_IS_NUMERIC ? true:false);
+	return true;
+}
+
+Win32ResExtractor::WinResource *Win32ResExtractor::list_pe_resources(WinLibrary *fi, Win32ImageResourceDirectory *pe_res, int level, int *count) {
+	WinResource *wr;
+	int c, rescnt;
+	Win32ImageResourceDirectoryEntry *dirent
+	  = (Win32ImageResourceDirectoryEntry *)(pe_res + 1);
+
+	/* count number of `type' resources */
+	RETURN_IF_BAD_POINTER(NULL, *dirent);
+	rescnt = pe_res->number_of_named_entries + pe_res->number_of_id_entries;
+	*count = rescnt;
+
+	/* allocate WinResource's */
+	wr = (WinResource *)malloc(sizeof(WinResource) * rescnt);
+
+	/* fill in the WinResource's */
+	for (c = 0 ; c < rescnt ; c++) {
+		RETURN_IF_BAD_POINTER(NULL, dirent[c]);
+		wr[c].this_ = pe_res;
+		wr[c].level = level;
+		wr[c].is_directory = (dirent[c].u2.s.data_is_directory);
+		wr[c].children = fi->first_resource + dirent[c].u2.s.offset_to_directory;
+
+		/* fill in wr->id, wr->numeric_id */
+		if (!decode_pe_resource_id (fi, wr + c, dirent[c].u1.name))
+			return NULL;
+	}
+
+	return wr;
+}
+
+Win32ResExtractor::WinResource *Win32ResExtractor::list_ne_name_resources(WinLibrary *fi, WinResource *typeres, int *count) {
+	int c, rescnt;
+	WinResource *wr;
+	Win16NETypeInfo *typeinfo = (Win16NETypeInfo *) typeres->this_;
+	Win16NENameInfo *nameinfo = (Win16NENameInfo *) typeres->children;
+
+	/* count number of `type' resources */
+	RETURN_IF_BAD_POINTER(NULL, typeinfo->count);
+	*count = rescnt = typeinfo->count;
+
+	/* allocate WinResource's */
+	wr = (WinResource *)malloc(sizeof(WinResource) * rescnt);
+
+	/* fill in the WinResource's */
+	for (c = 0 ; c < rescnt ; c++) {
+		RETURN_IF_BAD_POINTER(NULL, nameinfo[c]);
+		wr[c].this_ = nameinfo+c;
+		wr[c].is_directory = false;
+		wr[c].children = nameinfo+c;
+		wr[c].level = 1;
+
+		/* fill in wr->id, wr->numeric_id */
+		if (!decode_ne_resource_id(fi, wr + c, (nameinfo+c)->id))
+			return NULL;
+	}
+
+	return wr;
+}
+
+Win32ResExtractor::WinResource *Win32ResExtractor::list_ne_type_resources(WinLibrary *fi, int *count) {
+	int c, rescnt;
+	WinResource *wr;
+	Win16NETypeInfo *typeinfo;
+
+	/* count number of `type' resources */
+	typeinfo = (Win16NETypeInfo *) fi->first_resource;
+	RETURN_IF_BAD_POINTER(NULL, *typeinfo);
+	for (rescnt = 0 ; typeinfo->type_id != 0 ; rescnt++) {
+		typeinfo = NE_TYPEINFO_NEXT(typeinfo);
+		RETURN_IF_BAD_POINTER(NULL, *typeinfo);
+	}
+	*count = rescnt;
+
+	/* allocate WinResource's */
+	wr = (WinResource *)malloc(sizeof(WinResource) * rescnt);
+
+	/* fill in the WinResource's */
+	typeinfo = (Win16NETypeInfo *) fi->first_resource;
+	for (c = 0 ; c < rescnt ; c++) {
+		wr[c].this_ = typeinfo;
+		wr[c].is_directory = (typeinfo->count != 0);
+		wr[c].children = typeinfo+1;
+		wr[c].level = 0;
+
+		/* fill in wr->id, wr->numeric_id */
+		if (!decode_ne_resource_id(fi, wr + c, typeinfo->type_id))
+			return NULL;
+
+		typeinfo = NE_TYPEINFO_NEXT(typeinfo);
+	}
+
+	return wr;
+}
+
+/* list_resources:
+ *   Return an array of WinResource's in the current
+ *   resource level specified by res.
+ */
+Win32ResExtractor::WinResource *Win32ResExtractor::list_resources(WinLibrary *fi, WinResource *res, int *count) {
+	if (res != NULL && !res->is_directory)
+		return NULL;
+
+	if (fi->is_PE_binary) {
+		return list_pe_resources(fi, (Win32ImageResourceDirectory *)
+				 (res == NULL ? fi->first_resource : res->children),
+				 (res == NULL ? 0 : res->level+1),
+				 count);
+	} else {
+		return (res == NULL
+				? list_ne_type_resources(fi, count)
+				: list_ne_name_resources(fi, res, count));
+	}
+}
+
+/* read_library:
+ *   Read header and get resource directory offset in a Windows library
+ *    (AKA module).
+ *
+ */
+bool Win32ResExtractor::read_library(WinLibrary *fi) {
+	/* check for DOS header signature `MZ' */
+	RETURN_IF_BAD_POINTER(false, MZ_HEADER(fi->memory)->magic);
+	if (MZ_HEADER(fi->memory)->magic == IMAGE_DOS_SIGNATURE) {
+		DOSImageHeader *mz_header = MZ_HEADER(fi->memory);
+
+		RETURN_IF_BAD_POINTER(false, mz_header->lfanew);
+		if (mz_header->lfanew < sizeof(DOSImageHeader)) {
+			error("%s: not a Windows library", fi->file->name());
+			return false;
+		}
+	}
+
+	/* check for OS2 (Win16) header signature `NE' */
+	RETURN_IF_BAD_POINTER(false, NE_HEADER(fi->memory)->magic);
+	if (NE_HEADER(fi->memory)->magic == IMAGE_OS2_SIGNATURE) {
+		OS2ImageHeader *header = NE_HEADER(fi->memory);
+
+		RETURN_IF_BAD_POINTER(false, header->rsrctab);
+		RETURN_IF_BAD_POINTER(false, header->restab);
+		if (header->rsrctab >= header->restab) {
+			error("%s: no resource directory found", fi->file->name());
+			return false;
+		}
+
+		fi->is_PE_binary = false;
+		fi->first_resource = (byte *) NE_HEADER(fi->memory)
+		  + header->rsrctab + sizeof(uint16);
+		RETURN_IF_BAD_POINTER(false, *(Win16NETypeInfo *) fi->first_resource);
+
+		return true;
+	}
+
+	/* check for NT header signature `PE' */
+	RETURN_IF_BAD_POINTER(false, PE_HEADER(fi->memory)->signature);
+	if (PE_HEADER(fi->memory)->signature == IMAGE_NT_SIGNATURE) {
+		Win32ImageSectionHeader *pe_sec;
+		Win32ImageDataDirectory *dir;
+		Win32ImageNTHeaders *pe_header;
+		int d;
+
+		/* allocate new memory */
+		fi->total_size = calc_vma_size(fi);
+		if (fi->total_size == 0) {
+			/* calc_vma_size has reported error */
+			return false;
+		}
+		fi->memory = (byte *)realloc(fi->memory, fi->total_size);
+
+		/* relocate memory, start from last section */
+		pe_header = PE_HEADER(fi->memory);
+		RETURN_IF_BAD_POINTER(false, pe_header->file_header.number_of_sections);
+
+		/* we don't need to do OFFSET checking for the sections.
+		 * calc_vma_size has already done that */
+		for (d = pe_header->file_header.number_of_sections - 1; d >= 0 ; d--) {
+			pe_sec = PE_SECTIONS(fi->memory) + d;
+
+	            	if (pe_sec->characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+			    continue;
+
+    	    	    	//if (pe_sec->virtual_address + pe_sec->size_of_raw_data > fi->total_size)
+
+    	    	    	RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->virtual_address, pe_sec->size_of_raw_data);
+    	    	    	RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->pointer_to_raw_data, pe_sec->size_of_raw_data);
+    	    	    	if (pe_sec->virtual_address != pe_sec->pointer_to_raw_data) {
+    	    	    	    memmove(fi->memory + pe_sec->virtual_address,
+				    fi->memory + pe_sec->pointer_to_raw_data,
+				    pe_sec->size_of_raw_data);
+			}
+		}
+
+		/* find resource directory */
+		RETURN_IF_BAD_POINTER(false, pe_header->optional_header.data_directory[IMAGE_DIRECTORY_ENTRY_RESOURCE]);
+		dir = pe_header->optional_header.data_directory + IMAGE_DIRECTORY_ENTRY_RESOURCE;
+		if (dir->size == 0) {
+			error("%s: file contains no resources", fi->file->name());
+			return false;
+		}
+
+		fi->first_resource = fi->memory + dir->virtual_address;
+		fi->is_PE_binary = true;
+		return true;
+	}
+
+	/* other (unknown) header signature was found */
+	error("%s: not a Windows library", fi->file->name());
+	return false;
+}
+
+/* calc_vma_size:
+ *   Calculate the total amount of memory needed for a 32-bit Windows
+ *   module. Returns -1 if file was too small.
+ */
+int Win32ResExtractor::calc_vma_size(WinLibrary *fi) {
+    Win32ImageSectionHeader *seg;
+    int c, segcount, size;
+
+	size = 0;
+	RETURN_IF_BAD_POINTER(-1, PE_HEADER(fi->memory)->file_header.number_of_sections);
+	segcount = PE_HEADER(fi->memory)->file_header.number_of_sections;
+
+	/* If there are no segments, just process file like it is.
+	 * This is (probably) not the right thing to do, but problems
+	 * will be delt with later anyway.
+	 */
+	if (segcount == 0)
+		return fi->total_size;
+
+	seg = PE_SECTIONS(fi->memory);
+	RETURN_IF_BAD_POINTER(-1, *seg);
+    for (c = 0 ; c < segcount ; c++) {
+		RETURN_IF_BAD_POINTER(0, *seg);
+
+        size = MAX((uint32)size, seg->virtual_address + seg->size_of_raw_data);
+		/* I have no idea what misc.virtual_size is for... */
+        size = MAX((uint32)size, seg->virtual_address + seg->misc.virtual_size);
+        seg++;
+    }
+
+    return size;
+}
+
+Win32ResExtractor::WinResource *Win32ResExtractor::find_with_resource_array(WinLibrary *fi, WinResource *wr, const char *id) {
+	int c, rescnt;
+	WinResource *return_wr;
+
+	wr = list_resources(fi, wr, &rescnt);
+	if (wr == NULL)
+		return NULL;
+
+	for (c = 0 ; c < rescnt ; c++) {
+		if (compare_resource_id(&wr[c], id)) {
+			/* duplicate WinResource and return it */
+			return_wr = (WinResource *)malloc(sizeof(WinResource));
+			memcpy(return_wr, &wr[c], sizeof(WinResource));
+
+			/* free old WinResource */
+			free(wr);
+			return return_wr;
+		}
+	}
+
+	return NULL;
+}
+
+Win32ResExtractor::WinResource *Win32ResExtractor::find_resource(WinLibrary *fi, const char *type, const char *name, const char *language, int *level) {
+	WinResource *wr;
+
+	*level = 0;
+	if (type == NULL)
+		return NULL;
+	wr = find_with_resource_array(fi, NULL, type);
+	if (wr == NULL || !wr->is_directory)
+		return wr;
+
+	*level = 1;
+	if (name == NULL)
+		return wr;
+	wr = find_with_resource_array(fi, wr, name);
+	if (wr == NULL || !wr->is_directory)
+		return wr;
+
+	*level = 2;
+	if (language == NULL)
+		return wr;
+	wr = find_with_resource_array(fi, wr, language);
+	return wr;
+}
+
+#define ROW_BYTES(bits) ((((bits) + 31) >> 5) << 2)
+
+
+int Win32ResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
+			int *hotspot_x, int *hotspot_y, int *keycolor, byte **pal, int *palSize) {
+	Win32CursorIconFileDir dir;
+	Win32CursorIconFileDirEntry *entries = NULL;
+	uint32 offset;
+	uint32 c, d;
+	int completed;
+	int matched = 0;
+	MemoryReadStream *in = new MemoryReadStream(data, datasize);
+
+	if (!in->read(&dir, sizeof(Win32CursorIconFileDir)- sizeof(Win32CursorIconFileDirEntry)))
+		goto cleanup;
+	fix_win32_cursor_icon_file_dir_endian(&dir);
+
+	if (dir.reserved != 0) {
+		error("not an icon or cursor file (reserved non-zero)");
+		goto cleanup;
+	}
+	if (dir.type != 1 && dir.type != 2) {
+		error("not an icon or cursor file (wrong type)");
+		goto cleanup;
+	}
+
+	entries = (Win32CursorIconFileDirEntry *)malloc(dir.count * sizeof(Win32CursorIconFileDirEntry));
+	for (c = 0; c < dir.count; c++) {
+		if (!in->read(&entries[c], sizeof(Win32CursorIconFileDirEntry)))
+			goto cleanup;
+		fix_win32_cursor_icon_file_dir_entry_endian(&entries[c]);
+		if (entries[c].reserved != 0)
+			error("reserved is not zero");
+	}
+
+	offset = sizeof(Win32CursorIconFileDir) + (dir.count - 1) * (sizeof(Win32CursorIconFileDirEntry));
+
+	for (completed = 0; completed < dir.count; ) {
+		uint32 min_offset = 0x7fffffff;
+		int previous = completed;
+
+		for (c = 0; c < dir.count; c++) {
+			if (entries[c].dib_offset == offset) {
+				Win32BitmapInfoHeader bitmap;
+				Win32RGBQuad *palette = NULL;
+				uint32 palette_count = 0;
+				uint32 image_size, mask_size;
+				uint32 width, height;
+				byte *image_data = NULL, *mask_data = NULL;
+				byte *row = NULL;
+
+				if (!in->read(&bitmap, sizeof(Win32BitmapInfoHeader)))
+					goto local_cleanup;
+
+				fix_win32_bitmap_info_header_endian(&bitmap);
+				if (bitmap.size < sizeof(Win32BitmapInfoHeader)) {
+					error("bitmap header is too short");
+					goto local_cleanup;
+				}
+				if (bitmap.compression != 0) {
+					error("compressed image data not supported");
+					goto local_cleanup;
+				}
+				if (bitmap.x_pels_per_meter != 0)
+					error("x_pels_per_meter field in bitmap should be zero");
+				if (bitmap.y_pels_per_meter != 0)
+					error("y_pels_per_meter field in bitmap should be zero");
+				if (bitmap.clr_important != 0)
+					error("clr_important field in bitmap should be zero");
+				if (bitmap.planes != 1)
+					error("planes field in bitmap should be one");
+				if (bitmap.size != sizeof(Win32BitmapInfoHeader)) {
+					uint32 skip = bitmap.size - sizeof(Win32BitmapInfoHeader);
+					error("skipping %d bytes of extended bitmap header", skip);
+					in->seek(skip, SEEK_CUR);
+				}
+				offset += bitmap.size;
+
+				if (bitmap.clr_used != 0 || bitmap.bit_count < 24) {
+					palette_count = (bitmap.clr_used != 0 ? bitmap.clr_used : 1 << bitmap.bit_count);
+					palette = (Win32RGBQuad *)malloc(sizeof(Win32RGBQuad) * palette_count);
+					if (!in->read(palette, sizeof(Win32RGBQuad) * palette_count))
+						goto local_cleanup;
+					offset += sizeof(Win32RGBQuad) * palette_count;
+				}
+
+				width = bitmap.width;
+				height = ABS(bitmap.height)/2;
+
+				image_size = height * ROW_BYTES(width * bitmap.bit_count);
+				mask_size = height * ROW_BYTES(width);
+
+				if (entries[c].dib_size	!= bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad))
+					debugC(DEBUG_RESOURCE, "incorrect total size of bitmap (%d specified; %d real)",
+					    entries[c].dib_size,
+					    bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad)
+					);
+
+				image_data = (byte *)malloc(image_size);
+				if (!in->read(image_data, image_size))
+					goto local_cleanup;
+
+				mask_data = (byte *)malloc(mask_size);
+				if (!in->read(mask_data, mask_size))
+					goto local_cleanup;
+
+				offset += image_size;
+				offset += mask_size;
+				completed++;
+				matched++;
+
+				*hotspot_x = entries[c].hotspot_x;
+				*hotspot_y = entries[c].hotspot_y;
+				*w = width;
+				*h = height;
+				*keycolor = 0;
+				*cursor = (byte *)malloc(width * height);
+
+				row = (byte *)malloc(width * 4);
+
+				for (d = 0; d < height; d++) {
+					uint32 x;
+					uint32 y = (bitmap.height < 0 ? d : height - d - 1);
+					uint32 imod = y * (image_size / height) * 8 / bitmap.bit_count;
+					//uint32 mmod = y * (mask_size / height) * 8;
+
+					for (x = 0; x < width; x++) {
+
+						uint32 color = simple_vec(image_data, x + imod, bitmap.bit_count);
+
+						// FIXME?: This works only with b/w cursors and white index may be
+						// different. But now it's enough.
+						if (color) {
+							cursor[0][width * d + x] = 15; // white in SCUMM
+						} else {
+							cursor[0][width * d + x] = 255; // transparent
+						}
+						/*
+
+						if (bitmap.bit_count <= 16) {
+							if (color >= palette_count) {
+								error("color out of range in image data");
+								goto local_cleanup;
+							}
+							row[4*x+0] = palette[color].red;
+							row[4*x+1] = palette[color].green;
+							row[4*x+2] = palette[color].blue;
+
+						} else {
+							row[4*x+0] = (color >> 16) & 0xFF;
+							row[4*x+1] = (color >>  8) & 0xFF;
+							row[4*x+2] = (color >>  0) & 0xFF;
+						}
+						if (bitmap.bit_count == 32)
+						    row[4*x+3] = (color >> 24) & 0xFF;
+						else
+						    row[4*x+3] = simple_vec(mask_data, x + mmod, 1) ? 0 : 0xFF;
+						*/
+					}
+
+				}
+
+				if (row != NULL)
+					free(row);
+				if (palette != NULL)
+					free(palette);
+				if (image_data != NULL) {
+					free(image_data);
+					free(mask_data);
+				}
+				continue;
+
+			local_cleanup:
+
+				if (row != NULL)
+					free(row);
+				if (palette != NULL)
+					free(palette);
+				if (image_data != NULL) {
+					free(image_data);
+					free(mask_data);
+				}
+				goto cleanup;
+			} else {
+				if (entries[c].dib_offset > offset)
+						min_offset = MIN(min_offset, entries[c].dib_offset);
+			}
+		}
+
+		if (previous == completed) {
+			if (min_offset < offset) {
+				error("offset of bitmap header incorrect (too low)");
+				goto cleanup;
+			}
+			debugC(DEBUG_RESOURCE, "skipping %d bytes of garbage at %d", min_offset-offset, offset);
+			in->seek(min_offset - offset, SEEK_CUR);
+			offset = min_offset;
+		}
+	}
+
+	free(entries);
+	return matched;
+
+cleanup:
+
+	free(entries);
+	return -1;
+}
+
+uint32 Win32ResExtractor::simple_vec(byte *data, uint32 ofs, byte size) {
+	switch (size) {
+	case 1:
+		return (data[ofs/8] >> (7 - ofs%8)) & 1;
+	case 2:
+		return (data[ofs/4] >> ((3 - ofs%4) << 1)) & 3;
+	case 4:
+		return (data[ofs/2] >> ((1 - ofs%2) << 2)) & 15;
+	case 8:
+		return data[ofs];
+	case 16:
+		return data[2*ofs] | data[2*ofs+1] << 8;
+	case 24:
+		return data[3*ofs] | data[3*ofs+1] << 8 | data[3*ofs+2] << 16;
+	case 32:
+		return data[4*ofs] | data[4*ofs+1] << 8 | data[4*ofs+2] << 16 | data[4*ofs+3] << 24;
+	}
+
+	return 0;
+}
+
+#define LE16(x)      ((x) = TO_LE_16(x))
+#define LE32(x)      ((x) = TO_LE_32(x))
+
+void Win32ResExtractor::fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj) {
+    LE16(obj->reserved);
+	LE16(obj->type);
+    LE16(obj->count);
+}
+
+void Win32ResExtractor::fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj) {
+    LE32(obj->size);
+    LE32(obj->width);
+    LE32(obj->height);
+    LE16(obj->planes);
+    LE16(obj->bit_count);
+    LE32(obj->compression);
+    LE32(obj->size_image);
+    LE32(obj->x_pels_per_meter);
+    LE32(obj->y_pels_per_meter);
+    LE32(obj->clr_used);
+    LE32(obj->clr_important);
+}
+
+void Win32ResExtractor::fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj) {
+    LE16(obj->hotspot_x);
+    LE16(obj->hotspot_y);
+    LE32(obj->dib_size);
+    LE32(obj->dib_offset);
+}
+
+void Win32ResExtractor::fix_win32_image_section_header(Win32ImageSectionHeader *obj) {
+    LE32(obj->misc.physical_address);
+    LE32(obj->virtual_address);
+    LE32(obj->size_of_raw_data);
+    LE32(obj->pointer_to_raw_data);
+    LE32(obj->pointer_to_relocations);
+    LE32(obj->pointer_to_linenumbers);
+    LE16(obj->number_of_relocations);
+    LE16(obj->number_of_linenumbers);
+    LE32(obj->characteristics);
+}
+
+void Win32ResExtractor::fix_os2_image_header_endian(OS2ImageHeader *obj) {
+    LE16(obj->magic);
+    LE16(obj->enttab);
+    LE16(obj->cbenttab);
+    LE32(obj->crc);
+    LE16(obj->flags);
+    LE16(obj->autodata);
+    LE16(obj->heap);
+    LE16(obj->stack);
+    LE32(obj->csip);
+    LE32(obj->sssp);
+    LE16(obj->cseg);
+    LE16(obj->cmod);
+    LE16(obj->cbnrestab);
+    LE16(obj->segtab);
+    LE16(obj->rsrctab);
+    LE16(obj->restab);
+    LE16(obj->modtab);
+    LE16(obj->imptab);
+    LE32(obj->nrestab);
+    LE16(obj->cmovent);
+    LE16(obj->align);
+    LE16(obj->cres);
+    LE16(obj->fastload_offset);
+    LE16(obj->fastload_length);
+    LE16(obj->swaparea);
+    LE16(obj->expver);
+}
+
+/* fix_win32_image_header_endian:
+ * NOTE: This assumes that the optional header is always available.
+ */
+void Win32ResExtractor::fix_win32_image_header_endian(Win32ImageNTHeaders *obj) {
+    LE32(obj->signature);
+    LE16(obj->file_header.machine);
+    LE16(obj->file_header.number_of_sections);
+    LE32(obj->file_header.time_date_stamp);
+    LE32(obj->file_header.pointer_to_symbol_table);
+    LE32(obj->file_header.number_of_symbols);
+    LE16(obj->file_header.size_of_optional_header);
+    LE16(obj->file_header.characteristics);
+    LE16(obj->optional_header.magic);
+    LE32(obj->optional_header.size_of_code);
+    LE32(obj->optional_header.size_of_initialized_data);
+    LE32(obj->optional_header.size_of_uninitialized_data);
+    LE32(obj->optional_header.address_of_entry_point);
+    LE32(obj->optional_header.base_of_code);
+    LE32(obj->optional_header.base_of_data);
+    LE32(obj->optional_header.image_base);
+    LE32(obj->optional_header.section_alignment);
+    LE32(obj->optional_header.file_alignment);
+    LE16(obj->optional_header.major_operating_system_version);
+    LE16(obj->optional_header.minor_operating_system_version);
+    LE16(obj->optional_header.major_image_version);
+    LE16(obj->optional_header.minor_image_version);
+    LE16(obj->optional_header.major_subsystem_version);
+    LE16(obj->optional_header.minor_subsystem_version);
+    LE32(obj->optional_header.win32_version_value);
+    LE32(obj->optional_header.size_of_image);
+    LE32(obj->optional_header.size_of_headers);
+    LE32(obj->optional_header.checksum);
+    LE16(obj->optional_header.subsystem);
+    LE16(obj->optional_header.dll_characteristics);
+    LE32(obj->optional_header.size_of_stack_reserve);
+    LE32(obj->optional_header.size_of_stack_commit);
+    LE32(obj->optional_header.size_of_heap_reserve);
+    LE32(obj->optional_header.size_of_heap_commit);
+    LE32(obj->optional_header.loader_flags);
+    LE32(obj->optional_header.number_of_rva_and_sizes);
+}
+
+void Win32ResExtractor::fix_win32_image_data_directory(Win32ImageDataDirectory *obj) {
+    LE32(obj->virtual_address);
+    LE32(obj->size);
+}
+
+
+MacResExtractor::MacResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {
+	_resOffset = -1;
+}
+
+int MacResExtractor::extractResource(int id, byte **buf) {
+	Common::File in;
+	int size;
+
+	if (!_fileName[0]) // We are running for the first time
+		if (_vm->_substResFileNameIndex > 0) {
+			char buf1[128];
+
+			snprintf(buf1, 128, "%s.he3", _vm->getBaseName());
+			_vm->generateSubstResFileName(buf1, _fileName, sizeof(buf1));
+
+			// Some programs write it as .bin. Try that too
+			if (!in.exists(_fileName)) {
+				strcpy(buf1, _fileName);
+				snprintf(_fileName, 128, "%s.bin", buf1);
+
+				if (!in.exists(_fileName)) {
+					// And finally check if we have dumped resource fork
+					snprintf(_fileName, 128, "%s.rsrc", buf1);
+					if (!in.exists(_fileName)) {
+						error("Cannot open file any of files '%s', '%s.bin', '%s.rsrc",
+							  buf1, buf1, buf1);
+					}
+				}
+			}
+		}
+
+	in.open(_fileName);
+	if (!in.isOpen()) {
+		error("Cannot open file %s", _fileName);
+	}
+
+	// we haven't calculated it
+	if (_resOffset == -1) {
+		if (!init(in))
+			error("Resource fork is missing in file '%s'", _fileName);
+		in.close();
+		in.open(_fileName);
+	}
+
+	*buf = getResource(in, "crsr", 1000 + id, &size);
+
+	in.close();
+
+	if (*buf == NULL)
+		error("There is no cursor ID #%d", 1000 + id);
+
+	return size;
+}
+
+#define MBI_INFOHDR 128
+#define MBI_ZERO1 0
+#define MBI_NAMELEN 1
+#define MBI_ZERO2 74
+#define MBI_ZERO3 82
+#define MBI_DFLEN 83
+#define MBI_RFLEN 87
+#define MAXNAMELEN 63
+
+bool MacResExtractor::init(Common::File in) {
+	byte infoHeader[MBI_INFOHDR];
+	int32 data_size, rsrc_size;
+	int32 data_size_pad, rsrc_size_pad;
+	int filelen;
+
+	filelen = in.size();
+	in.read(infoHeader, MBI_INFOHDR);
+
+	// Maybe we have MacBinary?
+	if (infoHeader[MBI_ZERO1] == 0 && infoHeader[MBI_ZERO2] == 0 &&
+		infoHeader[MBI_ZERO3] == 0 && infoHeader[MBI_NAMELEN] <= MAXNAMELEN) {
+
+		// Pull out fork lengths
+		data_size = READ_BE_UINT32(infoHeader + MBI_DFLEN);
+		rsrc_size = READ_BE_UINT32(infoHeader + MBI_RFLEN);
+
+		data_size_pad = (((data_size + 127) >> 7) << 7);
+		rsrc_size_pad = (((rsrc_size + 127) >> 7) << 7);
+
+		// Length check
+		int sumlen =  MBI_INFOHDR + data_size_pad + rsrc_size_pad;
+
+		if (sumlen == filelen)
+			_resOffset = MBI_INFOHDR + data_size_pad;
+	}
+
+	if (_resOffset == -1) // MacBinary check is failed
+		_resOffset = 0; // Maybe we have dumped fork?
+
+	in.seek(_resOffset);
+
+	_dataOffset = in.readUint32BE() + _resOffset;
+	_mapOffset = in.readUint32BE() + _resOffset;
+	_dataLength = in.readUint32BE();
+	_mapLength = in.readUint32BE();
+
+	// do sanity check
+	if (_dataOffset >= filelen || _mapOffset >= filelen ||
+		_dataLength + _mapLength  > filelen) {
+		_resOffset = -1;
+		return false;
+	}
+
+	debug(7, "got header: data %d [%d] map %d [%d]",
+		_dataOffset, _dataLength, _mapOffset, _mapLength);
+
+	readMap(in);
+
+	return true;
+}
+
+byte *MacResExtractor::getResource(Common::File in, const char *typeID, int16 resID, int *size) {
+	int	i;
+	int typeNum = -1;
+	int resNum = -1;
+	byte *buf;
+	int len;
+
+	for (i = 0; i < _resMap.numTypes; i++)
+		if (strcmp(_resTypes[i].id, typeID) == 0) {
+			typeNum = i;
+			break;
+		}
+
+	if (typeNum == -1)
+		return NULL;
+
+	for (i = 0; i < _resTypes[typeNum].items; i++)
+		if (_resLists[typeNum][i].id == resID) {
+			resNum = i;
+			break;
+		}
+
+	if (resNum == -1)
+		return NULL;
+
+	in.seek(_dataOffset + _resLists[typeNum][resNum].dataOffset);
+
+	len = in.readUint32BE();
+	buf = (byte *)malloc(len);
+
+	in.read(buf, len);
+
+	*size = len;
+
+	return buf;
+}
+
+void MacResExtractor::readMap(Common::File in) {
+	int	i, j, len;
+
+	in.seek(_mapOffset + 22);
+
+	_resMap.resAttr = in.readUint16BE();
+	_resMap.typeOffset = in.readUint16BE();
+	_resMap.nameOffset = in.readUint16BE();
+	_resMap.numTypes = in.readUint16BE();
+	_resMap.numTypes++;
+
+	in.seek(_mapOffset + _resMap.typeOffset + 2);
+	_resTypes = new ResType[_resMap.numTypes];
+
+	for (i = 0; i < _resMap.numTypes; i++) {
+		in.read(_resTypes[i].id, 4);
+		_resTypes[i].id[4] = 0;
+		_resTypes[i].items = in.readUint16BE();
+		_resTypes[i].offset = in.readUint16BE();
+		_resTypes[i].items++;
+	}
+
+	_resLists = new ResPtr[_resMap.numTypes];
+
+	for (i = 0; i < _resMap.numTypes; i++) {
+		_resLists[i] = new Resource[_resTypes[i].items];
+		in.seek(_resTypes[i].offset + _mapOffset + _resMap.typeOffset);
+
+		for (j = 0; j < _resTypes[i].items; j++) {
+			ResPtr resPtr = _resLists[i] + j;
+
+			resPtr->id = in.readUint16BE();
+			resPtr->nameOffset = in.readUint16BE();
+			resPtr->dataOffset = in.readUint32BE();
+			in.readUint32BE();
+			resPtr->name = 0;
+
+			resPtr->attr = resPtr->dataOffset >> 24;
+			resPtr->dataOffset &= 0xFFFFFF;
+		}
+
+		for (j = 0; j < _resTypes[i].items; j++) {
+			if (_resLists[i][j].nameOffset != -1) {
+				in.seek(_resLists[i][j].nameOffset + _mapOffset + _resMap.nameOffset);
+
+				len = in.readByte();
+				_resLists[i][j].name = new byte[len + 1];
+				_resLists[i][j].name[len] = 0;
+				in.read(_resLists[i][j].name, len);
+			}
+		}
+	}
+}
+
+int MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
+			  int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize) {
+	Common::MemoryReadStream dis(data, datasize);
+	int i, b;
+	byte imageByte;
+	byte *iconData;
+	int numBytes;
+	int pixelsPerByte, bpp;
+	int ctSize;
+	byte bitmask;
+	int iconRowBytes, iconBounds[4];
+	int ignored;
+	int iconDataSize;
+
+	dis.readUint16BE(); // type
+	dis.readUint32BE(); // offset to pixel map
+	dis.readUint32BE(); // offset to pixel data
+	dis.readUint32BE(); // expanded cursor data
+	dis.readUint16BE(); // expanded data depth
+	dis.readUint32BE(); // reserved
+
+	// Grab B/W icon data
+	*cursor = (byte *)malloc(16 * 16);
+	for (i = 0; i < 32; i++) {
+		imageByte = dis.readByte();
+		for (b = 0; b < 8; b++)
+			cursor[0][i*8+b] = (byte)((imageByte &
+									  (0x80 >> b)) > 0? 0x0F: 0x00);
+	}
+
+	// Apply mask data
+	for (i = 0; i < 32; i++) {
+		imageByte = dis.readByte();
+		for (b = 0; b < 8; b++)
+			if ((imageByte & (0x80 >> b)) == 0)
+				cursor[0][i*8+b] = 0xff;
+	}
+
+	*hotspot_y = dis.readUint16BE();
+	*hotspot_x = dis.readUint16BE();
+	*w = *h = 16;
+
+	// Use b/w cursor on backends which don't support cursor palettes
+	if (!_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette))
+		return 1;
+
+	dis.readUint32BE(); // reserved
+	dis.readUint32BE(); // cursorID
+
+	// Color version of cursor
+	dis.readUint32BE(); // baseAddr
+
+	// Keep only lowbyte for now
+	dis.readByte();
+	iconRowBytes = dis.readByte();
+
+	if (!iconRowBytes)
+		return 1;
+
+	iconBounds[0] = dis.readUint16BE();
+	iconBounds[1] = dis.readUint16BE();
+	iconBounds[2] = dis.readUint16BE();
+	iconBounds[3] = dis.readUint16BE();
+
+	dis.readUint16BE(); // pmVersion
+	dis.readUint16BE(); // packType
+	dis.readUint32BE(); // packSize
+
+	dis.readUint32BE(); // hRes
+	dis.readUint32BE(); // vRes
+
+	dis.readUint16BE(); // pixelType
+	dis.readUint16BE(); // pixelSize
+	dis.readUint16BE(); // cmpCount
+	dis.readUint16BE(); // cmpSize
+
+	dis.readUint32BE(); // planeByte
+	dis.readUint32BE(); // pmTable
+	dis.readUint32BE(); // reserved
+
+	// Pixel data for cursor
+	iconDataSize =  iconRowBytes * (iconBounds[3] - iconBounds[1]);
+	iconData = (byte *)malloc(iconDataSize);
+	dis.read(iconData, iconDataSize);
+
+	// Color table
+	dis.readUint32BE(); // ctSeed
+	dis.readUint16BE(); // ctFlag
+	ctSize = dis.readUint16BE() + 1;
+
+	*palette = (byte *)malloc(ctSize * 4);
+
+	// Read just high byte of 16-bit color
+	for (int c = 0; c < ctSize; c++) {
+		// We just use indices 0..ctSize, so ignore color ID
+		dis.readUint16BE(); // colorID[c]
+
+		palette[0][c * 4 + 0] = dis.readByte();
+		ignored = dis.readByte();
+
+		palette[0][c * 4 + 1] = dis.readByte();
+		ignored = dis.readByte();
+
+		palette[0][c * 4 + 2] = dis.readByte();
+		ignored = dis.readByte();
+
+		palette[0][c * 4 + 3] = 0;
+	}
+
+	*palSize = ctSize;
+
+	numBytes =
+         (iconBounds[2] - iconBounds[0]) *
+         (iconBounds[3] - iconBounds[1]);
+
+	pixelsPerByte = (iconBounds[2] - iconBounds[0]) / iconRowBytes;
+	bpp           = 8 / pixelsPerByte;
+
+	// build a mask to make sure the pixels are properly shifted out
+	bitmask = 0;
+	for (int m = 0; m < bpp; m++) {
+		bitmask <<= 1;
+		bitmask  |= 1;
+	}
+
+	// Extract pixels from bytes
+	for (int j = 0; j < iconDataSize; j++)
+		for (b = 0; b < pixelsPerByte; b++) {
+			int idx = j * pixelsPerByte + (pixelsPerByte - 1 - b);
+
+			if (cursor[0][idx] != 0xff) // if mask is not there
+				cursor[0][idx] = (byte)((iconData[j] >> (b * bpp)) & bitmask);
+		}
+
+	free(iconData);
+
+	assert(datasize - dis.pos() == 0);
+
+	return 1;
+}
+
+
+
+void ScummEngine_v70he::readRoomsOffsets() {
+	int num, i;
+	byte *ptr;
+
+	debug(9, "readRoomOffsets()");
+
+	num = READ_LE_UINT16(_heV7RoomOffsets);
+	ptr = _heV7RoomOffsets + 2;
+	for (i = 0; i < num; i++) {
+		res.roomoffs[rtRoom][i] = READ_LE_UINT32(ptr);
+		ptr += 4;
+	}
+}
+
+void ScummEngine_v70he::readGlobalObjects() {
+	int num = _fileHandle->readUint16LE();
+	assert(num == _numGlobalObjects);
+
+	_fileHandle->read(_objectStateTable, num);
+	_fileHandle->read(_objectOwnerTable, num);
+	_fileHandle->read(_objectRoomTable, num);
+
+	_fileHandle->read(_classData, num * sizeof(uint32));
+
+#if defined(SCUMM_BIG_ENDIAN)
+	// Correct the endianess if necessary
+	for (int i = 0; i != num; i++)
+		_classData[i] = FROM_LE_32(_classData[i]);
+#endif
+}
+
+void ScummEngine_v99he::readMAXS(int blockSize) {
+	debug(0, "ScummEngine_v99he readMAXS: MAXS has blocksize %d", blockSize);
+
+	_numVariables = _fileHandle->readUint16LE();
+	_fileHandle->readUint16LE();
+	_numRoomVariables = _fileHandle->readUint16LE();
+	_numLocalObjects = _fileHandle->readUint16LE();
+	_numArray = _fileHandle->readUint16LE();
+	_fileHandle->readUint16LE();
+	_fileHandle->readUint16LE();
+	_numFlObject = _fileHandle->readUint16LE();
+	_numInventory = _fileHandle->readUint16LE();
+	_numRooms = _fileHandle->readUint16LE();
+	_numScripts = _fileHandle->readUint16LE();
+	_numSounds = _fileHandle->readUint16LE();
+	_numCharsets = _fileHandle->readUint16LE();
+	_numCostumes = _fileHandle->readUint16LE();
+	_numGlobalObjects = _fileHandle->readUint16LE();
+	_numImages = _fileHandle->readUint16LE();
+	_numSprites = _fileHandle->readUint16LE();
+	_numLocalScripts = _fileHandle->readUint16LE();
+	_HEHeapSize = _fileHandle->readUint16LE();
+	_numPalettes = _fileHandle->readUint16LE();
+	_numUnk = _fileHandle->readUint16LE();
+	_numTalkies = _fileHandle->readUint16LE();
+	_numNewNames = 10;
+
+	_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
+	_numGlobalScripts = 2048;
+}
+
+void ScummEngine_v90he::readMAXS(int blockSize) {
+	debug(0, "ScummEngine_v90he readMAXS: MAXS has blocksize %d", blockSize);
+
+	_numVariables = _fileHandle->readUint16LE();
+	_fileHandle->readUint16LE();
+	_numRoomVariables = _fileHandle->readUint16LE();
+	_numLocalObjects = _fileHandle->readUint16LE();
+	_numArray = _fileHandle->readUint16LE();
+	_fileHandle->readUint16LE();
+	_fileHandle->readUint16LE();
+	_numFlObject = _fileHandle->readUint16LE();
+	_numInventory = _fileHandle->readUint16LE();
+	_numRooms = _fileHandle->readUint16LE();
+	_numScripts = _fileHandle->readUint16LE();
+	_numSounds = _fileHandle->readUint16LE();
+	_numCharsets = _fileHandle->readUint16LE();
+	_numCostumes = _fileHandle->readUint16LE();
+	_numGlobalObjects = _fileHandle->readUint16LE();
+	_numImages = _fileHandle->readUint16LE();
+	_numSprites = _fileHandle->readUint16LE();
+	_numLocalScripts = _fileHandle->readUint16LE();
+	_HEHeapSize = _fileHandle->readUint16LE();
+	_numNewNames = 10;
+
+	_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
+	if (_features & GF_HE_985)
+		_numGlobalScripts = 2048;
+	else
+		_numGlobalScripts = 200;
+}
+
+void ScummEngine_v72he::readMAXS(int blockSize) {
+	debug(0, "ScummEngine_v72he readMAXS: MAXS has blocksize %d", blockSize);
+
+	_numVariables = _fileHandle->readUint16LE();
+	_fileHandle->readUint16LE();
+	_numBitVariables = _numRoomVariables = _fileHandle->readUint16LE();
+	_numLocalObjects = _fileHandle->readUint16LE();
+	_numArray = _fileHandle->readUint16LE();
+	_fileHandle->readUint16LE();
+	_numVerbs = _fileHandle->readUint16LE();
+	_numFlObject = _fileHandle->readUint16LE();
+	_numInventory = _fileHandle->readUint16LE();
+	_numRooms = _fileHandle->readUint16LE();
+	_numScripts = _fileHandle->readUint16LE();
+	_numSounds = _fileHandle->readUint16LE();
+	_numCharsets = _fileHandle->readUint16LE();
+	_numCostumes = _fileHandle->readUint16LE();
+	_numGlobalObjects = _fileHandle->readUint16LE();
+	_numImages = _fileHandle->readUint16LE();
+	_numNewNames = 10;
+
+	_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
+	_numGlobalScripts = 200;
+}
+
+byte *ScummEngine_v72he::getStringAddress(int i) {
+	byte *addr = getResourceAddress(rtString, i);
+	if (addr == NULL)
+		return NULL;
+	return ((ScummEngine_v72he::ArrayHeader *)addr)->data;
+}
+
+int ScummEngine_v72he::getSoundResourceSize(int id) {
+	const byte *ptr;
+	int offs, size;
+
+	if (id > _numSounds) {
+		if (!_sound->getHEMusicDetails(id, offs, size)) {
+			debug(0, "getSoundResourceSize: musicID %d not found", id);
+			return 0;
+		}
+	} else {
+		ptr = getResourceAddress(rtSound, id);
+		if (!ptr)
+			return 0;
+
+		if (READ_UINT32(ptr) == MKID('RIFF')) {
+			byte flags;
+			int rate;
+
+			size = READ_BE_UINT32(ptr + 4);
+			Common::MemoryReadStream stream(ptr, size);
+
+			if (!loadWAVFromStream(stream, size, rate, flags)) {
+				error("getSoundResourceSize: Not a valid WAV file");
+			}
+		} else {
+			ptr += 8 + READ_BE_UINT32(ptr + 12);
+			if (READ_UINT32(ptr) == MKID('SBNG')) {
+				ptr += READ_BE_UINT32(ptr + 4);
+			}
+
+			assert(READ_UINT32(ptr) == MKID('SDAT'));
+			size = READ_BE_UINT32(ptr + 4) - 8;
+		}
+	}
+
+	return size;
+}
+
+void ScummEngine_v80he::createSound(int snd1id, int snd2id) {
+	debug(0, "createSound: snd1id %d snd2id %d", snd1id, snd2id);
+
+	byte *snd1Ptr, *snd2Ptr;
+	byte *sbng1Ptr, *sbng2Ptr;
+	byte *sdat1Ptr, *sdat2Ptr;
+	byte *src, *dst, *tmp;
+	int len, offs, size;
+	int sdat1size, sdat2size;
+
+	if (snd2id == -1) {
+		_sndPtrOffs = 0;
+		_sndTmrOffs = 0;
+		return;
+	}
+
+	if (snd1id != _curSndId) {
+		_curSndId = snd1id;
+		_sndPtrOffs = 0;
+		_sndTmrOffs = 0;
+	}
+
+	snd1Ptr = getResourceAddress(rtSound, snd1id);
+	assert(snd1Ptr);
+	snd2Ptr = getResourceAddress(rtSound, snd2id);
+	assert(snd2Ptr);
+
+	int i;
+	int chan = -1;
+	for (i = 0; i < ARRAYSIZE(_sound->_heChannel); i++) {
+		if (_sound->_heChannel[i].sound == snd1id)
+			chan =  i;
+	}
+
+	sbng1Ptr = heFindResource(MKID('SBNG'), snd1Ptr);
+	sbng2Ptr = heFindResource(MKID('SBNG'), snd2Ptr);
+
+	if (sbng1Ptr != NULL && sbng2Ptr != NULL) {
+		if (chan != -1 && _sound->_heChannel[chan].codeOffs > 0) {
+			int curOffs = _sound->_heChannel[chan].codeOffs;
+
+			src = snd1Ptr + curOffs;
+			dst = sbng1Ptr + 8;
+			size = READ_BE_UINT32(sbng1Ptr + 4);
+			len = sbng1Ptr - snd1Ptr + size - curOffs;
+
+			byte *data = (byte *)malloc(len);
+			memcpy(data, src, len);
+			memcpy(dst, data, len);
+			free(data);
+
+			dst = sbng1Ptr + 8;
+			while ((size = READ_LE_UINT16(dst)) != 0)
+				dst += size;
+		} else {
+			dst = sbng1Ptr + 8;
+		}
+
+		_sound->_heChannel[chan].codeOffs = sbng1Ptr - snd1Ptr + 8;
+
+		tmp = sbng2Ptr + 8;
+		while ((offs = READ_LE_UINT16(tmp)) != 0) {
+			tmp += offs;
+		}
+
+		src = sbng2Ptr + 8;
+		len = tmp - sbng2Ptr - 6;
+		memcpy(dst, src, len);
+
+		int32 time;
+		while ((size = READ_LE_UINT16(dst)) != 0) {
+			time = READ_LE_UINT32(dst + 2);
+			time += _sndTmrOffs;
+			WRITE_LE_UINT32(dst + 2, time);
+			dst += size;
+		}
+	}
+
+	sdat1Ptr = heFindResource(MKID('SDAT'), snd1Ptr);
+	assert(sdat1Ptr);
+	sdat2Ptr = heFindResource(MKID('SDAT'), snd2Ptr);
+	assert(sdat2Ptr);
+
+	sdat1size = READ_BE_UINT32(sdat1Ptr + 4) - 8 - _sndPtrOffs;
+	sdat2size = READ_BE_UINT32(sdat2Ptr + 4) - 8;
+
+	debug(0, "SDAT size1 %d size2 %d", sdat1size, sdat2size);
+	if (sdat2size < sdat1size) {
+		src = sdat2Ptr + 8;
+		dst = sdat1Ptr + 8 + _sndPtrOffs;
+		len = sdat2size;
+		
+		memcpy(dst, src, len);
+
+		_sndPtrOffs += sdat2size;
+		_sndTmrOffs += sdat2size;
+	} else {
+		src = sdat2Ptr + 8;
+		dst = sdat1Ptr + 8 + _sndPtrOffs;
+		len = sdat1size;
+		
+		memcpy(dst, src, len);
+
+		if (sdat2size != sdat1size) {
+			src = sdat2Ptr + 8 + sdat1size;
+			dst = sdat1Ptr + 8;
+			len = sdat2size - sdat1size;
+		
+			memcpy(dst, src, len);
+		}
+
+		_sndPtrOffs = sdat2size - sdat1size;
+		_sndTmrOffs += sdat2size;
+	}
+}
+
+} // End of namespace Scumm

Copied: scummvm/trunk/engines/scumm/he/resource_he.h (from rev 20696, scummvm/trunk/engines/scumm/he/resource_v7he.h)
===================================================================
--- scummvm/trunk/engines/scumm/he/resource_he.h	                        (rev 0)
+++ scummvm/trunk/engines/scumm/he/resource_he.h	2006-02-15 18:48:49 UTC (rev 20703)
@@ -0,0 +1,556 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004-2006 The ScummVM project
+ *
+ * Parts of code heavily based on:
+ * icoutils - A set of programs dealing with MS Windows icons and cursors.
+ * Copyright (C) 1998-2001 Oskar Liljeblad
+ *
+ * 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$
+ *
+ */
+
+#if !defined(RESOURCE_HE_H) && !defined(DISABLE_HE)
+#define RESOURCE_HE_H
+
+namespace Scumm {
+
+#define WINRES_ID_MAXLEN (256)
+
+/*
+ * Definitions
+ */
+
+#define ACTION_LIST 				1	/* command: list resources */
+#define ACTION_EXTRACT				2	/* command: extract resources */
+#define CALLBACK_STOP				0	/* results of ResourceCallback */
+#define CALLBACK_CONTINUE			1
+#define CALLBACK_CONTINUE_RECURS	2
+
+#define MZ_HEADER(x)	((DOSImageHeader *)(x))
+#define NE_HEADER(x)	((OS2ImageHeader *)PE_HEADER(x))
+#define NE_TYPEINFO_NEXT(x) ((Win16NETypeInfo *)((byte *)(x) + sizeof(Win16NETypeInfo) + \
+						    ((Win16NETypeInfo *)x)->count * sizeof(Win16NENameInfo)))
+#define NE_RESOURCE_NAME_IS_NUMERIC (0x8000)
+
+#define STRIP_RES_ID_FORMAT(x) (x != NULL && (x[0] == '-' || x[0] == '+') ? ++x : x)
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+#define IMAGE_SIZEOF_SHORT_NAME 8
+
+#define	IMAGE_RESOURCE_NAME_IS_STRING		0x80000000
+#define	IMAGE_RESOURCE_DATA_IS_DIRECTORY	0x80000000
+
+#define PE_HEADER(module) \
+    ((Win32ImageNTHeaders*)((byte *)(module) + \
+    	(((DOSImageHeader*)(module))->lfanew)))
+
+#define PE_SECTIONS(module) \
+    ((Win32ImageSectionHeader *)((byte *) &PE_HEADER(module)->optional_header + \
+                           PE_HEADER(module)->file_header.size_of_optional_header))
+
+#define IMAGE_DOS_SIGNATURE    0x5A4D     /* MZ */
+#define IMAGE_OS2_SIGNATURE    0x454E     /* NE */
+#define IMAGE_OS2_SIGNATURE_LE 0x454C     /* LE */
+#define IMAGE_OS2_SIGNATURE_LX 0x584C     /* LX */
+#define IMAGE_VXD_SIGNATURE    0x454C     /* LE */
+#define IMAGE_NT_SIGNATURE     0x00004550 /* PE00 */
+
+#if !defined (WIN32)
+#define IMAGE_SCN_CNT_CODE			0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA		0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA	0x00000080
+#endif
+
+#define	IMAGE_DIRECTORY_ENTRY_EXPORT		0
+#define	IMAGE_DIRECTORY_ENTRY_IMPORT		1
+#define	IMAGE_DIRECTORY_ENTRY_RESOURCE		2
+#define	IMAGE_DIRECTORY_ENTRY_EXCEPTION		3
+#define	IMAGE_DIRECTORY_ENTRY_SECURITY		4
+#define	IMAGE_DIRECTORY_ENTRY_BASERELOC		5
+#define	IMAGE_DIRECTORY_ENTRY_DEBUG			6
+#define	IMAGE_DIRECTORY_ENTRY_COPYRIGHT		7
+#define	IMAGE_DIRECTORY_ENTRY_GLOBALPTR		8   /* (MIPS GP) */
+#define	IMAGE_DIRECTORY_ENTRY_TLS			9
+#define	IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG	10
+#define	IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT	11
+#define	IMAGE_DIRECTORY_ENTRY_IAT			12  /* Import Address Table */
+#define	IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT	13
+#define	IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR	14
+
+#if !defined (WIN32)
+#define RT_CURSOR        1
+#define RT_BITMAP        2
+#define RT_ICON          3
+#define RT_MENU          4
+#define RT_DIALOG        5
+#define RT_STRING        6
+#define RT_FONTDIR       7
+#define RT_FONT          8
+#define RT_ACCELERATOR   9
+#define RT_RCDATA        10
+#define RT_MESSAGELIST   11
+#define RT_GROUP_CURSOR  12
+#define RT_GROUP_ICON    14
+#endif
+
+#define RETURN_IF_BAD_POINTER(r, x) \
+	if (!check_offset(fi->memory, fi->total_size, fi->file->name(), &(x), sizeof(x))) \
+		return (r);
+#define RETURN_IF_BAD_OFFSET(r, x, s) \
+	if (!check_offset(fi->memory, fi->total_size, fi->file->name(), x, s)) \
+		return (r);
+
+class ScummEngine_v70he;
+
+class ResExtractor {
+public:
+	ResExtractor(ScummEngine_v70he *scumm);
+	virtual ~ResExtractor();
+
+	void setCursor(int id);
+
+	virtual int extractResource(int id, byte **buf) { return 0; };
+	virtual int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
+							 int *hotspot_x, int *hotspot_y, int *keycolor,
+							 byte **palette, int *palSize) { return 0; };
+
+	enum {
+		MAX_CACHED_CURSORS = 10
+	};
+
+	struct CachedCursor {
+		bool valid;
+		int id;
+		byte *bitmap;
+		int w, h;
+		int hotspot_x, hotspot_y;
+		uint32 last_used;
+		byte *palette;
+		int palSize;
+	};
+
+	ScummEngine_v70he *_vm;
+
+	ResExtractor::CachedCursor *findCachedCursor(int id);
+	ResExtractor::CachedCursor *getCachedCursorSlot();
+
+	bool _arg_raw;
+	char _fileName[256];
+	CachedCursor _cursorCache[MAX_CACHED_CURSORS];
+
+	typedef Common::MemoryReadStream MemoryReadStream;
+
+};
+
+class Win32ResExtractor : public ResExtractor {
+ public:
+	Win32ResExtractor(ScummEngine_v70he *scumm);
+	~Win32ResExtractor() {};
+	int extractResource(int id, byte **data);
+	void setCursor(int id);
+	int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
+			 int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
+
+ private:
+	int extractResource_(const char *resType, char *resName, byte **data);
+/*
+ * Structures
+ */
+
+#if !defined(__GNUC__)
+	#pragma START_PACK_STRUCTS
+#endif
+
+	struct WinLibrary {
+		Common::File *file;
+		byte *memory;
+		byte *first_resource;
+		bool is_PE_binary;
+		int total_size;
+	};
+
+	struct WinResource {
+		char id[256];
+		void *this_;
+		void *children;
+		int level;
+		bool numeric_id;
+		bool is_directory;
+	};
+
+
+	struct Win32IconResDir {
+		byte width;
+		byte height;
+		byte color_count;
+		byte reserved;
+	};
+
+	struct Win32CursorDir {
+		uint16 width;
+		uint16 height;
+	};
+
+	struct Win32CursorIconDirEntry {
+		union {
+			Win32IconResDir icon;
+			Win32CursorDir cursor;
+		} res_info;
+		uint16 plane_count;
+		uint16 bit_count;
+		uint32 bytes_in_res;
+		uint16 res_id;
+	};
+
+	struct Win32CursorIconDir {
+		uint16 reserved;
+		uint16 type;
+		uint16 count;
+		Win32CursorIconDirEntry entries[1] GCC_PACK;
+	};
+
+	struct Win32CursorIconFileDirEntry {
+		byte width;
+		byte height;
+		byte color_count;
+		byte reserved;
+		uint16 hotspot_x;
+		uint16 hotspot_y;
+		uint32 dib_size;
+		uint32 dib_offset;
+	};
+
+	struct Win32CursorIconFileDir {
+		uint16 reserved;
+		uint16 type;
+		uint16 count;
+		Win32CursorIconFileDirEntry entries[1];
+	};
+
+	struct Win32BitmapInfoHeader {
+		uint32 size;
+		int32 width;
+		int32 height;
+		uint16 planes;
+		uint16 bit_count;
+		uint32 compression;
+		uint32 size_image;
+		int32 x_pels_per_meter;
+		int32 y_pels_per_meter;
+		uint32 clr_used;
+		uint32 clr_important;
+	};
+
+	struct Win32RGBQuad {
+		byte blue;
+		byte green;
+		byte red;
+		byte reserved;
+	};
+
+	struct Win32ImageResourceDirectoryEntry {
+		union {
+			struct {
+				#ifdef SCUMM_BIGENDIAN
+				unsigned name_is_string:1;
+				unsigned name_offset:31;
+	    	    #else
+				unsigned name_offset:31;
+				unsigned name_is_string:1;
+	    	    #endif
+			} s1;
+			uint32 name;
+			struct {
+	    	    #ifdef SCUMM_BIG_ENDIAN
+				uint16 __pad;
+				uint16 id;
+	    	    #else
+				uint16 id;
+				uint16 __pad;
+	    	    #endif
+			} s2;
+		} u1;
+		union {
+			uint32 offset_to_data;
+			struct {
+	    	    #ifdef SCUMM_BIG_ENDIAN
+				unsigned data_is_directory:1;
+				unsigned offset_to_directory:31;
+	    	    #else
+				unsigned offset_to_directory:31;
+				unsigned data_is_directory:1;
+	    	    #endif
+			} s;
+		} u2;
+	};
+
+	struct Win16NETypeInfo {
+		uint16 type_id;
+		uint16 count;
+		uint32 resloader;     // FARPROC16 - smaller? uint16?
+	};
+
+	struct Win16NENameInfo {
+		uint16 offset;
+		uint16 length;
+		uint16 flags;
+		uint16 id;
+		uint16 handle;
+		uint16 usage;
+	};
+
+	struct OS2ImageHeader {
+		uint16 magic;
+		byte ver;
+		byte rev;
+		uint16 enttab;
+		uint16 cbenttab;
+		int32 crc;
+		uint16 flags;
+		uint16 autodata;
+		uint16 heap;
+		uint16 stack;
+		uint32 csip;
+		uint32 sssp;
+		uint16 cseg;
+		uint16 cmod;
+		uint16 cbnrestab;
+		uint16 segtab;
+		uint16 rsrctab;
+		uint16 restab;
+		uint16 modtab;
+		uint16 imptab;
+		uint32 nrestab;
+		uint16 cmovent;
+		uint16 align;
+		uint16 cres;
+		byte exetyp;
+		byte flagsothers;
+		uint16 fastload_offset;
+		uint16 fastload_length;
+		uint16 swaparea;
+		uint16 expver;
+	};
+
+	struct DOSImageHeader {
+		uint16 magic;
+		uint16 cblp;
+		uint16 cp;
+		uint16 crlc;
+		uint16 cparhdr;
+		uint16 minalloc;
+		uint16 maxalloc;
+		uint16 ss;
+		uint16 sp;
+		uint16 csum;
+		uint16 ip;
+		uint16 cs;
+		uint16 lfarlc;
+		uint16 ovno;
+		uint16 res[4];
+		uint16 oemid;
+		uint16 oeminfo;
+		uint16 res2[10];
+		uint32 lfanew;
+	};
+
+	struct Win32ImageFileHeader {
+		uint16 machine;
+		uint16 number_of_sections;
+		uint32 time_date_stamp;
+		uint32 pointer_to_symbol_table;
+		uint32 number_of_symbols;
+		uint16 size_of_optional_header;
+		uint16 characteristics;
+	};
+
+	struct Win32ImageDataDirectory {
+		uint32 virtual_address;
+		uint32 size;
+	};
+
+	struct Win32ImageOptionalHeader {
+		uint16 magic;
+		byte major_linker_version;
+		byte minor_linker_version;
+		uint32 size_of_code;
+		uint32 size_of_initialized_data;
+		uint32 size_of_uninitialized_data;
+		uint32 address_of_entry_point;
+		uint32 base_of_code;
+		uint32 base_of_data;
+		uint32 image_base;
+		uint32 section_alignment;
+		uint32 file_alignment;
+		uint16 major_operating_system_version;
+		uint16 minor_operating_system_version;
+		uint16 major_image_version;
+		uint16 minor_image_version;
+		uint16 major_subsystem_version;
+		uint16 minor_subsystem_version;
+		uint32 win32_version_value;
+		uint32 size_of_image;
+		uint32 size_of_headers;
+		uint32 checksum;
+		uint16 subsystem;
+		uint16 dll_characteristics;
+		uint32 size_of_stack_reserve;
+		uint32 size_of_stack_commit;
+		uint32 size_of_heap_reserve;
+		uint32 size_of_heap_commit;
+		uint32 loader_flags;
+		uint32 number_of_rva_and_sizes;
+		Win32ImageDataDirectory data_directory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+	};
+
+	struct Win32ImageNTHeaders {
+		uint32 signature;
+		Win32ImageFileHeader file_header;
+		Win32ImageOptionalHeader optional_header;
+	};
+
+	struct Win32ImageSectionHeader {
+		byte name[IMAGE_SIZEOF_SHORT_NAME];
+		union {
+			uint32 physical_address;
+			uint32 virtual_size;
+		} misc;
+		uint32 virtual_address;
+		uint32 size_of_raw_data;
+		uint32 pointer_to_raw_data;
+		uint32 pointer_to_relocations;
+		uint32 pointer_to_linenumbers;
+		uint16 number_of_relocations;
+		uint16 number_of_linenumbers;
+		uint32 characteristics;
+	};
+
+	struct Win32ImageResourceDataEntry {
+		uint32 offset_to_data;
+		uint32 size;
+		uint32 code_page;
+		uint32 resource_handle;
+	};
+
+	struct Win32ImageResourceDirectory {
+		uint32 characteristics;
+		uint32 time_date_stamp;
+		uint16 major_version;
+		uint16 minor_version;
+		uint16 number_of_named_entries;
+		uint16 number_of_id_entries;
+	};
+
+#if !defined(__GNUC__)
+	#pragma END_PACK_STRUCTS
+#endif
+
+/*
+ * Function Prototypes
+ */
+
+	WinResource *list_resources(WinLibrary *, WinResource *, int *);
+	bool read_library(WinLibrary *);
+	WinResource *find_resource(WinLibrary *, const char *, const char *, const char *, int *);
+	byte *get_resource_entry(WinLibrary *, WinResource *, int *);
+	int do_resources(WinLibrary *, const char *, char *, char *, int, byte **);
+	bool compare_resource_id(WinResource *, const char *);
+	const char *res_type_string_to_id(const char *);
+
+	const char *res_type_id_to_string(int);
+	char *get_destination_name(WinLibrary *, char *, char *, char *);
+
+	byte *extract_resource(WinLibrary *, WinResource *, int *, bool *, char *, char *, bool);
+	int extract_resources(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, byte **);
+	byte *extract_group_icon_cursor_resource(WinLibrary *, WinResource *, char *, int *, bool);
+
+	bool decode_pe_resource_id(WinLibrary *, WinResource *, uint32);
+	bool decode_ne_resource_id(WinLibrary *, WinResource *, uint16);
+	WinResource *list_ne_type_resources(WinLibrary *, int *);
+	WinResource *list_ne_name_resources(WinLibrary *, WinResource *, int *);
+	WinResource *list_pe_resources(WinLibrary *, Win32ImageResourceDirectory *, int, int *);
+	int calc_vma_size(WinLibrary *);
+	int do_resources_recurs(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, const char *, char *, char *, int, byte **);
+	char *get_resource_id_quoted(WinResource *);
+	WinResource *find_with_resource_array(WinLibrary *, WinResource *, const char *);
+
+	bool check_offset(byte *, int, const char *, void *, int);
+
+	uint32 simple_vec(byte *data, uint32 ofs, byte size);
+
+	void fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj);
+	void fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj);
+	void fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj);
+	void fix_win32_image_section_header(Win32ImageSectionHeader *obj);
+	void fix_os2_image_header_endian(OS2ImageHeader *obj);
+	void fix_win32_image_header_endian(Win32ImageNTHeaders *obj);
+	void fix_win32_image_data_directory(Win32ImageDataDirectory *obj);
+};
+
+class MacResExtractor : public ResExtractor {
+
+public:
+	MacResExtractor(ScummEngine_v70he *scumm);
+	~MacResExtractor() { }
+	void setCursor(int id) ;
+
+private:
+	int extractResource(int id, byte **buf);
+	bool init(Common::File in);
+	void readMap(Common::File in);
+	byte *getResource(Common::File in, const char *typeID, int16 resID, int *size);
+	int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
+			 int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
+
+	struct ResMap {
+		int16 resAttr;
+		int16 typeOffset;
+		int16 nameOffset;
+		int16 numTypes;
+	};
+
+	struct ResType {
+		char  id[5];
+		int16 items;
+		int16 offset;
+	};
+
+	struct Resource {
+		int16 id;
+		int16 nameOffset;
+		byte  attr;
+		int32 dataOffset;
+		byte  *name;
+	};
+
+	typedef Resource *ResPtr;
+
+private:
+	int _resOffset;
+	int32 _dataOffset;
+	int32 _dataLength;
+	int32 _mapOffset;
+	int32 _mapLength;
+	ResMap _resMap;
+	ResType *_resTypes;
+	ResPtr  *_resLists;
+};
+
+} // End of namespace Scumm
+
+#endif

Deleted: scummvm/trunk/engines/scumm/he/resource_v7he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/resource_v7he.cpp	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/he/resource_v7he.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -1,1912 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2004-2006 The ScummVM project
- *
- * Parts of code heavily based on:
- * icoutils - A set of programs dealing with MS Windows icons and cursors.
- * Copyright (C) 1998-2001 Oskar Liljeblad
- *
- * 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 "scumm/scumm.h"
-#include "scumm/he/intern_he.h"
-#include "scumm/resource.h"
-#include "scumm/he/resource_v7he.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-#include "sound/wave.h"
-
-#include "common/stream.h"
-#include "common/system.h"
-
-namespace Scumm {
-
-ResExtractor::ResExtractor(ScummEngine_v70he *scumm)
-	: _vm(scumm) {
-
-	_fileName[0] = 0;
-	memset(_cursorCache, 0, sizeof(_cursorCache));
-}
-
-ResExtractor::~ResExtractor() {
-	for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
-		CachedCursor *cc = &_cursorCache[i];
-		if (cc->valid) {
-			free(cc->bitmap);
-			free(cc->palette);
-		}
-	}
-	memset(_cursorCache, 0, sizeof(_cursorCache));
-}
-
-ResExtractor::CachedCursor *ResExtractor::findCachedCursor(int id) {
-	for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
-		CachedCursor *cc = &_cursorCache[i];
-		if (cc->valid && cc->id == id) {
-			return cc;
-		}
-	}
-	return NULL;
-}
-
-ResExtractor::CachedCursor *ResExtractor::getCachedCursorSlot() {
-	uint32 min_last_used = 0;
-	CachedCursor *r = NULL;
-	for (int i = 0; i < MAX_CACHED_CURSORS; ++i) {
-		CachedCursor *cc = &_cursorCache[i];
-		if (!cc->valid) {
-			return cc;
-		} else {
-			if (min_last_used == 0 || cc->last_used < min_last_used) {
-				min_last_used = cc->last_used;
-				r = cc;
-			}
-		}
-	}
-	assert(r);
-	free(r->bitmap);
-	free(r->palette);
-	memset(r, 0, sizeof(CachedCursor));
-	return r;
-}
-
-void ResExtractor::setCursor(int id) {
-	byte *cursorRes = 0;
-	int cursorsize;
-	int keycolor = 0;
-	CachedCursor *cc = findCachedCursor(id);
-	if (cc != NULL) {
-		debug(7, "Found cursor %d in cache slot %d", id, cc - _cursorCache);
-	} else {
-		cc = getCachedCursorSlot();
-		assert(cc && !cc->valid);
-		cursorsize = extractResource(id, &cursorRes);
-		convertIcons(cursorRes, cursorsize, &cc->bitmap, &cc->w, &cc->h, &cc->hotspot_x, &cc->hotspot_y, &keycolor, &cc->palette, &cc->palSize);
-		debug(7, "Adding cursor %d to cache slot %d", id, cc - _cursorCache);
-		free(cursorRes);
-		cc->valid = true;
-		cc->id = id;
-		cc->last_used = g_system->getMillis();
-	}
-
-	if (_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette) && cc->palette)
-		_vm->_system->setCursorPalette(cc->palette, 0, cc->palSize);
-
-	_vm->setCursorHotspot(cc->hotspot_x, cc->hotspot_y);
-	_vm->setCursorFromBuffer(cc->bitmap, cc->w, cc->h, cc->w);
-}
-
-
-/*
- * Static variables
- */
-const char *res_types[] = {
-	/* 0x01: */
-	"cursor", "bitmap", "icon", "menu", "dialog", "string",
-	"fontdir", "font", "accelerator", "rcdata", "messagelist",
-	"group_cursor", NULL, "group_icon", NULL,
-	/* the following are not defined in winbase.h, but found in wrc. */
-	/* 0x10: */
-	"version", "dlginclude", NULL, "plugplay", "vxd",
-	"anicursor", "aniicon"
-};
-#define RES_TYPE_COUNT (sizeof(res_types)/sizeof(char *))
-
-Win32ResExtractor::Win32ResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {
-}
-
-int Win32ResExtractor::extractResource(int resId, byte **data) {
-	char buf[20];
-
-	snprintf(buf, sizeof(buf), "%d", resId);
-
-	return extractResource_("group_cursor", buf, data);
-}
-
-int Win32ResExtractor::extractResource_(const char *resType, char *resName, byte **data) {
-	char *arg_language = NULL;
-	const char *arg_type = resType;
-	char *arg_name = resName;
-	int arg_action = ACTION_LIST;
-	int ressize = 0;
-
-	_arg_raw = false;
-
-	/* translate --type option from resource type string to integer */
-	arg_type = res_type_string_to_id(arg_type);
-
-	WinLibrary fi;
-
-	/* initiate stuff */
-	fi.memory = NULL;
-	fi.file = new Common::File;
-
-	if (!_fileName[0]) { // We are running for the first time
-		snprintf(_fileName, 256, "%s.he3", _vm->getBaseName());
-
-		if (_vm->_substResFileNameIndex > 0) {
-			char buf1[128];
-
-			_vm->generateSubstResFileName(_fileName, buf1, sizeof(buf1));
-			strcpy(_fileName, buf1);
-		}
-	}
-
-
-	/* get file size */
-	fi.file->open(_fileName);
-	if (!fi.file->isOpen()) {
-		error("Cannot open file %s", _fileName);
-	}
-
-	fi.total_size = fi.file->size();
-	if (fi.total_size == -1) {
-		error("Cannot get size of file %s", fi.file->name());
-		goto cleanup;
-	}
-	if (fi.total_size == 0) {
-		error("%s: file has a size of 0", fi.file->name());
-		goto cleanup;
-	}
-
-	/* read all of file */
-	fi.memory = (byte *)malloc(fi.total_size);
-	if (fi.file->read(fi.memory, fi.total_size) == 0) {
-		error("Cannot read from file %s", fi.file->name());
-		goto cleanup;
-	}
-
-	/* identify file and find resource table */
-	if (!read_library(&fi)) {
-		/* error reported by read_library */
-		goto cleanup;
-	}
-
-	//	verbose_printf("file is a %s\n",
-	//		fi.is_PE_binary ? "Windows NT `PE' binary" : "Windows 3.1 `NE' binary");
-
-	/* errors will be printed by the callback */
-	ressize = do_resources(&fi, arg_type, arg_name, arg_language, arg_action, data);
-
-	/* free stuff and close file */
-	cleanup:
-	if (fi.file != NULL)
-		fi.file->close();
-	if (fi.memory != NULL)
-		free(fi.memory);
-
-	return ressize;
-}
-
-
-/* res_type_id_to_string:
- *   Translate a numeric resource type to it's corresponding string type.
- *   (For informative-ness.)
- */
-const char *Win32ResExtractor::res_type_id_to_string(int id) {
-	if (id == 241)
-		return "toolbar";
-	if (id > 0 && id <= (int)RES_TYPE_COUNT)
-		return res_types[id-1];
-	return NULL;
-}
-
-/* res_type_string_to_id:
- *   Translate a resource type string to integer.
- *   (Used to convert the --type option.)
- */
-const char *Win32ResExtractor::res_type_string_to_id(const char *type) {
-	static const char *res_type_ids[] = {
-		"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9", "-10",
-		"-11", "-12", NULL, "-14", NULL, "-16", "-17", NULL, "-19",
-		"-20", "-21", "-22"
-	};
-	int c;
-
-	if (type == NULL)
-		return NULL;
-
-	for (c = 0 ; c < (int)RES_TYPE_COUNT ; c++) {
-		if (res_types[c] != NULL && !scumm_stricmp(type, res_types[c]))
-			return res_type_ids[c];
-	}
-
-	return type;
-}
-
-int Win32ResExtractor::extract_resources(WinLibrary *fi, WinResource *wr,
-                            WinResource *type_wr, WinResource *name_wr,
-							WinResource *lang_wr, byte **data) {
-	int size;
-	bool free_it;
-	const char *type;
-	int32 id;
-
-	if (*data) {
-		error("Win32ResExtractor::extract_resources() more than one cursor");
-		return 0;
-	}
-
-	*data = extract_resource(fi, wr, &size, &free_it, type_wr->id, (lang_wr == NULL ? NULL : lang_wr->id), _arg_raw);
-
-	if (data == NULL) {
-		error("Win32ResExtractor::extract_resources() problem with resource extraction");
-		return 0;
-	}
-
-	/* get named resource type if possible */
-	type = NULL;
-	if ((id = strtol(type_wr->id, 0, 10)) != 0)
-		type = res_type_id_to_string(id);
-
-	debugC(DEBUG_RESOURCE, "extractCursor(). Found cursor name: %s%s%s [size=%d]",
-	  get_resource_id_quoted(name_wr),
-	  (lang_wr->id[0] != '\0' ? " language: " : ""),
-	  get_resource_id_quoted(lang_wr), size);
-
-	return size;
-}
-
-/* extract_resource:
- *   Extract a resource, returning pointer to data.
- */
-byte *Win32ResExtractor::extract_resource(WinLibrary *fi, WinResource *wr, int *size,
-                  bool *free_it, char *type, char *lang, bool raw) {
-	char *str;
-	int32 intval;
-
-	/* just return pointer to data if raw */
-	if (raw) {
-		*free_it = false;
-		/* get_resource_entry will print possible error */
-		return get_resource_entry(fi, wr, size);
-	}
-
-	/* find out how to extract */
-	str = type;
-	if (str != NULL && (intval = strtol(STRIP_RES_ID_FORMAT(str), 0, 10))) {
-		if (intval == (int)RT_GROUP_ICON) {
-			*free_it = true;
-			return extract_group_icon_cursor_resource(fi, wr, lang, size, true);
-		}
-		if (intval == (int)RT_GROUP_CURSOR) {
-			*free_it = true;
-			return extract_group_icon_cursor_resource(fi, wr, lang, size, false);
-		}
-	}
-
-	return NULL;
-}
-
-/* extract_group_icon_resource:
- *   Create a complete RT_GROUP_ICON resource, that can be written to
- *   an `.ico' file without modifications. Returns an allocated
- *   memory block that should be freed with free() once used.
- *
- *   `root' is the offset in file that specifies the resource.
- *   `base' is the offset that string pointers are calculated from.
- *   `ressize' should point to an integer variable where the size of
- *   the returned memory block will be placed.
- *   `is_icon' indicates whether resource to be extracted is icon
- *   or cursor group.
- */
-byte *Win32ResExtractor::extract_group_icon_cursor_resource(WinLibrary *fi, WinResource *wr, char *lang,
-                                   int *ressize, bool is_icon) {
-	Win32CursorIconDir *icondir;
-	Win32CursorIconFileDir *fileicondir;
-	byte *memory;
-	int c, offset, skipped;
-	int size;
-
-	/* get resource data and size */
-	icondir = (Win32CursorIconDir *)get_resource_entry(fi, wr, &size);
-	if (icondir == NULL) {
-		/* get_resource_entry will print error */
-		return NULL;
-	}
-
-	/* calculate total size of output file */
-	RETURN_IF_BAD_POINTER(NULL, icondir->count);
-	skipped = 0;
-	for (c = 0 ; c < icondir->count ; c++) {
-		int level;
-		int iconsize;
-		char name[14];
-		WinResource *fwr;
-
-		RETURN_IF_BAD_POINTER(NULL, icondir->entries[c]);
-		/*printf("%d. bytes_in_res=%d width=%d height=%d planes=%d bit_count=%d\n", c,
-			icondir->entries[c].bytes_in_res,
-			(is_icon ? icondir->entries[c].res_info.icon.width : icondir->entries[c].res_info.cursor.width),
-			(is_icon ? icondir->entries[c].res_info.icon.height : icondir->entries[c].res_info.cursor.height),
-			icondir->entries[c].plane_count,
-			icondir->entries[c].bit_count);*/
-
-		/* find the corresponding icon resource */
-		snprintf(name, sizeof(name)/sizeof(char), "-%d", icondir->entries[c].res_id);
-		fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level);
-		if (fwr == NULL) {
-			error("%s: could not find `%s' in `%s' resource.",
-					fi->file->name(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
-			return NULL;
-		}
-
-		if (get_resource_entry(fi, fwr, &iconsize) != NULL) {
-		    if (iconsize == 0) {
-				debugC(DEBUG_RESOURCE, "%s: icon resource `%s' is empty, skipping", fi->file->name(), name);
-				skipped++;
-				continue;
-		    }
-		    if ((uint32)iconsize != icondir->entries[c].bytes_in_res) {
-				debugC(DEBUG_RESOURCE, "%s: mismatch of size in icon resource `%s' and group (%d != %d)",
-					fi->file->name(), name, iconsize, icondir->entries[c].bytes_in_res);
-		    }
-		    size += iconsize; /* size += icondir->entries[c].bytes_in_res; */
-
-		    /* cursor resources have two additional WORDs that contain
-		     * hotspot info */
-		    if (!is_icon)
-			size -= sizeof(uint16)*2;
-		}
-	}
-	offset = sizeof(Win32CursorIconFileDir) + (icondir->count-skipped) * sizeof(Win32CursorIconFileDirEntry);
-	size += offset;
-	*ressize = size;
-
-	/* allocate that much memory */
-	memory = (byte *)malloc(size);
-	fileicondir = (Win32CursorIconFileDir *)memory;
-
-	/* transfer Win32CursorIconDir structure members */
-	fileicondir->reserved = icondir->reserved;
-	fileicondir->type = icondir->type;
-	fileicondir->count = icondir->count - skipped;
-
-	/* transfer each cursor/icon: Win32CursorIconDirEntry and data */
-	skipped = 0;
-	for (c = 0 ; c < icondir->count ; c++) {
-		int level;
-		char name[14];
-		WinResource *fwr;
-		byte *data;
-
-		/* find the corresponding icon resource */
-		snprintf(name, sizeof(name)/sizeof(char), "-%d", icondir->entries[c].res_id);
-		fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level);
-		if (fwr == NULL) {
-			error("%s: could not find `%s' in `%s' resource.",
-				fi->file->name(), &name[1], (is_icon ? "group_icon" : "group_cursor"));
-			return NULL;
-		}
-
-		/* get data and size of that resource */
-		data = (byte *)get_resource_entry(fi, fwr, &size);
-		if (data == NULL) {
-			/* get_resource_entry has printed error */
-			return NULL;
-		}
-    	    	if (size == 0) {
-		    skipped++;
-		    continue;
-		}
-
-		/* copy ICONDIRENTRY (not including last dwImageOffset) */
-		memcpy(&fileicondir->entries[c-skipped], &icondir->entries[c],
-			sizeof(Win32CursorIconFileDirEntry)-sizeof(uint32));
-
-		/* special treatment for cursors */
-		if (!is_icon) {
-			fileicondir->entries[c-skipped].width = icondir->entries[c].res_info.cursor.width;
-			fileicondir->entries[c-skipped].height = icondir->entries[c].res_info.cursor.height / 2;
-			fileicondir->entries[c-skipped].color_count = 0;
-			fileicondir->entries[c-skipped].reserved = 0;
-		}
-
-		/* set image offset and increase it */
-		fileicondir->entries[c-skipped].dib_offset = offset;
-
-		/* transfer resource into file memory */
-		if (is_icon) {
-			memcpy(&memory[offset], data, icondir->entries[c].bytes_in_res);
-		} else {
-			fileicondir->entries[c-skipped].hotspot_x = ((uint16 *) data)[0];
-			fileicondir->entries[c-skipped].hotspot_y = ((uint16 *) data)[1];
-			memcpy(&memory[offset], data+sizeof(uint16)*2,
-				   icondir->entries[c].bytes_in_res-sizeof(uint16)*2);
-			offset -= sizeof(uint16)*2;
-		}
-
-		/* increase the offset pointer */
-		offset += icondir->entries[c].bytes_in_res;
-	}
-
-	return memory;
-}
-
-/* check_offset:
- *   Check if a chunk of data (determined by offset and size)
- *   is within the bounds of the WinLibrary file.
- *   Usually not called directly.
- */
-bool Win32ResExtractor::check_offset(byte *memory, int total_size, const char *name, void *offset, int size) {
-	int need_size = (int)((byte *)offset - memory + size);
-
-	debugC(DEBUG_RESOURCE, "check_offset: size=%x vs %x offset=%x size=%x",
-		need_size, total_size, (byte *)offset - memory, size);
-
-	if (need_size < 0 || need_size > total_size) {
-		error("%s: premature end", name);
-		return false;
-	}
-
-	return true;
-}
-
-
-/* do_resources:
- *   Do something for each resource matching type, name and lang.
- */
-int Win32ResExtractor::do_resources(WinLibrary *fi, const char *type, char *name, char *lang, int action, byte **data) {
-	WinResource *type_wr;
-	WinResource *name_wr;
-	WinResource *lang_wr;
-	int size;
-
-	type_wr = (WinResource *)calloc(sizeof(WinResource)*3, 1);
-	name_wr = type_wr + 1;
-	lang_wr = type_wr + 2;
-
-	size = do_resources_recurs(fi, NULL, type_wr, name_wr, lang_wr, type, name, lang, action, data);
-
-	free(type_wr);
-
-	return size;
-}
-
-/* what is each entry in this directory level for? type, name or language? */
-#define WINRESOURCE_BY_LEVEL(x) ((x)==0 ? type_wr : ((x)==1 ? name_wr : lang_wr))
-
-/* does the id of this entry match the specified id? */
-#define LEVEL_MATCHES(x) (x == NULL || x ## _wr->id[0] == '\0' || compare_resource_id(x ## _wr, x))
-
-int Win32ResExtractor::do_resources_recurs(WinLibrary *fi, WinResource *base,
-		  WinResource *type_wr, WinResource *name_wr, WinResource *lang_wr,
-		  const char *type, char *name, char *lang, int action, byte **data) {
-	int c, rescnt;
-	WinResource *wr;
-	uint32 size = 0;
-
-	/* get a list of all resources at this level */
-	wr = list_resources(fi, base, &rescnt);
-	if (wr == NULL)
-		if (size != 0)
-			return size;
-		else
-			return 0;
-
-	/* process each resource listed */
-	for (c = 0 ; c < rescnt ; c++) {
-		/* (over)write the corresponding WinResource holder with the current */
-		memcpy(WINRESOURCE_BY_LEVEL(wr[c].level), wr+c, sizeof(WinResource));
-
-		/* go deeper unless there is something that does NOT match */
-		if (LEVEL_MATCHES(type) && LEVEL_MATCHES(name) && LEVEL_MATCHES(lang)) {
-			if (wr->is_directory)
-				size = do_resources_recurs(fi, wr+c, type_wr, name_wr, lang_wr, type, name, lang, action, data);
-			else
-				size = extract_resources(fi, wr+c, type_wr, name_wr, lang_wr, data);
-		}
-	}
-
-	/* since we're moving back one level after this, unset the
-	 * WinResource holder used on this level */
-	memset(WINRESOURCE_BY_LEVEL(wr[0].level), 0, sizeof(WinResource));
-
-	return size;
-}
-
-/* return the resource id quoted if it's a string, otherwise just return it */
-char *Win32ResExtractor::get_resource_id_quoted(WinResource *wr) {
-	static char tmp[WINRES_ID_MAXLEN+2];
-
-	if (wr->numeric_id || wr->id[0] == '\0')
-		return wr->id;
-
-	sprintf(tmp, "'%s'", wr->id);
-	return tmp;
-}
-
-bool Win32ResExtractor::compare_resource_id(WinResource *wr, const char *id) {
-	if (wr->numeric_id) {
-		int32 cmp1, cmp2;
-		if (id[0] == '+')
-			return false;
-		if (id[0] == '-')
-			id++;
-		if (!(cmp1 = strtol(wr->id, 0, 10)) || !(cmp2 = strtol(id, 0, 10)) || cmp1 != cmp2)
-			return false;
-	} else {
-		if (id[0] == '-')
-			return false;
-		if (id[0] == '+')
-			id++;
-		if (strcmp(wr->id, id))
-			return false;
-	}
-
-	return true;
-}
-
-bool Win32ResExtractor::decode_pe_resource_id(WinLibrary *fi, WinResource *wr, uint32 value) {
-	if (value & IMAGE_RESOURCE_NAME_IS_STRING) {	/* numeric id */
-		int c, len;
-		uint16 *mem = (uint16 *)
-		  (fi->first_resource + (value & ~IMAGE_RESOURCE_NAME_IS_STRING));
-
-		/* copy each char of the string, and terminate it */
-		RETURN_IF_BAD_POINTER(false, *mem);
-		len = mem[0];
-		RETURN_IF_BAD_OFFSET(false, &mem[1], sizeof(uint16) * len);
-
-		len = MIN(mem[0], (uint16)WINRES_ID_MAXLEN);
-		for (c = 0 ; c < len ; c++)
-			wr->id[c] = mem[c+1] & 0x00FF;
-		wr->id[len] = '\0';
-	} else {					/* Unicode string id */
-		/* translate id into a string */
-		snprintf(wr->id, WINRES_ID_MAXLEN, "%d", value);
-	}
-
-	wr->numeric_id = (value & IMAGE_RESOURCE_NAME_IS_STRING ? false:true);
-	return true;
-}
-
-byte *Win32ResExtractor::get_resource_entry(WinLibrary *fi, WinResource *wr, int *size) {
-	if (fi->is_PE_binary) {
-		Win32ImageResourceDataEntry *dataent;
-
-		dataent = (Win32ImageResourceDataEntry *) wr->children;
-		RETURN_IF_BAD_POINTER(NULL, *dataent);
-		*size = dataent->size;
-		RETURN_IF_BAD_OFFSET(NULL, fi->memory + dataent->offset_to_data, *size);
-
-		return fi->memory + dataent->offset_to_data;
-	} else {
-		Win16NENameInfo *nameinfo;
-		int sizeshift;
-
-		nameinfo = (Win16NENameInfo *) wr->children;
-		sizeshift = *((uint16 *) fi->first_resource - 1);
-		*size = nameinfo->length << sizeshift;
-		RETURN_IF_BAD_OFFSET(NULL, fi->memory + (nameinfo->offset << sizeshift), *size);
-
-		return fi->memory + (nameinfo->offset << sizeshift);
-	}
-}
-
-bool Win32ResExtractor::decode_ne_resource_id(WinLibrary *fi, WinResource *wr, uint16 value) {
-	if (value & NE_RESOURCE_NAME_IS_NUMERIC) {		/* numeric id */
-		/* translate id into a string */
-		snprintf(wr->id, WINRES_ID_MAXLEN, "%d", value & ~NE_RESOURCE_NAME_IS_NUMERIC);
-	} else {					/* ASCII string id */
-		int len;
-		char *mem = (char *)NE_HEADER(fi->memory)
-		                     + NE_HEADER(fi->memory)->rsrctab
-		                     + value;
-
-		/* copy each char of the string, and terminate it */
-		RETURN_IF_BAD_POINTER(false, *mem);
-		len = mem[0];
-		RETURN_IF_BAD_OFFSET(false, &mem[1], sizeof(char) * len);
-		memcpy(wr->id, &mem[1], len);
-		wr->id[len] = '\0';
-	}
-
-	wr->numeric_id = (value & NE_RESOURCE_NAME_IS_NUMERIC ? true:false);
-	return true;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::list_pe_resources(WinLibrary *fi, Win32ImageResourceDirectory *pe_res, int level, int *count) {
-	WinResource *wr;
-	int c, rescnt;
-	Win32ImageResourceDirectoryEntry *dirent
-	  = (Win32ImageResourceDirectoryEntry *)(pe_res + 1);
-
-	/* count number of `type' resources */
-	RETURN_IF_BAD_POINTER(NULL, *dirent);
-	rescnt = pe_res->number_of_named_entries + pe_res->number_of_id_entries;
-	*count = rescnt;
-
-	/* allocate WinResource's */
-	wr = (WinResource *)malloc(sizeof(WinResource) * rescnt);
-
-	/* fill in the WinResource's */
-	for (c = 0 ; c < rescnt ; c++) {
-		RETURN_IF_BAD_POINTER(NULL, dirent[c]);
-		wr[c].this_ = pe_res;
-		wr[c].level = level;
-		wr[c].is_directory = (dirent[c].u2.s.data_is_directory);
-		wr[c].children = fi->first_resource + dirent[c].u2.s.offset_to_directory;
-
-		/* fill in wr->id, wr->numeric_id */
-		if (!decode_pe_resource_id (fi, wr + c, dirent[c].u1.name))
-			return NULL;
-	}
-
-	return wr;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::list_ne_name_resources(WinLibrary *fi, WinResource *typeres, int *count) {
-	int c, rescnt;
-	WinResource *wr;
-	Win16NETypeInfo *typeinfo = (Win16NETypeInfo *) typeres->this_;
-	Win16NENameInfo *nameinfo = (Win16NENameInfo *) typeres->children;
-
-	/* count number of `type' resources */
-	RETURN_IF_BAD_POINTER(NULL, typeinfo->count);
-	*count = rescnt = typeinfo->count;
-
-	/* allocate WinResource's */
-	wr = (WinResource *)malloc(sizeof(WinResource) * rescnt);
-
-	/* fill in the WinResource's */
-	for (c = 0 ; c < rescnt ; c++) {
-		RETURN_IF_BAD_POINTER(NULL, nameinfo[c]);
-		wr[c].this_ = nameinfo+c;
-		wr[c].is_directory = false;
-		wr[c].children = nameinfo+c;
-		wr[c].level = 1;
-
-		/* fill in wr->id, wr->numeric_id */
-		if (!decode_ne_resource_id(fi, wr + c, (nameinfo+c)->id))
-			return NULL;
-	}
-
-	return wr;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::list_ne_type_resources(WinLibrary *fi, int *count) {
-	int c, rescnt;
-	WinResource *wr;
-	Win16NETypeInfo *typeinfo;
-
-	/* count number of `type' resources */
-	typeinfo = (Win16NETypeInfo *) fi->first_resource;
-	RETURN_IF_BAD_POINTER(NULL, *typeinfo);
-	for (rescnt = 0 ; typeinfo->type_id != 0 ; rescnt++) {
-		typeinfo = NE_TYPEINFO_NEXT(typeinfo);
-		RETURN_IF_BAD_POINTER(NULL, *typeinfo);
-	}
-	*count = rescnt;
-
-	/* allocate WinResource's */
-	wr = (WinResource *)malloc(sizeof(WinResource) * rescnt);
-
-	/* fill in the WinResource's */
-	typeinfo = (Win16NETypeInfo *) fi->first_resource;
-	for (c = 0 ; c < rescnt ; c++) {
-		wr[c].this_ = typeinfo;
-		wr[c].is_directory = (typeinfo->count != 0);
-		wr[c].children = typeinfo+1;
-		wr[c].level = 0;
-
-		/* fill in wr->id, wr->numeric_id */
-		if (!decode_ne_resource_id(fi, wr + c, typeinfo->type_id))
-			return NULL;
-
-		typeinfo = NE_TYPEINFO_NEXT(typeinfo);
-	}
-
-	return wr;
-}
-
-/* list_resources:
- *   Return an array of WinResource's in the current
- *   resource level specified by res.
- */
-Win32ResExtractor::WinResource *Win32ResExtractor::list_resources(WinLibrary *fi, WinResource *res, int *count) {
-	if (res != NULL && !res->is_directory)
-		return NULL;
-
-	if (fi->is_PE_binary) {
-		return list_pe_resources(fi, (Win32ImageResourceDirectory *)
-				 (res == NULL ? fi->first_resource : res->children),
-				 (res == NULL ? 0 : res->level+1),
-				 count);
-	} else {
-		return (res == NULL
-				? list_ne_type_resources(fi, count)
-				: list_ne_name_resources(fi, res, count));
-	}
-}
-
-/* read_library:
- *   Read header and get resource directory offset in a Windows library
- *    (AKA module).
- *
- */
-bool Win32ResExtractor::read_library(WinLibrary *fi) {
-	/* check for DOS header signature `MZ' */
-	RETURN_IF_BAD_POINTER(false, MZ_HEADER(fi->memory)->magic);
-	if (MZ_HEADER(fi->memory)->magic == IMAGE_DOS_SIGNATURE) {
-		DOSImageHeader *mz_header = MZ_HEADER(fi->memory);
-
-		RETURN_IF_BAD_POINTER(false, mz_header->lfanew);
-		if (mz_header->lfanew < sizeof(DOSImageHeader)) {
-			error("%s: not a Windows library", fi->file->name());
-			return false;
-		}
-	}
-
-	/* check for OS2 (Win16) header signature `NE' */
-	RETURN_IF_BAD_POINTER(false, NE_HEADER(fi->memory)->magic);
-	if (NE_HEADER(fi->memory)->magic == IMAGE_OS2_SIGNATURE) {
-		OS2ImageHeader *header = NE_HEADER(fi->memory);
-
-		RETURN_IF_BAD_POINTER(false, header->rsrctab);
-		RETURN_IF_BAD_POINTER(false, header->restab);
-		if (header->rsrctab >= header->restab) {
-			error("%s: no resource directory found", fi->file->name());
-			return false;
-		}
-
-		fi->is_PE_binary = false;
-		fi->first_resource = (byte *) NE_HEADER(fi->memory)
-		  + header->rsrctab + sizeof(uint16);
-		RETURN_IF_BAD_POINTER(false, *(Win16NETypeInfo *) fi->first_resource);
-
-		return true;
-	}
-
-	/* check for NT header signature `PE' */
-	RETURN_IF_BAD_POINTER(false, PE_HEADER(fi->memory)->signature);
-	if (PE_HEADER(fi->memory)->signature == IMAGE_NT_SIGNATURE) {
-		Win32ImageSectionHeader *pe_sec;
-		Win32ImageDataDirectory *dir;
-		Win32ImageNTHeaders *pe_header;
-		int d;
-
-		/* allocate new memory */
-		fi->total_size = calc_vma_size(fi);
-		if (fi->total_size == 0) {
-			/* calc_vma_size has reported error */
-			return false;
-		}
-		fi->memory = (byte *)realloc(fi->memory, fi->total_size);
-
-		/* relocate memory, start from last section */
-		pe_header = PE_HEADER(fi->memory);
-		RETURN_IF_BAD_POINTER(false, pe_header->file_header.number_of_sections);
-
-		/* we don't need to do OFFSET checking for the sections.
-		 * calc_vma_size has already done that */
-		for (d = pe_header->file_header.number_of_sections - 1; d >= 0 ; d--) {
-			pe_sec = PE_SECTIONS(fi->memory) + d;
-
-	            	if (pe_sec->characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
-			    continue;
-
-    	    	    	//if (pe_sec->virtual_address + pe_sec->size_of_raw_data > fi->total_size)
-
-    	    	    	RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->virtual_address, pe_sec->size_of_raw_data);
-    	    	    	RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->pointer_to_raw_data, pe_sec->size_of_raw_data);
-    	    	    	if (pe_sec->virtual_address != pe_sec->pointer_to_raw_data) {
-    	    	    	    memmove(fi->memory + pe_sec->virtual_address,
-				    fi->memory + pe_sec->pointer_to_raw_data,
-				    pe_sec->size_of_raw_data);
-			}
-		}
-
-		/* find resource directory */
-		RETURN_IF_BAD_POINTER(false, pe_header->optional_header.data_directory[IMAGE_DIRECTORY_ENTRY_RESOURCE]);
-		dir = pe_header->optional_header.data_directory + IMAGE_DIRECTORY_ENTRY_RESOURCE;
-		if (dir->size == 0) {
-			error("%s: file contains no resources", fi->file->name());
-			return false;
-		}
-
-		fi->first_resource = fi->memory + dir->virtual_address;
-		fi->is_PE_binary = true;
-		return true;
-	}
-
-	/* other (unknown) header signature was found */
-	error("%s: not a Windows library", fi->file->name());
-	return false;
-}
-
-/* calc_vma_size:
- *   Calculate the total amount of memory needed for a 32-bit Windows
- *   module. Returns -1 if file was too small.
- */
-int Win32ResExtractor::calc_vma_size(WinLibrary *fi) {
-    Win32ImageSectionHeader *seg;
-    int c, segcount, size;
-
-	size = 0;
-	RETURN_IF_BAD_POINTER(-1, PE_HEADER(fi->memory)->file_header.number_of_sections);
-	segcount = PE_HEADER(fi->memory)->file_header.number_of_sections;
-
-	/* If there are no segments, just process file like it is.
-	 * This is (probably) not the right thing to do, but problems
-	 * will be delt with later anyway.
-	 */
-	if (segcount == 0)
-		return fi->total_size;
-
-	seg = PE_SECTIONS(fi->memory);
-	RETURN_IF_BAD_POINTER(-1, *seg);
-    for (c = 0 ; c < segcount ; c++) {
-		RETURN_IF_BAD_POINTER(0, *seg);
-
-        size = MAX((uint32)size, seg->virtual_address + seg->size_of_raw_data);
-		/* I have no idea what misc.virtual_size is for... */
-        size = MAX((uint32)size, seg->virtual_address + seg->misc.virtual_size);
-        seg++;
-    }
-
-    return size;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::find_with_resource_array(WinLibrary *fi, WinResource *wr, const char *id) {
-	int c, rescnt;
-	WinResource *return_wr;
-
-	wr = list_resources(fi, wr, &rescnt);
-	if (wr == NULL)
-		return NULL;
-
-	for (c = 0 ; c < rescnt ; c++) {
-		if (compare_resource_id(&wr[c], id)) {
-			/* duplicate WinResource and return it */
-			return_wr = (WinResource *)malloc(sizeof(WinResource));
-			memcpy(return_wr, &wr[c], sizeof(WinResource));
-
-			/* free old WinResource */
-			free(wr);
-			return return_wr;
-		}
-	}
-
-	return NULL;
-}
-
-Win32ResExtractor::WinResource *Win32ResExtractor::find_resource(WinLibrary *fi, const char *type, const char *name, const char *language, int *level) {
-	WinResource *wr;
-
-	*level = 0;
-	if (type == NULL)
-		return NULL;
-	wr = find_with_resource_array(fi, NULL, type);
-	if (wr == NULL || !wr->is_directory)
-		return wr;
-
-	*level = 1;
-	if (name == NULL)
-		return wr;
-	wr = find_with_resource_array(fi, wr, name);
-	if (wr == NULL || !wr->is_directory)
-		return wr;
-
-	*level = 2;
-	if (language == NULL)
-		return wr;
-	wr = find_with_resource_array(fi, wr, language);
-	return wr;
-}
-
-#define ROW_BYTES(bits) ((((bits) + 31) >> 5) << 2)
-
-
-int Win32ResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
-			int *hotspot_x, int *hotspot_y, int *keycolor, byte **pal, int *palSize) {
-	Win32CursorIconFileDir dir;
-	Win32CursorIconFileDirEntry *entries = NULL;
-	uint32 offset;
-	uint32 c, d;
-	int completed;
-	int matched = 0;
-	MemoryReadStream *in = new MemoryReadStream(data, datasize);
-
-	if (!in->read(&dir, sizeof(Win32CursorIconFileDir)- sizeof(Win32CursorIconFileDirEntry)))
-		goto cleanup;
-	fix_win32_cursor_icon_file_dir_endian(&dir);
-
-	if (dir.reserved != 0) {
-		error("not an icon or cursor file (reserved non-zero)");
-		goto cleanup;
-	}
-	if (dir.type != 1 && dir.type != 2) {
-		error("not an icon or cursor file (wrong type)");
-		goto cleanup;
-	}
-
-	entries = (Win32CursorIconFileDirEntry *)malloc(dir.count * sizeof(Win32CursorIconFileDirEntry));
-	for (c = 0; c < dir.count; c++) {
-		if (!in->read(&entries[c], sizeof(Win32CursorIconFileDirEntry)))
-			goto cleanup;
-		fix_win32_cursor_icon_file_dir_entry_endian(&entries[c]);
-		if (entries[c].reserved != 0)
-			error("reserved is not zero");
-	}
-
-	offset = sizeof(Win32CursorIconFileDir) + (dir.count - 1) * (sizeof(Win32CursorIconFileDirEntry));
-
-	for (completed = 0; completed < dir.count; ) {
-		uint32 min_offset = 0x7fffffff;
-		int previous = completed;
-
-		for (c = 0; c < dir.count; c++) {
-			if (entries[c].dib_offset == offset) {
-				Win32BitmapInfoHeader bitmap;
-				Win32RGBQuad *palette = NULL;
-				uint32 palette_count = 0;
-				uint32 image_size, mask_size;
-				uint32 width, height;
-				byte *image_data = NULL, *mask_data = NULL;
-				byte *row = NULL;
-
-				if (!in->read(&bitmap, sizeof(Win32BitmapInfoHeader)))
-					goto local_cleanup;
-
-				fix_win32_bitmap_info_header_endian(&bitmap);
-				if (bitmap.size < sizeof(Win32BitmapInfoHeader)) {
-					error("bitmap header is too short");
-					goto local_cleanup;
-				}
-				if (bitmap.compression != 0) {
-					error("compressed image data not supported");
-					goto local_cleanup;
-				}
-				if (bitmap.x_pels_per_meter != 0)
-					error("x_pels_per_meter field in bitmap should be zero");
-				if (bitmap.y_pels_per_meter != 0)
-					error("y_pels_per_meter field in bitmap should be zero");
-				if (bitmap.clr_important != 0)
-					error("clr_important field in bitmap should be zero");
-				if (bitmap.planes != 1)
-					error("planes field in bitmap should be one");
-				if (bitmap.size != sizeof(Win32BitmapInfoHeader)) {
-					uint32 skip = bitmap.size - sizeof(Win32BitmapInfoHeader);
-					error("skipping %d bytes of extended bitmap header", skip);
-					in->seek(skip, SEEK_CUR);
-				}
-				offset += bitmap.size;
-
-				if (bitmap.clr_used != 0 || bitmap.bit_count < 24) {
-					palette_count = (bitmap.clr_used != 0 ? bitmap.clr_used : 1 << bitmap.bit_count);
-					palette = (Win32RGBQuad *)malloc(sizeof(Win32RGBQuad) * palette_count);
-					if (!in->read(palette, sizeof(Win32RGBQuad) * palette_count))
-						goto local_cleanup;
-					offset += sizeof(Win32RGBQuad) * palette_count;
-				}
-
-				width = bitmap.width;
-				height = ABS(bitmap.height)/2;
-
-				image_size = height * ROW_BYTES(width * bitmap.bit_count);
-				mask_size = height * ROW_BYTES(width);
-
-				if (entries[c].dib_size	!= bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad))
-					debugC(DEBUG_RESOURCE, "incorrect total size of bitmap (%d specified; %d real)",
-					    entries[c].dib_size,
-					    bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad)
-					);
-
-				image_data = (byte *)malloc(image_size);
-				if (!in->read(image_data, image_size))
-					goto local_cleanup;
-
-				mask_data = (byte *)malloc(mask_size);
-				if (!in->read(mask_data, mask_size))
-					goto local_cleanup;
-
-				offset += image_size;
-				offset += mask_size;
-				completed++;
-				matched++;
-
-				*hotspot_x = entries[c].hotspot_x;
-				*hotspot_y = entries[c].hotspot_y;
-				*w = width;
-				*h = height;
-				*keycolor = 0;
-				*cursor = (byte *)malloc(width * height);
-
-				row = (byte *)malloc(width * 4);
-
-				for (d = 0; d < height; d++) {
-					uint32 x;
-					uint32 y = (bitmap.height < 0 ? d : height - d - 1);
-					uint32 imod = y * (image_size / height) * 8 / bitmap.bit_count;
-					//uint32 mmod = y * (mask_size / height) * 8;
-
-					for (x = 0; x < width; x++) {
-
-						uint32 color = simple_vec(image_data, x + imod, bitmap.bit_count);
-
-						// FIXME?: This works only with b/w cursors and white index may be
-						// different. But now it's enough.
-						if (color) {
-							cursor[0][width * d + x] = 15; // white in SCUMM
-						} else {
-							cursor[0][width * d + x] = 255; // transparent
-						}
-						/*
-
-						if (bitmap.bit_count <= 16) {
-							if (color >= palette_count) {
-								error("color out of range in image data");
-								goto local_cleanup;
-							}
-							row[4*x+0] = palette[color].red;
-							row[4*x+1] = palette[color].green;
-							row[4*x+2] = palette[color].blue;
-
-						} else {
-							row[4*x+0] = (color >> 16) & 0xFF;
-							row[4*x+1] = (color >>  8) & 0xFF;
-							row[4*x+2] = (color >>  0) & 0xFF;
-						}
-						if (bitmap.bit_count == 32)
-						    row[4*x+3] = (color >> 24) & 0xFF;
-						else
-						    row[4*x+3] = simple_vec(mask_data, x + mmod, 1) ? 0 : 0xFF;
-						*/
-					}
-
-				}
-
-				if (row != NULL)
-					free(row);
-				if (palette != NULL)
-					free(palette);
-				if (image_data != NULL) {
-					free(image_data);
-					free(mask_data);
-				}
-				continue;
-
-			local_cleanup:
-
-				if (row != NULL)
-					free(row);
-				if (palette != NULL)
-					free(palette);
-				if (image_data != NULL) {
-					free(image_data);
-					free(mask_data);
-				}
-				goto cleanup;
-			} else {
-				if (entries[c].dib_offset > offset)
-						min_offset = MIN(min_offset, entries[c].dib_offset);
-			}
-		}
-
-		if (previous == completed) {
-			if (min_offset < offset) {
-				error("offset of bitmap header incorrect (too low)");
-				goto cleanup;
-			}
-			debugC(DEBUG_RESOURCE, "skipping %d bytes of garbage at %d", min_offset-offset, offset);
-			in->seek(min_offset - offset, SEEK_CUR);
-			offset = min_offset;
-		}
-	}
-
-	free(entries);
-	return matched;
-
-cleanup:
-
-	free(entries);
-	return -1;
-}
-
-uint32 Win32ResExtractor::simple_vec(byte *data, uint32 ofs, byte size) {
-	switch (size) {
-	case 1:
-		return (data[ofs/8] >> (7 - ofs%8)) & 1;
-	case 2:
-		return (data[ofs/4] >> ((3 - ofs%4) << 1)) & 3;
-	case 4:
-		return (data[ofs/2] >> ((1 - ofs%2) << 2)) & 15;
-	case 8:
-		return data[ofs];
-	case 16:
-		return data[2*ofs] | data[2*ofs+1] << 8;
-	case 24:
-		return data[3*ofs] | data[3*ofs+1] << 8 | data[3*ofs+2] << 16;
-	case 32:
-		return data[4*ofs] | data[4*ofs+1] << 8 | data[4*ofs+2] << 16 | data[4*ofs+3] << 24;
-	}
-
-	return 0;
-}
-
-#define LE16(x)      ((x) = TO_LE_16(x))
-#define LE32(x)      ((x) = TO_LE_32(x))
-
-void Win32ResExtractor::fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj) {
-    LE16(obj->reserved);
-	LE16(obj->type);
-    LE16(obj->count);
-}
-
-void Win32ResExtractor::fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj) {
-    LE32(obj->size);
-    LE32(obj->width);
-    LE32(obj->height);
-    LE16(obj->planes);
-    LE16(obj->bit_count);
-    LE32(obj->compression);
-    LE32(obj->size_image);
-    LE32(obj->x_pels_per_meter);
-    LE32(obj->y_pels_per_meter);
-    LE32(obj->clr_used);
-    LE32(obj->clr_important);
-}
-
-void Win32ResExtractor::fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj) {
-    LE16(obj->hotspot_x);
-    LE16(obj->hotspot_y);
-    LE32(obj->dib_size);
-    LE32(obj->dib_offset);
-}
-
-void Win32ResExtractor::fix_win32_image_section_header(Win32ImageSectionHeader *obj) {
-    LE32(obj->misc.physical_address);
-    LE32(obj->virtual_address);
-    LE32(obj->size_of_raw_data);
-    LE32(obj->pointer_to_raw_data);
-    LE32(obj->pointer_to_relocations);
-    LE32(obj->pointer_to_linenumbers);
-    LE16(obj->number_of_relocations);
-    LE16(obj->number_of_linenumbers);
-    LE32(obj->characteristics);
-}
-
-void Win32ResExtractor::fix_os2_image_header_endian(OS2ImageHeader *obj) {
-    LE16(obj->magic);
-    LE16(obj->enttab);
-    LE16(obj->cbenttab);
-    LE32(obj->crc);
-    LE16(obj->flags);
-    LE16(obj->autodata);
-    LE16(obj->heap);
-    LE16(obj->stack);
-    LE32(obj->csip);
-    LE32(obj->sssp);
-    LE16(obj->cseg);
-    LE16(obj->cmod);
-    LE16(obj->cbnrestab);
-    LE16(obj->segtab);
-    LE16(obj->rsrctab);
-    LE16(obj->restab);
-    LE16(obj->modtab);
-    LE16(obj->imptab);
-    LE32(obj->nrestab);
-    LE16(obj->cmovent);
-    LE16(obj->align);
-    LE16(obj->cres);
-    LE16(obj->fastload_offset);
-    LE16(obj->fastload_length);
-    LE16(obj->swaparea);
-    LE16(obj->expver);
-}
-
-/* fix_win32_image_header_endian:
- * NOTE: This assumes that the optional header is always available.
- */
-void Win32ResExtractor::fix_win32_image_header_endian(Win32ImageNTHeaders *obj) {
-    LE32(obj->signature);
-    LE16(obj->file_header.machine);
-    LE16(obj->file_header.number_of_sections);
-    LE32(obj->file_header.time_date_stamp);
-    LE32(obj->file_header.pointer_to_symbol_table);
-    LE32(obj->file_header.number_of_symbols);
-    LE16(obj->file_header.size_of_optional_header);
-    LE16(obj->file_header.characteristics);
-    LE16(obj->optional_header.magic);
-    LE32(obj->optional_header.size_of_code);
-    LE32(obj->optional_header.size_of_initialized_data);
-    LE32(obj->optional_header.size_of_uninitialized_data);
-    LE32(obj->optional_header.address_of_entry_point);
-    LE32(obj->optional_header.base_of_code);
-    LE32(obj->optional_header.base_of_data);
-    LE32(obj->optional_header.image_base);
-    LE32(obj->optional_header.section_alignment);
-    LE32(obj->optional_header.file_alignment);
-    LE16(obj->optional_header.major_operating_system_version);
-    LE16(obj->optional_header.minor_operating_system_version);
-    LE16(obj->optional_header.major_image_version);
-    LE16(obj->optional_header.minor_image_version);
-    LE16(obj->optional_header.major_subsystem_version);
-    LE16(obj->optional_header.minor_subsystem_version);
-    LE32(obj->optional_header.win32_version_value);
-    LE32(obj->optional_header.size_of_image);
-    LE32(obj->optional_header.size_of_headers);
-    LE32(obj->optional_header.checksum);
-    LE16(obj->optional_header.subsystem);
-    LE16(obj->optional_header.dll_characteristics);
-    LE32(obj->optional_header.size_of_stack_reserve);
-    LE32(obj->optional_header.size_of_stack_commit);
-    LE32(obj->optional_header.size_of_heap_reserve);
-    LE32(obj->optional_header.size_of_heap_commit);
-    LE32(obj->optional_header.loader_flags);
-    LE32(obj->optional_header.number_of_rva_and_sizes);
-}
-
-void Win32ResExtractor::fix_win32_image_data_directory(Win32ImageDataDirectory *obj) {
-    LE32(obj->virtual_address);
-    LE32(obj->size);
-}
-
-
-MacResExtractor::MacResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {
-	_resOffset = -1;
-}
-
-int MacResExtractor::extractResource(int id, byte **buf) {
-	Common::File in;
-	int size;
-
-	if (!_fileName[0]) // We are running for the first time
-		if (_vm->_substResFileNameIndex > 0) {
-			char buf1[128];
-
-			snprintf(buf1, 128, "%s.he3", _vm->getBaseName());
-			_vm->generateSubstResFileName(buf1, _fileName, sizeof(buf1));
-
-			// Some programs write it as .bin. Try that too
-			if (!in.exists(_fileName)) {
-				strcpy(buf1, _fileName);
-				snprintf(_fileName, 128, "%s.bin", buf1);
-
-				if (!in.exists(_fileName)) {
-					// And finally check if we have dumped resource fork
-					snprintf(_fileName, 128, "%s.rsrc", buf1);
-					if (!in.exists(_fileName)) {
-						error("Cannot open file any of files '%s', '%s.bin', '%s.rsrc",
-							  buf1, buf1, buf1);
-					}
-				}
-			}
-		}
-
-	in.open(_fileName);
-	if (!in.isOpen()) {
-		error("Cannot open file %s", _fileName);
-	}
-
-	// we haven't calculated it
-	if (_resOffset == -1) {
-		if (!init(in))
-			error("Resource fork is missing in file '%s'", _fileName);
-		in.close();
-		in.open(_fileName);
-	}
-
-	*buf = getResource(in, "crsr", 1000 + id, &size);
-
-	in.close();
-
-	if (*buf == NULL)
-		error("There is no cursor ID #%d", 1000 + id);
-
-	return size;
-}
-
-#define MBI_INFOHDR 128
-#define MBI_ZERO1 0
-#define MBI_NAMELEN 1
-#define MBI_ZERO2 74
-#define MBI_ZERO3 82
-#define MBI_DFLEN 83
-#define MBI_RFLEN 87
-#define MAXNAMELEN 63
-
-bool MacResExtractor::init(Common::File in) {
-	byte infoHeader[MBI_INFOHDR];
-	int32 data_size, rsrc_size;
-	int32 data_size_pad, rsrc_size_pad;
-	int filelen;
-
-	filelen = in.size();
-	in.read(infoHeader, MBI_INFOHDR);
-
-	// Maybe we have MacBinary?
-	if (infoHeader[MBI_ZERO1] == 0 && infoHeader[MBI_ZERO2] == 0 &&
-		infoHeader[MBI_ZERO3] == 0 && infoHeader[MBI_NAMELEN] <= MAXNAMELEN) {
-
-		// Pull out fork lengths
-		data_size = READ_BE_UINT32(infoHeader + MBI_DFLEN);
-		rsrc_size = READ_BE_UINT32(infoHeader + MBI_RFLEN);
-
-		data_size_pad = (((data_size + 127) >> 7) << 7);
-		rsrc_size_pad = (((rsrc_size + 127) >> 7) << 7);
-
-		// Length check
-		int sumlen =  MBI_INFOHDR + data_size_pad + rsrc_size_pad;
-
-		if (sumlen == filelen)
-			_resOffset = MBI_INFOHDR + data_size_pad;
-	}
-
-	if (_resOffset == -1) // MacBinary check is failed
-		_resOffset = 0; // Maybe we have dumped fork?
-
-	in.seek(_resOffset);
-
-	_dataOffset = in.readUint32BE() + _resOffset;
-	_mapOffset = in.readUint32BE() + _resOffset;
-	_dataLength = in.readUint32BE();
-	_mapLength = in.readUint32BE();
-
-	// do sanity check
-	if (_dataOffset >= filelen || _mapOffset >= filelen ||
-		_dataLength + _mapLength  > filelen) {
-		_resOffset = -1;
-		return false;
-	}
-
-	debug(7, "got header: data %d [%d] map %d [%d]",
-		_dataOffset, _dataLength, _mapOffset, _mapLength);
-
-	readMap(in);
-
-	return true;
-}
-
-byte *MacResExtractor::getResource(Common::File in, const char *typeID, int16 resID, int *size) {
-	int	i;
-	int typeNum = -1;
-	int resNum = -1;
-	byte *buf;
-	int len;
-
-	for (i = 0; i < _resMap.numTypes; i++)
-		if (strcmp(_resTypes[i].id, typeID) == 0) {
-			typeNum = i;
-			break;
-		}
-
-	if (typeNum == -1)
-		return NULL;
-
-	for (i = 0; i < _resTypes[typeNum].items; i++)
-		if (_resLists[typeNum][i].id == resID) {
-			resNum = i;
-			break;
-		}
-
-	if (resNum == -1)
-		return NULL;
-
-	in.seek(_dataOffset + _resLists[typeNum][resNum].dataOffset);
-
-	len = in.readUint32BE();
-	buf = (byte *)malloc(len);
-
-	in.read(buf, len);
-
-	*size = len;
-
-	return buf;
-}
-
-void MacResExtractor::readMap(Common::File in) {
-	int	i, j, len;
-
-	in.seek(_mapOffset + 22);
-
-	_resMap.resAttr = in.readUint16BE();
-	_resMap.typeOffset = in.readUint16BE();
-	_resMap.nameOffset = in.readUint16BE();
-	_resMap.numTypes = in.readUint16BE();
-	_resMap.numTypes++;
-
-	in.seek(_mapOffset + _resMap.typeOffset + 2);
-	_resTypes = new ResType[_resMap.numTypes];
-
-	for (i = 0; i < _resMap.numTypes; i++) {
-		in.read(_resTypes[i].id, 4);
-		_resTypes[i].id[4] = 0;
-		_resTypes[i].items = in.readUint16BE();
-		_resTypes[i].offset = in.readUint16BE();
-		_resTypes[i].items++;
-	}
-
-	_resLists = new ResPtr[_resMap.numTypes];
-
-	for (i = 0; i < _resMap.numTypes; i++) {
-		_resLists[i] = new Resource[_resTypes[i].items];
-		in.seek(_resTypes[i].offset + _mapOffset + _resMap.typeOffset);
-
-		for (j = 0; j < _resTypes[i].items; j++) {
-			ResPtr resPtr = _resLists[i] + j;
-
-			resPtr->id = in.readUint16BE();
-			resPtr->nameOffset = in.readUint16BE();
-			resPtr->dataOffset = in.readUint32BE();
-			in.readUint32BE();
-			resPtr->name = 0;
-
-			resPtr->attr = resPtr->dataOffset >> 24;
-			resPtr->dataOffset &= 0xFFFFFF;
-		}
-
-		for (j = 0; j < _resTypes[i].items; j++) {
-			if (_resLists[i][j].nameOffset != -1) {
-				in.seek(_resLists[i][j].nameOffset + _mapOffset + _resMap.nameOffset);
-
-				len = in.readByte();
-				_resLists[i][j].name = new byte[len + 1];
-				_resLists[i][j].name[len] = 0;
-				in.read(_resLists[i][j].name, len);
-			}
-		}
-	}
-}
-
-int MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
-			  int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize) {
-	Common::MemoryReadStream dis(data, datasize);
-	int i, b;
-	byte imageByte;
-	byte *iconData;
-	int numBytes;
-	int pixelsPerByte, bpp;
-	int ctSize;
-	byte bitmask;
-	int iconRowBytes, iconBounds[4];
-	int ignored;
-	int iconDataSize;
-
-	dis.readUint16BE(); // type
-	dis.readUint32BE(); // offset to pixel map
-	dis.readUint32BE(); // offset to pixel data
-	dis.readUint32BE(); // expanded cursor data
-	dis.readUint16BE(); // expanded data depth
-	dis.readUint32BE(); // reserved
-
-	// Grab B/W icon data
-	*cursor = (byte *)malloc(16 * 16);
-	for (i = 0; i < 32; i++) {
-		imageByte = dis.readByte();
-		for (b = 0; b < 8; b++)
-			cursor[0][i*8+b] = (byte)((imageByte &
-									  (0x80 >> b)) > 0? 0x0F: 0x00);
-	}
-
-	// Apply mask data
-	for (i = 0; i < 32; i++) {
-		imageByte = dis.readByte();
-		for (b = 0; b < 8; b++)
-			if ((imageByte & (0x80 >> b)) == 0)
-				cursor[0][i*8+b] = 0xff;
-	}
-
-	*hotspot_y = dis.readUint16BE();
-	*hotspot_x = dis.readUint16BE();
-	*w = *h = 16;
-
-	// Use b/w cursor on backends which don't support cursor palettes
-	if (!_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette))
-		return 1;
-
-	dis.readUint32BE(); // reserved
-	dis.readUint32BE(); // cursorID
-
-	// Color version of cursor
-	dis.readUint32BE(); // baseAddr
-
-	// Keep only lowbyte for now
-	dis.readByte();
-	iconRowBytes = dis.readByte();
-
-	if (!iconRowBytes)
-		return 1;
-
-	iconBounds[0] = dis.readUint16BE();
-	iconBounds[1] = dis.readUint16BE();
-	iconBounds[2] = dis.readUint16BE();
-	iconBounds[3] = dis.readUint16BE();
-
-	dis.readUint16BE(); // pmVersion
-	dis.readUint16BE(); // packType
-	dis.readUint32BE(); // packSize
-
-	dis.readUint32BE(); // hRes
-	dis.readUint32BE(); // vRes
-
-	dis.readUint16BE(); // pixelType
-	dis.readUint16BE(); // pixelSize
-	dis.readUint16BE(); // cmpCount
-	dis.readUint16BE(); // cmpSize
-
-	dis.readUint32BE(); // planeByte
-	dis.readUint32BE(); // pmTable
-	dis.readUint32BE(); // reserved
-
-	// Pixel data for cursor
-	iconDataSize =  iconRowBytes * (iconBounds[3] - iconBounds[1]);
-	iconData = (byte *)malloc(iconDataSize);
-	dis.read(iconData, iconDataSize);
-
-	// Color table
-	dis.readUint32BE(); // ctSeed
-	dis.readUint16BE(); // ctFlag
-	ctSize = dis.readUint16BE() + 1;
-
-	*palette = (byte *)malloc(ctSize * 4);
-
-	// Read just high byte of 16-bit color
-	for (int c = 0; c < ctSize; c++) {
-		// We just use indices 0..ctSize, so ignore color ID
-		dis.readUint16BE(); // colorID[c]
-
-		palette[0][c * 4 + 0] = dis.readByte();
-		ignored = dis.readByte();
-
-		palette[0][c * 4 + 1] = dis.readByte();
-		ignored = dis.readByte();
-
-		palette[0][c * 4 + 2] = dis.readByte();
-		ignored = dis.readByte();
-
-		palette[0][c * 4 + 3] = 0;
-	}
-
-	*palSize = ctSize;
-
-	numBytes =
-         (iconBounds[2] - iconBounds[0]) *
-         (iconBounds[3] - iconBounds[1]);
-
-	pixelsPerByte = (iconBounds[2] - iconBounds[0]) / iconRowBytes;
-	bpp           = 8 / pixelsPerByte;
-
-	// build a mask to make sure the pixels are properly shifted out
-	bitmask = 0;
-	for (int m = 0; m < bpp; m++) {
-		bitmask <<= 1;
-		bitmask  |= 1;
-	}
-
-	// Extract pixels from bytes
-	for (int j = 0; j < iconDataSize; j++)
-		for (b = 0; b < pixelsPerByte; b++) {
-			int idx = j * pixelsPerByte + (pixelsPerByte - 1 - b);
-
-			if (cursor[0][idx] != 0xff) // if mask is not there
-				cursor[0][idx] = (byte)((iconData[j] >> (b * bpp)) & bitmask);
-		}
-
-	free(iconData);
-
-	assert(datasize - dis.pos() == 0);
-
-	return 1;
-}
-
-
-
-void ScummEngine_v70he::readRoomsOffsets() {
-	int num, i;
-	byte *ptr;
-
-	debug(9, "readRoomOffsets()");
-
-	num = READ_LE_UINT16(_heV7RoomOffsets);
-	ptr = _heV7RoomOffsets + 2;
-	for (i = 0; i < num; i++) {
-		res.roomoffs[rtRoom][i] = READ_LE_UINT32(ptr);
-		ptr += 4;
-	}
-}
-
-void ScummEngine_v70he::readGlobalObjects() {
-	int num = _fileHandle->readUint16LE();
-	assert(num == _numGlobalObjects);
-
-	_fileHandle->read(_objectStateTable, num);
-	_fileHandle->read(_objectOwnerTable, num);
-	_fileHandle->read(_objectRoomTable, num);
-
-	_fileHandle->read(_classData, num * sizeof(uint32));
-
-#if defined(SCUMM_BIG_ENDIAN)
-	// Correct the endianess if necessary
-	for (int i = 0; i != num; i++)
-		_classData[i] = FROM_LE_32(_classData[i]);
-#endif
-}
-
-void ScummEngine_v99he::readMAXS(int blockSize) {
-	debug(0, "ScummEngine_v99he readMAXS: MAXS has blocksize %d", blockSize);
-
-	_numVariables = _fileHandle->readUint16LE();
-	_fileHandle->readUint16LE();
-	_numRoomVariables = _fileHandle->readUint16LE();
-	_numLocalObjects = _fileHandle->readUint16LE();
-	_numArray = _fileHandle->readUint16LE();
-	_fileHandle->readUint16LE();
-	_fileHandle->readUint16LE();
-	_numFlObject = _fileHandle->readUint16LE();
-	_numInventory = _fileHandle->readUint16LE();
-	_numRooms = _fileHandle->readUint16LE();
-	_numScripts = _fileHandle->readUint16LE();
-	_numSounds = _fileHandle->readUint16LE();
-	_numCharsets = _fileHandle->readUint16LE();
-	_numCostumes = _fileHandle->readUint16LE();
-	_numGlobalObjects = _fileHandle->readUint16LE();
-	_numImages = _fileHandle->readUint16LE();
-	_numSprites = _fileHandle->readUint16LE();
-	_numLocalScripts = _fileHandle->readUint16LE();
-	_HEHeapSize = _fileHandle->readUint16LE();
-	_numPalettes = _fileHandle->readUint16LE();
-	_numUnk = _fileHandle->readUint16LE();
-	_numTalkies = _fileHandle->readUint16LE();
-	_numNewNames = 10;
-
-	_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
-	_numGlobalScripts = 2048;
-}
-
-void ScummEngine_v90he::readMAXS(int blockSize) {
-	debug(0, "ScummEngine_v90he readMAXS: MAXS has blocksize %d", blockSize);
-
-	_numVariables = _fileHandle->readUint16LE();
-	_fileHandle->readUint16LE();
-	_numRoomVariables = _fileHandle->readUint16LE();
-	_numLocalObjects = _fileHandle->readUint16LE();
-	_numArray = _fileHandle->readUint16LE();
-	_fileHandle->readUint16LE();
-	_fileHandle->readUint16LE();
-	_numFlObject = _fileHandle->readUint16LE();
-	_numInventory = _fileHandle->readUint16LE();
-	_numRooms = _fileHandle->readUint16LE();
-	_numScripts = _fileHandle->readUint16LE();
-	_numSounds = _fileHandle->readUint16LE();
-	_numCharsets = _fileHandle->readUint16LE();
-	_numCostumes = _fileHandle->readUint16LE();
-	_numGlobalObjects = _fileHandle->readUint16LE();
-	_numImages = _fileHandle->readUint16LE();
-	_numSprites = _fileHandle->readUint16LE();
-	_numLocalScripts = _fileHandle->readUint16LE();
-	_HEHeapSize = _fileHandle->readUint16LE();
-	_numNewNames = 10;
-
-	_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
-	if (_features & GF_HE_985)
-		_numGlobalScripts = 2048;
-	else
-		_numGlobalScripts = 200;
-}
-
-void ScummEngine_v72he::readMAXS(int blockSize) {
-	debug(0, "ScummEngine_v72he readMAXS: MAXS has blocksize %d", blockSize);
-
-	_numVariables = _fileHandle->readUint16LE();
-	_fileHandle->readUint16LE();
-	_numBitVariables = _numRoomVariables = _fileHandle->readUint16LE();
-	_numLocalObjects = _fileHandle->readUint16LE();
-	_numArray = _fileHandle->readUint16LE();
-	_fileHandle->readUint16LE();
-	_numVerbs = _fileHandle->readUint16LE();
-	_numFlObject = _fileHandle->readUint16LE();
-	_numInventory = _fileHandle->readUint16LE();
-	_numRooms = _fileHandle->readUint16LE();
-	_numScripts = _fileHandle->readUint16LE();
-	_numSounds = _fileHandle->readUint16LE();
-	_numCharsets = _fileHandle->readUint16LE();
-	_numCostumes = _fileHandle->readUint16LE();
-	_numGlobalObjects = _fileHandle->readUint16LE();
-	_numImages = _fileHandle->readUint16LE();
-	_numNewNames = 10;
-
-	_objectRoomTable = (byte *)calloc(_numGlobalObjects, 1);
-	_numGlobalScripts = 200;
-}
-
-byte *ScummEngine_v72he::getStringAddress(int i) {
-	byte *addr = getResourceAddress(rtString, i);
-	if (addr == NULL)
-		return NULL;
-	return ((ScummEngine_v72he::ArrayHeader *)addr)->data;
-}
-
-int ScummEngine_v72he::getSoundResourceSize(int id) {
-	const byte *ptr;
-	int offs, size;
-
-	if (id > _numSounds) {
-		if (!_sound->getHEMusicDetails(id, offs, size)) {
-			debug(0, "getSoundResourceSize: musicID %d not found", id);
-			return 0;
-		}
-	} else {
-		ptr = getResourceAddress(rtSound, id);
-		if (!ptr)
-			return 0;
-
-		if (READ_UINT32(ptr) == MKID('RIFF')) {
-			byte flags;
-			int rate;
-
-			size = READ_BE_UINT32(ptr + 4);
-			Common::MemoryReadStream stream(ptr, size);
-
-			if (!loadWAVFromStream(stream, size, rate, flags)) {
-				error("getSoundResourceSize: Not a valid WAV file");
-			}
-		} else {
-			ptr += 8 + READ_BE_UINT32(ptr + 12);
-			if (READ_UINT32(ptr) == MKID('SBNG')) {
-				ptr += READ_BE_UINT32(ptr + 4);
-			}
-
-			assert(READ_UINT32(ptr) == MKID('SDAT'));
-			size = READ_BE_UINT32(ptr + 4) - 8;
-		}
-	}
-
-	return size;
-}
-
-void ScummEngine_v80he::createSound(int snd1id, int snd2id) {
-	debug(0, "createSound: snd1id %d snd2id %d", snd1id, snd2id);
-
-	byte *snd1Ptr, *snd2Ptr;
-	byte *sbng1Ptr, *sbng2Ptr;
-	byte *sdat1Ptr, *sdat2Ptr;
-	byte *src, *dst, *tmp;
-	int len, offs, size;
-	int sdat1size, sdat2size;
-
-	if (snd2id == -1) {
-		_sndPtrOffs = 0;
-		_sndTmrOffs = 0;
-		return;
-	}
-
-	if (snd1id != _curSndId) {
-		_curSndId = snd1id;
-		_sndPtrOffs = 0;
-		_sndTmrOffs = 0;
-	}
-
-	snd1Ptr = getResourceAddress(rtSound, snd1id);
-	assert(snd1Ptr);
-	snd2Ptr = getResourceAddress(rtSound, snd2id);
-	assert(snd2Ptr);
-
-	int i;
-	int chan = -1;
-	for (i = 0; i < ARRAYSIZE(_sound->_heChannel); i++) {
-		if (_sound->_heChannel[i].sound == snd1id)
-			chan =  i;
-	}
-
-	sbng1Ptr = heFindResource(MKID('SBNG'), snd1Ptr);
-	sbng2Ptr = heFindResource(MKID('SBNG'), snd2Ptr);
-
-	if (sbng1Ptr != NULL && sbng2Ptr != NULL) {
-		if (chan != -1 && _sound->_heChannel[chan].codeOffs > 0) {
-			int curOffs = _sound->_heChannel[chan].codeOffs;
-
-			src = snd1Ptr + curOffs;
-			dst = sbng1Ptr + 8;
-			size = READ_BE_UINT32(sbng1Ptr + 4);
-			len = sbng1Ptr - snd1Ptr + size - curOffs;
-
-			byte *data = (byte *)malloc(len);
-			memcpy(data, src, len);
-			memcpy(dst, data, len);
-			free(data);
-
-			dst = sbng1Ptr + 8;
-			while ((size = READ_LE_UINT16(dst)) != 0)
-				dst += size;
-		} else {
-			dst = sbng1Ptr + 8;
-		}
-
-		_sound->_heChannel[chan].codeOffs = sbng1Ptr - snd1Ptr + 8;
-
-		tmp = sbng2Ptr + 8;
-		while ((offs = READ_LE_UINT16(tmp)) != 0) {
-			tmp += offs;
-		}
-
-		src = sbng2Ptr + 8;
-		len = tmp - sbng2Ptr - 6;
-		memcpy(dst, src, len);
-
-		int32 time;
-		while ((size = READ_LE_UINT16(dst)) != 0) {
-			time = READ_LE_UINT32(dst + 2);
-			time += _sndTmrOffs;
-			WRITE_LE_UINT32(dst + 2, time);
-			dst += size;
-		}
-	}
-
-	sdat1Ptr = heFindResource(MKID('SDAT'), snd1Ptr);
-	assert(sdat1Ptr);
-	sdat2Ptr = heFindResource(MKID('SDAT'), snd2Ptr);
-	assert(sdat2Ptr);
-
-	sdat1size = READ_BE_UINT32(sdat1Ptr + 4) - 8 - _sndPtrOffs;
-	sdat2size = READ_BE_UINT32(sdat2Ptr + 4) - 8;
-
-	debug(0, "SDAT size1 %d size2 %d", sdat1size, sdat2size);
-	if (sdat2size < sdat1size) {
-		src = sdat2Ptr + 8;
-		dst = sdat1Ptr + 8 + _sndPtrOffs;
-		len = sdat2size;
-		
-		memcpy(dst, src, len);
-
-		_sndPtrOffs += sdat2size;
-		_sndTmrOffs += sdat2size;
-	} else {
-		src = sdat2Ptr + 8;
-		dst = sdat1Ptr + 8 + _sndPtrOffs;
-		len = sdat1size;
-		
-		memcpy(dst, src, len);
-
-		if (sdat2size != sdat1size) {
-			src = sdat2Ptr + 8 + sdat1size;
-			dst = sdat1Ptr + 8;
-			len = sdat2size - sdat1size;
-		
-			memcpy(dst, src, len);
-		}
-
-		_sndPtrOffs = sdat2size - sdat1size;
-		_sndTmrOffs += sdat2size;
-	}
-}
-
-} // End of namespace Scumm

Deleted: scummvm/trunk/engines/scumm/he/resource_v7he.h
===================================================================
--- scummvm/trunk/engines/scumm/he/resource_v7he.h	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/he/resource_v7he.h	2006-02-15 18:48:49 UTC (rev 20703)
@@ -1,556 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2004-2006 The ScummVM project
- *
- * Parts of code heavily based on:
- * icoutils - A set of programs dealing with MS Windows icons and cursors.
- * Copyright (C) 1998-2001 Oskar Liljeblad
- *
- * 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$
- *
- */
-
-#if !defined(RESOURCE_V7HE_H) && !defined(DISABLE_HE)
-#define RESOURCE_V7HE_H
-
-namespace Scumm {
-
-#define WINRES_ID_MAXLEN (256)
-
-/*
- * Definitions
- */
-
-#define ACTION_LIST 				1	/* command: list resources */
-#define ACTION_EXTRACT				2	/* command: extract resources */
-#define CALLBACK_STOP				0	/* results of ResourceCallback */
-#define CALLBACK_CONTINUE			1
-#define CALLBACK_CONTINUE_RECURS	2
-
-#define MZ_HEADER(x)	((DOSImageHeader *)(x))
-#define NE_HEADER(x)	((OS2ImageHeader *)PE_HEADER(x))
-#define NE_TYPEINFO_NEXT(x) ((Win16NETypeInfo *)((byte *)(x) + sizeof(Win16NETypeInfo) + \
-						    ((Win16NETypeInfo *)x)->count * sizeof(Win16NENameInfo)))
-#define NE_RESOURCE_NAME_IS_NUMERIC (0x8000)
-
-#define STRIP_RES_ID_FORMAT(x) (x != NULL && (x[0] == '-' || x[0] == '+') ? ++x : x)
-
-#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
-#define IMAGE_SIZEOF_SHORT_NAME 8
-
-#define	IMAGE_RESOURCE_NAME_IS_STRING		0x80000000
-#define	IMAGE_RESOURCE_DATA_IS_DIRECTORY	0x80000000
-
-#define PE_HEADER(module) \
-    ((Win32ImageNTHeaders*)((byte *)(module) + \
-    	(((DOSImageHeader*)(module))->lfanew)))
-
-#define PE_SECTIONS(module) \
-    ((Win32ImageSectionHeader *)((byte *) &PE_HEADER(module)->optional_header + \
-                           PE_HEADER(module)->file_header.size_of_optional_header))
-
-#define IMAGE_DOS_SIGNATURE    0x5A4D     /* MZ */
-#define IMAGE_OS2_SIGNATURE    0x454E     /* NE */
-#define IMAGE_OS2_SIGNATURE_LE 0x454C     /* LE */
-#define IMAGE_OS2_SIGNATURE_LX 0x584C     /* LX */
-#define IMAGE_VXD_SIGNATURE    0x454C     /* LE */
-#define IMAGE_NT_SIGNATURE     0x00004550 /* PE00 */
-
-#if !defined (WIN32)
-#define IMAGE_SCN_CNT_CODE			0x00000020
-#define IMAGE_SCN_CNT_INITIALIZED_DATA		0x00000040
-#define IMAGE_SCN_CNT_UNINITIALIZED_DATA	0x00000080
-#endif
-
-#define	IMAGE_DIRECTORY_ENTRY_EXPORT		0
-#define	IMAGE_DIRECTORY_ENTRY_IMPORT		1
-#define	IMAGE_DIRECTORY_ENTRY_RESOURCE		2
-#define	IMAGE_DIRECTORY_ENTRY_EXCEPTION		3
-#define	IMAGE_DIRECTORY_ENTRY_SECURITY		4
-#define	IMAGE_DIRECTORY_ENTRY_BASERELOC		5
-#define	IMAGE_DIRECTORY_ENTRY_DEBUG			6
-#define	IMAGE_DIRECTORY_ENTRY_COPYRIGHT		7
-#define	IMAGE_DIRECTORY_ENTRY_GLOBALPTR		8   /* (MIPS GP) */
-#define	IMAGE_DIRECTORY_ENTRY_TLS			9
-#define	IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG	10
-#define	IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT	11
-#define	IMAGE_DIRECTORY_ENTRY_IAT			12  /* Import Address Table */
-#define	IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT	13
-#define	IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR	14
-
-#if !defined (WIN32)
-#define RT_CURSOR        1
-#define RT_BITMAP        2
-#define RT_ICON          3
-#define RT_MENU          4
-#define RT_DIALOG        5
-#define RT_STRING        6
-#define RT_FONTDIR       7
-#define RT_FONT          8
-#define RT_ACCELERATOR   9
-#define RT_RCDATA        10
-#define RT_MESSAGELIST   11
-#define RT_GROUP_CURSOR  12
-#define RT_GROUP_ICON    14
-#endif
-
-#define RETURN_IF_BAD_POINTER(r, x) \
-	if (!check_offset(fi->memory, fi->total_size, fi->file->name(), &(x), sizeof(x))) \
-		return (r);
-#define RETURN_IF_BAD_OFFSET(r, x, s) \
-	if (!check_offset(fi->memory, fi->total_size, fi->file->name(), x, s)) \
-		return (r);
-
-class ScummEngine_v70he;
-
-class ResExtractor {
-public:
-	ResExtractor(ScummEngine_v70he *scumm);
-	virtual ~ResExtractor();
-
-	void setCursor(int id);
-
-	virtual int extractResource(int id, byte **buf) { return 0; };
-	virtual int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
-							 int *hotspot_x, int *hotspot_y, int *keycolor,
-							 byte **palette, int *palSize) { return 0; };
-
-	enum {
-		MAX_CACHED_CURSORS = 10
-	};
-
-	struct CachedCursor {
-		bool valid;
-		int id;
-		byte *bitmap;
-		int w, h;
-		int hotspot_x, hotspot_y;
-		uint32 last_used;
-		byte *palette;
-		int palSize;
-	};
-
-	ScummEngine_v70he *_vm;
-
-	ResExtractor::CachedCursor *findCachedCursor(int id);
-	ResExtractor::CachedCursor *getCachedCursorSlot();
-
-	bool _arg_raw;
-	char _fileName[256];
-	CachedCursor _cursorCache[MAX_CACHED_CURSORS];
-
-	typedef Common::MemoryReadStream MemoryReadStream;
-
-};
-
-class Win32ResExtractor : public ResExtractor {
- public:
-	Win32ResExtractor(ScummEngine_v70he *scumm);
-	~Win32ResExtractor() {};
-	int extractResource(int id, byte **data);
-	void setCursor(int id);
-	int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
-			 int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
-
- private:
-	int extractResource_(const char *resType, char *resName, byte **data);
-/*
- * Structures
- */
-
-#if !defined(__GNUC__)
-	#pragma START_PACK_STRUCTS
-#endif
-
-	struct WinLibrary {
-		Common::File *file;
-		byte *memory;
-		byte *first_resource;
-		bool is_PE_binary;
-		int total_size;
-	};
-
-	struct WinResource {
-		char id[256];
-		void *this_;
-		void *children;
-		int level;
-		bool numeric_id;
-		bool is_directory;
-	};
-
-
-	struct Win32IconResDir {
-		byte width;
-		byte height;
-		byte color_count;
-		byte reserved;
-	};
-
-	struct Win32CursorDir {
-		uint16 width;
-		uint16 height;
-	};
-
-	struct Win32CursorIconDirEntry {
-		union {
-			Win32IconResDir icon;
-			Win32CursorDir cursor;
-		} res_info;
-		uint16 plane_count;
-		uint16 bit_count;
-		uint32 bytes_in_res;
-		uint16 res_id;
-	};
-
-	struct Win32CursorIconDir {
-		uint16 reserved;
-		uint16 type;
-		uint16 count;
-		Win32CursorIconDirEntry entries[1] GCC_PACK;
-	};
-
-	struct Win32CursorIconFileDirEntry {
-		byte width;
-		byte height;
-		byte color_count;
-		byte reserved;
-		uint16 hotspot_x;
-		uint16 hotspot_y;
-		uint32 dib_size;
-		uint32 dib_offset;
-	};
-
-	struct Win32CursorIconFileDir {
-		uint16 reserved;
-		uint16 type;
-		uint16 count;
-		Win32CursorIconFileDirEntry entries[1];
-	};
-
-	struct Win32BitmapInfoHeader {
-		uint32 size;
-		int32 width;
-		int32 height;
-		uint16 planes;
-		uint16 bit_count;
-		uint32 compression;
-		uint32 size_image;
-		int32 x_pels_per_meter;
-		int32 y_pels_per_meter;
-		uint32 clr_used;
-		uint32 clr_important;
-	};
-
-	struct Win32RGBQuad {
-		byte blue;
-		byte green;
-		byte red;
-		byte reserved;
-	};
-
-	struct Win32ImageResourceDirectoryEntry {
-		union {
-			struct {
-				#ifdef SCUMM_BIGENDIAN
-				unsigned name_is_string:1;
-				unsigned name_offset:31;
-	    	    #else
-				unsigned name_offset:31;
-				unsigned name_is_string:1;
-	    	    #endif
-			} s1;
-			uint32 name;
-			struct {
-	    	    #ifdef SCUMM_BIG_ENDIAN
-				uint16 __pad;
-				uint16 id;
-	    	    #else
-				uint16 id;
-				uint16 __pad;
-	    	    #endif
-			} s2;
-		} u1;
-		union {
-			uint32 offset_to_data;
-			struct {
-	    	    #ifdef SCUMM_BIG_ENDIAN
-				unsigned data_is_directory:1;
-				unsigned offset_to_directory:31;
-	    	    #else
-				unsigned offset_to_directory:31;
-				unsigned data_is_directory:1;
-	    	    #endif
-			} s;
-		} u2;
-	};
-
-	struct Win16NETypeInfo {
-		uint16 type_id;
-		uint16 count;
-		uint32 resloader;     // FARPROC16 - smaller? uint16?
-	};
-
-	struct Win16NENameInfo {
-		uint16 offset;
-		uint16 length;
-		uint16 flags;
-		uint16 id;
-		uint16 handle;
-		uint16 usage;
-	};
-
-	struct OS2ImageHeader {
-		uint16 magic;
-		byte ver;
-		byte rev;
-		uint16 enttab;
-		uint16 cbenttab;
-		int32 crc;
-		uint16 flags;
-		uint16 autodata;
-		uint16 heap;
-		uint16 stack;
-		uint32 csip;
-		uint32 sssp;
-		uint16 cseg;
-		uint16 cmod;
-		uint16 cbnrestab;
-		uint16 segtab;
-		uint16 rsrctab;
-		uint16 restab;
-		uint16 modtab;
-		uint16 imptab;
-		uint32 nrestab;
-		uint16 cmovent;
-		uint16 align;
-		uint16 cres;
-		byte exetyp;
-		byte flagsothers;
-		uint16 fastload_offset;
-		uint16 fastload_length;
-		uint16 swaparea;
-		uint16 expver;
-	};
-
-	struct DOSImageHeader {
-		uint16 magic;
-		uint16 cblp;
-		uint16 cp;
-		uint16 crlc;
-		uint16 cparhdr;
-		uint16 minalloc;
-		uint16 maxalloc;
-		uint16 ss;
-		uint16 sp;
-		uint16 csum;
-		uint16 ip;
-		uint16 cs;
-		uint16 lfarlc;
-		uint16 ovno;
-		uint16 res[4];
-		uint16 oemid;
-		uint16 oeminfo;
-		uint16 res2[10];
-		uint32 lfanew;
-	};
-
-	struct Win32ImageFileHeader {
-		uint16 machine;
-		uint16 number_of_sections;
-		uint32 time_date_stamp;
-		uint32 pointer_to_symbol_table;
-		uint32 number_of_symbols;
-		uint16 size_of_optional_header;
-		uint16 characteristics;
-	};
-
-	struct Win32ImageDataDirectory {
-		uint32 virtual_address;
-		uint32 size;
-	};
-
-	struct Win32ImageOptionalHeader {
-		uint16 magic;
-		byte major_linker_version;
-		byte minor_linker_version;
-		uint32 size_of_code;
-		uint32 size_of_initialized_data;
-		uint32 size_of_uninitialized_data;
-		uint32 address_of_entry_point;
-		uint32 base_of_code;
-		uint32 base_of_data;
-		uint32 image_base;
-		uint32 section_alignment;
-		uint32 file_alignment;
-		uint16 major_operating_system_version;
-		uint16 minor_operating_system_version;
-		uint16 major_image_version;
-		uint16 minor_image_version;
-		uint16 major_subsystem_version;
-		uint16 minor_subsystem_version;
-		uint32 win32_version_value;
-		uint32 size_of_image;
-		uint32 size_of_headers;
-		uint32 checksum;
-		uint16 subsystem;
-		uint16 dll_characteristics;
-		uint32 size_of_stack_reserve;
-		uint32 size_of_stack_commit;
-		uint32 size_of_heap_reserve;
-		uint32 size_of_heap_commit;
-		uint32 loader_flags;
-		uint32 number_of_rva_and_sizes;
-		Win32ImageDataDirectory data_directory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
-	};
-
-	struct Win32ImageNTHeaders {
-		uint32 signature;
-		Win32ImageFileHeader file_header;
-		Win32ImageOptionalHeader optional_header;
-	};
-
-	struct Win32ImageSectionHeader {
-		byte name[IMAGE_SIZEOF_SHORT_NAME];
-		union {
-			uint32 physical_address;
-			uint32 virtual_size;
-		} misc;
-		uint32 virtual_address;
-		uint32 size_of_raw_data;
-		uint32 pointer_to_raw_data;
-		uint32 pointer_to_relocations;
-		uint32 pointer_to_linenumbers;
-		uint16 number_of_relocations;
-		uint16 number_of_linenumbers;
-		uint32 characteristics;
-	};
-
-	struct Win32ImageResourceDataEntry {
-		uint32 offset_to_data;
-		uint32 size;
-		uint32 code_page;
-		uint32 resource_handle;
-	};
-
-	struct Win32ImageResourceDirectory {
-		uint32 characteristics;
-		uint32 time_date_stamp;
-		uint16 major_version;
-		uint16 minor_version;
-		uint16 number_of_named_entries;
-		uint16 number_of_id_entries;
-	};
-
-#if !defined(__GNUC__)
-	#pragma END_PACK_STRUCTS
-#endif
-
-/*
- * Function Prototypes
- */
-
-	WinResource *list_resources(WinLibrary *, WinResource *, int *);
-	bool read_library(WinLibrary *);
-	WinResource *find_resource(WinLibrary *, const char *, const char *, const char *, int *);
-	byte *get_resource_entry(WinLibrary *, WinResource *, int *);
-	int do_resources(WinLibrary *, const char *, char *, char *, int, byte **);
-	bool compare_resource_id(WinResource *, const char *);
-	const char *res_type_string_to_id(const char *);
-
-	const char *res_type_id_to_string(int);
-	char *get_destination_name(WinLibrary *, char *, char *, char *);
-
-	byte *extract_resource(WinLibrary *, WinResource *, int *, bool *, char *, char *, bool);
-	int extract_resources(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, byte **);
-	byte *extract_group_icon_cursor_resource(WinLibrary *, WinResource *, char *, int *, bool);
-
-	bool decode_pe_resource_id(WinLibrary *, WinResource *, uint32);
-	bool decode_ne_resource_id(WinLibrary *, WinResource *, uint16);
-	WinResource *list_ne_type_resources(WinLibrary *, int *);
-	WinResource *list_ne_name_resources(WinLibrary *, WinResource *, int *);
-	WinResource *list_pe_resources(WinLibrary *, Win32ImageResourceDirectory *, int, int *);
-	int calc_vma_size(WinLibrary *);
-	int do_resources_recurs(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, const char *, char *, char *, int, byte **);
-	char *get_resource_id_quoted(WinResource *);
-	WinResource *find_with_resource_array(WinLibrary *, WinResource *, const char *);
-
-	bool check_offset(byte *, int, const char *, void *, int);
-
-	uint32 simple_vec(byte *data, uint32 ofs, byte size);
-
-	void fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj);
-	void fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj);
-	void fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj);
-	void fix_win32_image_section_header(Win32ImageSectionHeader *obj);
-	void fix_os2_image_header_endian(OS2ImageHeader *obj);
-	void fix_win32_image_header_endian(Win32ImageNTHeaders *obj);
-	void fix_win32_image_data_directory(Win32ImageDataDirectory *obj);
-};
-
-class MacResExtractor : public ResExtractor {
-
-public:
-	MacResExtractor(ScummEngine_v70he *scumm);
-	~MacResExtractor() { }
-	void setCursor(int id) ;
-
-private:
-	int extractResource(int id, byte **buf);
-	bool init(Common::File in);
-	void readMap(Common::File in);
-	byte *getResource(Common::File in, const char *typeID, int16 resID, int *size);
-	int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
-			 int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
-
-	struct ResMap {
-		int16 resAttr;
-		int16 typeOffset;
-		int16 nameOffset;
-		int16 numTypes;
-	};
-
-	struct ResType {
-		char  id[5];
-		int16 items;
-		int16 offset;
-	};
-
-	struct Resource {
-		int16 id;
-		int16 nameOffset;
-		byte  attr;
-		int32 dataOffset;
-		byte  *name;
-	};
-
-	typedef Resource *ResPtr;
-
-private:
-	int _resOffset;
-	int32 _dataOffset;
-	int32 _dataLength;
-	int32 _mapOffset;
-	int32 _mapLength;
-	ResMap _resMap;
-	ResType *_resTypes;
-	ResPtr  *_resLists;
-};
-
-} // End of namespace Scumm
-
-#endif

Modified: scummvm/trunk/engines/scumm/he/script_v100he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v100he.cpp	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/he/script_v100he.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -30,7 +30,7 @@
 #include "scumm/he/intern_he.h"
 #include "scumm/object.h"
 #include "scumm/resource.h"
-#include "scumm/he/resource_v7he.h"
+#include "scumm/he/resource_he.h"
 #include "scumm/scumm.h"
 #include "scumm/sound.h"
 #include "scumm/he/sprite_he.h"

Copied: scummvm/trunk/engines/scumm/he/script_v60he.cpp (from rev 20696, scummvm/trunk/engines/scumm/he/script_v6he.cpp)
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v60he.cpp	                        (rev 0)
+++ scummvm/trunk/engines/scumm/he/script_v60he.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -0,0 +1,1276 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001  Ludvig Strigeus
+ * 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 "common/savefile.h"
+
+#include "scumm/actor.h"
+#include "scumm/charset.h"
+#include "scumm/imuse.h"
+#include "scumm/he/intern_he.h"
+#include "scumm/object.h"
+#include "scumm/resource.h"
+#include "scumm/scumm.h"
+#include "scumm/sound.h"
+#include "scumm/usage_bits.h"
+#include "scumm/util.h"
+#include "scumm/verbs.h"
+
+namespace Scumm {
+
+struct vsUnpackCtx {
+	uint8 size;
+	uint8 type;
+	uint8 b;
+	uint8 *ptr;
+};
+
+struct vsPackCtx {
+	int size;
+	uint8 buf[256];
+};
+
+static void virtScreenSavePackBuf(vsPackCtx *ctx, uint8 *&dst, int len);
+static void virtScreenSavePackByte(vsPackCtx *ctx, uint8 *&dst, int len, uint8 b);
+static uint8 virtScreenLoadUnpack(vsUnpackCtx *ctx, byte *data);
+static int virtScreenSavePack(byte *dst, byte *src, int len, int unk);
+
+// Compatibility notes:
+//
+// FBEAR (fbear, fbeardemo)
+//     transparency in akos.cpp
+//     negative size in file read/write
+
+#define OPCODE(x)	_OPCODE(ScummEngine_v60he, x)
+
+void ScummEngine_v60he::setupOpcodes() {
+	static const OpcodeEntryv60he opcodes[256] = {
+		/* 00 */
+		OPCODE(o6_pushByte),
+		OPCODE(o6_pushWord),
+		OPCODE(o6_pushByteVar),
+		OPCODE(o6_pushWordVar),
+		/* 04 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayRead),
+		OPCODE(o6_wordArrayRead),
+		/* 08 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayIndexedRead),
+		OPCODE(o6_wordArrayIndexedRead),
+		/* 0C */
+		OPCODE(o6_dup),
+		OPCODE(o6_not),
+		OPCODE(o6_eq),
+		OPCODE(o6_neq),
+		/* 10 */
+		OPCODE(o6_gt),
+		OPCODE(o6_lt),
+		OPCODE(o6_le),
+		OPCODE(o6_ge),
+		/* 14 */
+		OPCODE(o6_add),
+		OPCODE(o6_sub),
+		OPCODE(o6_mul),
+		OPCODE(o6_div),
+		/* 18 */
+		OPCODE(o6_land),
+		OPCODE(o6_lor),
+		OPCODE(o6_pop),
+		OPCODE(o6_invalid),
+		/* 1C */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 20 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 24 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 28 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 2C */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 30 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 34 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 38 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 3C */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 40 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_writeByteVar),
+		OPCODE(o6_writeWordVar),
+		/* 44 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayWrite),
+		OPCODE(o6_wordArrayWrite),
+		/* 48 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayIndexedWrite),
+		OPCODE(o6_wordArrayIndexedWrite),
+		/* 4C */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteVarInc),
+		OPCODE(o6_wordVarInc),
+		/* 50 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayInc),
+		OPCODE(o6_wordArrayInc),
+		/* 54 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteVarDec),
+		OPCODE(o6_wordVarDec),
+		/* 58 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayDec),
+		OPCODE(o6_wordArrayDec),
+		/* 5C */
+		OPCODE(o6_if),
+		OPCODE(o6_ifNot),
+		OPCODE(o6_startScript),
+		OPCODE(o6_startScriptQuick),
+		/* 60 */
+		OPCODE(o6_startObject),
+		OPCODE(o6_drawObject),
+		OPCODE(o6_drawObjectAt),
+		OPCODE(o6_invalid),
+		/* 64 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_stopObjectCode),
+		OPCODE(o6_stopObjectCode),
+		OPCODE(o6_endCutscene),
+		/* 68 */
+		OPCODE(o6_cutscene),
+		OPCODE(o6_stopMusic),
+		OPCODE(o6_freezeUnfreeze),
+		OPCODE(o6_cursorCommand),
+		/* 6C */
+		OPCODE(o6_breakHere),
+		OPCODE(o6_ifClassOfIs),
+		OPCODE(o6_setClass),
+		OPCODE(o6_getState),
+		/* 70 */
+		OPCODE(o60_setState),
+		OPCODE(o6_setOwner),
+		OPCODE(o6_getOwner),
+		OPCODE(o6_jump),
+		/* 74 */
+		OPCODE(o6_startSound),
+		OPCODE(o6_stopSound),
+		OPCODE(o6_startMusic),
+		OPCODE(o6_stopObjectScript),
+		/* 78 */
+		OPCODE(o6_panCameraTo),
+		OPCODE(o6_actorFollowCamera),
+		OPCODE(o6_setCameraAt),
+		OPCODE(o6_loadRoom),
+		/* 7C */
+		OPCODE(o6_stopScript),
+		OPCODE(o6_walkActorToObj),
+		OPCODE(o6_walkActorTo),
+		OPCODE(o6_putActorAtXY),
+		/* 80 */
+		OPCODE(o6_putActorAtObject),
+		OPCODE(o6_faceActor),
+		OPCODE(o6_animateActor),
+		OPCODE(o6_doSentence),
+		/* 84 */
+		OPCODE(o6_pickupObject),
+		OPCODE(o6_loadRoomWithEgo),
+		OPCODE(o6_invalid),
+		OPCODE(o6_getRandomNumber),
+		/* 88 */
+		OPCODE(o6_getRandomNumberRange),
+		OPCODE(o6_invalid),
+		OPCODE(o6_getActorMoving),
+		OPCODE(o6_isScriptRunning),
+		/* 8C */
+		OPCODE(o6_getActorRoom),
+		OPCODE(o6_getObjectX),
+		OPCODE(o6_getObjectY),
+		OPCODE(o6_getObjectOldDir),
+		/* 90 */
+		OPCODE(o6_getActorWalkBox),
+		OPCODE(o6_getActorCostume),
+		OPCODE(o6_findInventory),
+		OPCODE(o6_getInventoryCount),
+		/* 94 */
+		OPCODE(o6_getVerbFromXY),
+		OPCODE(o6_beginOverride),
+		OPCODE(o6_endOverride),
+		OPCODE(o6_setObjectName),
+		/* 98 */
+		OPCODE(o6_isSoundRunning),
+		OPCODE(o6_setBoxFlags),
+		OPCODE(o6_invalid),
+		OPCODE(o6_resourceRoutines),
+		/* 9C */
+		OPCODE(o60_roomOps),
+		OPCODE(o60_actorOps),
+		OPCODE(o6_verbOps),
+		OPCODE(o6_getActorFromXY),
+		/* A0 */
+		OPCODE(o6_findObject),
+		OPCODE(o6_pseudoRoom),
+		OPCODE(o6_getActorElevation),
+		OPCODE(o6_getVerbEntrypoint),
+		/* A4 */
+		OPCODE(o6_arrayOps),
+		OPCODE(o6_saveRestoreVerbs),
+		OPCODE(o6_drawBox),
+		OPCODE(o6_pop),
+		/* A8 */
+		OPCODE(o6_getActorWidth),
+		OPCODE(o6_wait),
+		OPCODE(o6_getActorScaleX),
+		OPCODE(o6_getActorAnimCounter1),
+		/* AC */
+		OPCODE(o6_invalid),
+		OPCODE(o6_isAnyOf),
+		OPCODE(o6_systemOps),
+		OPCODE(o6_isActorInBox),
+		/* B0 */
+		OPCODE(o6_delay),
+		OPCODE(o6_delaySeconds),
+		OPCODE(o6_delayMinutes),
+		OPCODE(o6_stopSentence),
+		/* B4 */
+		OPCODE(o6_printLine),
+		OPCODE(o6_printText),
+		OPCODE(o6_printDebug),
+		OPCODE(o6_printSystem),
+		/* B8 */
+		OPCODE(o6_printActor),
+		OPCODE(o6_printEgo),
+		OPCODE(o6_talkActor),
+		OPCODE(o6_talkEgo),
+		/* BC */
+		OPCODE(o6_dimArray),
+		OPCODE(o6_stopObjectCode),
+		OPCODE(o6_startObjectQuick),
+		OPCODE(o6_startScriptQuick2),
+		/* C0 */
+		OPCODE(o6_dim2dimArray),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* C4 */
+		OPCODE(o6_abs),
+		OPCODE(o6_distObjectObject),
+		OPCODE(o6_distObjectPt),
+		OPCODE(o6_distPtPt),
+		/* C8 */
+		OPCODE(o60_kernelGetFunctions),
+		OPCODE(o60_kernelSetFunctions),
+		OPCODE(o6_delayFrames),
+		OPCODE(o6_pickOneOf),
+		/* CC */
+		OPCODE(o6_pickOneOfDefault),
+		OPCODE(o6_stampObject),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* D0 */
+		OPCODE(o6_getDateTime),
+		OPCODE(o6_stopTalking),
+		OPCODE(o6_getAnimateVariable),
+		OPCODE(o6_invalid),
+		/* D4 */
+		OPCODE(o6_shuffle),
+		OPCODE(o6_jumpToScript),
+		OPCODE(o6_band),
+		OPCODE(o6_bor),
+		/* D8 */
+		OPCODE(o6_isRoomScriptRunning),
+		OPCODE(o60_closeFile),
+		OPCODE(o60_openFile),
+		OPCODE(o60_readFile),
+		/* DC */
+		OPCODE(o60_writeFile),
+		OPCODE(o6_findAllObjects),
+		OPCODE(o60_deleteFile),
+		OPCODE(o60_rename),
+		/* E0 */
+		OPCODE(o60_soundOps),
+		OPCODE(o6_getPixel),
+		OPCODE(o60_localizeArrayToScript),
+		OPCODE(o6_pickVarRandom),
+		/* E4 */
+		OPCODE(o6_setBoxSet),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* E8 */
+		OPCODE(o6_invalid),
+		OPCODE(o60_seekFilePos),
+		OPCODE(o60_redimArray),
+		OPCODE(o60_readFilePos),
+		/* EC */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* F0 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* F4 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* F8 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* FC */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+	};
+
+	_opcodesv60he = opcodes;
+}
+
+void ScummEngine_v60he::executeOpcode(byte i) {
+	OpcodeProcv60he op = _opcodesv60he[i].proc;
+	(this->*op) ();
+}
+
+const char *ScummEngine_v60he::getOpcodeDesc(byte i) {
+	return _opcodesv60he[i].desc;
+}
+
+void ScummEngine_v60he::o60_setState() {
+	int state = pop();
+	int obj = pop();
+
+	if (state & 0x8000) {
+		state &= 0x7FFF;
+		putState(obj, state);
+		if (_heversion >= 72)
+			removeObjectFromDrawQue(obj);
+	} else {
+		putState(obj, state);
+		markObjectRectAsDirty(obj);
+		if (_bgNeedsRedraw)
+			clearDrawObjectQueue();
+	}
+}
+
+void ScummEngine_v60he::o60_roomOps() {
+	int a, b, c, d, e;
+
+	byte subOp = fetchScriptByte();
+
+	switch (subOp) {
+	case 172:		// SO_ROOM_SCROLL
+		b = pop();
+		a = pop();
+		if (a < (_screenWidth / 2))
+			a = (_screenWidth / 2);
+		if (b < (_screenWidth / 2))
+			b = (_screenWidth / 2);
+		if (a > _roomWidth - (_screenWidth / 2))
+			a = _roomWidth - (_screenWidth / 2);
+		if (b > _roomWidth - (_screenWidth / 2))
+			b = _roomWidth - (_screenWidth / 2);
+		VAR(VAR_CAMERA_MIN_X) = a;
+		VAR(VAR_CAMERA_MAX_X) = b;
+		break;
+
+	case 174:		// SO_ROOM_SCREEN
+		b = pop();
+		a = pop();
+		if (_heversion >= 71)
+			initScreens(a, _screenHeight);
+		else
+			initScreens(a, b);
+		break;
+
+	case 175:		// SO_ROOM_PALETTE
+		d = pop();
+		c = pop();
+		b = pop();
+		a = pop();
+		setPalColor(d, a, b, c);
+		break;
+
+	case 176:		// SO_ROOM_SHAKE_ON
+		setShake(1);
+		break;
+
+	case 177:		// SO_ROOM_SHAKE_OFF
+		setShake(0);
+		break;
+
+	case 179:		// SO_ROOM_INTENSITY
+		c = pop();
+		b = pop();
+		a = pop();
+		darkenPalette(a, a, a, b, c);
+		break;
+
+	case 180:		// SO_ROOM_SAVEGAME
+		_saveTemporaryState = true;
+		_saveLoadSlot = pop();
+		_saveLoadFlag = pop();
+		break;
+
+	case 181:		// SO_ROOM_FADE
+		a = pop();
+		if (_heversion >= 70) {
+			// Defaults to 1 but doesn't use fade effects
+		} else if (a) {
+			_switchRoomEffect = (byte)(a & 0xFF);
+			_switchRoomEffect2 = (byte)(a >> 8);
+		} else {
+			fadeIn(_newEffect);
+		}
+		break;
+
+	case 182:		// SO_RGB_ROOM_INTENSITY
+		e = pop();
+		d = pop();
+		c = pop();
+		b = pop();
+		a = pop();
+		darkenPalette(a, b, c, d, e);
+		break;
+
+	case 183:		// SO_ROOM_SHADOW
+		e = pop();
+		d = pop();
+		c = pop();
+		b = pop();
+		a = pop();
+		if (_heversion == 60)
+			setupShadowPalette(a, b, c, d, e, 0, 256);
+		break;
+
+	case 186:		// SO_ROOM_TRANSFORM
+		d = pop();
+		c = pop();
+		b = pop();
+		a = pop();
+		palManipulateInit(a, b, c, d);
+		break;
+
+	case 187:		// SO_CYCLE_SPEED
+		b = pop();
+		a = pop();
+		checkRange(16, 1, a, "o60_roomOps: 187: color cycle out of range (%d)");
+		_colorCycle[a - 1].delay = (b != 0) ? 0x4000 / (b * 0x4C) : 0;
+		break;
+
+	case 213:		// SO_ROOM_NEW_PALETTE
+		a = pop();
+		setPalette(a);
+		break;
+	case 220:
+		a = pop();
+		b = pop();
+		copyPalColor(a, b);
+		break;
+	case 221:
+		int len;
+		len = resStrLen(_scriptPointer);
+		_scriptPointer += len + 1;
+		_saveLoadFlag = pop();
+		_saveLoadSlot = 1;
+		_saveTemporaryState = true;
+		break;
+	case 234:		// HE 7.2
+		b = pop();
+		a = pop();
+		swapObjects(a, b);
+		break;
+	case 236:		// HE 7.2
+		b = pop();
+		a = pop();
+		setRoomPalette(a, b);
+		break;
+	default:
+		error("o60_roomOps: default case %d", subOp);
+	}
+}
+
+void ScummEngine_v60he::swapObjects(int object1, int object2) {
+	int idx1 = -1, idx2 = -1;
+
+	for (int i = 0; i < _numLocalObjects; i++) {
+		if (_objs[i].obj_nr == object1)
+			idx1 = i;
+
+		if (_objs[i].obj_nr == object2)
+			idx2 = i;
+	}
+
+	if (idx1 == -1 || idx2 == -1 || idx1 <= idx2)
+		return;
+
+	stopObjectScript(object1);
+	stopObjectScript(object2);
+
+	ObjectData tmpOd;
+
+	memcpy(&tmpOd, &_objs[idx1], sizeof(tmpOd));
+	memcpy(&_objs[idx1], &_objs[idx2], sizeof(tmpOd));
+	memcpy(&_objs[idx2], &tmpOd, sizeof(tmpOd));
+}
+
+void ScummEngine_v60he::o60_actorOps() {
+	Actor *a;
+	int i, j, k;
+	int args[8];
+
+	byte subOp = fetchScriptByte();
+	if (subOp == 197) {
+		_curActor = pop();
+		return;
+	}
+
+	a = derefActorSafe(_curActor, "o60_actorOps");
+	if (!a)
+		return;
+
+	switch (subOp) {
+	case 30:
+		// _heversion >= 70
+		_actorClipOverride.bottom = pop();
+		_actorClipOverride.right = pop();
+		_actorClipOverride.top = pop();
+		_actorClipOverride.left = pop();
+		break;
+	case 76:		// SO_COSTUME
+		a->setActorCostume(pop());
+		break;
+	case 77:		// SO_STEP_DIST
+		j = pop();
+		i = pop();
+		a->setActorWalkSpeed(i, j);
+		break;
+	case 78:		// SO_SOUND
+		k = getStackList(args, ARRAYSIZE(args));
+		for (i = 0; i < k; i++)
+			a->_sound[i] = args[i];
+		break;
+	case 79:		// SO_WALK_ANIMATION
+		a->_walkFrame = pop();
+		break;
+	case 80:		// SO_TALK_ANIMATION
+		a->_talkStopFrame = pop();
+		a->_talkStartFrame = pop();
+		break;
+	case 81:		// SO_STAND_ANIMATION
+		a->_standFrame = pop();
+		break;
+	case 82:		// SO_ANIMATION
+		// dummy case in scumm6
+		pop();
+		pop();
+		pop();
+		break;
+	case 83:		// SO_DEFAULT
+		a->initActor(0);
+		break;
+	case 84:		// SO_ELEVATION
+		a->setElevation(pop());
+		break;
+	case 85:		// SO_ANIMATION_DEFAULT
+		a->_initFrame = 1;
+		a->_walkFrame = 2;
+		a->_standFrame = 3;
+		a->_talkStartFrame = 4;
+		a->_talkStopFrame = 5;
+		break;
+	case 86:		// SO_PALETTE
+		j = pop();
+		i = pop();
+		checkRange(255, 0, i, "Illegal palette slot %d");
+		a->remapActorPaletteColor(i, j);
+		a->_needRedraw = true;
+		break;
+	case 87:		// SO_TALK_COLOR
+		a->_talkColor = pop();
+		break;
+	case 88:		// SO_ACTOR_NAME
+		loadPtrToResource(rtActorName, a->_number, NULL);
+		break;
+	case 89:		// SO_INIT_ANIMATION
+		a->_initFrame = pop();
+		break;
+	case 91:		// SO_ACTOR_WIDTH
+		a->_width = pop();
+		break;
+	case 92:		// SO_SCALE
+		i = pop();
+		a->setScale(i, i);
+		break;
+	case 93:		// SO_NEVER_ZCLIP
+		a->_forceClip = 0;
+		break;
+	case 94:		// SO_ALWAYS_ZCLIP
+		a->_forceClip = pop();
+		break;
+	case 95:		// SO_IGNORE_BOXES
+		a->_ignoreBoxes = 1;
+		a->_forceClip = 0;
+		if (a->isInCurrentRoom())
+			a->putActor(a->_pos.x, a->_pos.y, a->_room);
+		break;
+	case 96:		// SO_FOLLOW_BOXES
+		a->_ignoreBoxes = 0;
+		a->_forceClip = 0;
+		if (a->isInCurrentRoom())
+			a->putActor(a->_pos.x, a->_pos.y, a->_room);
+		break;
+	case 97:		// SO_ANIMATION_SPEED
+		a->setAnimSpeed(pop());
+		break;
+	case 98:		// SO_SHADOW
+		a->_shadowMode = pop();
+		a->_needRedraw = true;
+		break;
+	case 99:		// SO_TEXT_OFFSET
+		a->_talkPosY = pop();
+		a->_talkPosX = pop();
+		break;
+	case 156:		// HE 7.2
+		a->_charset = pop();
+		break;
+	case 198:		// SO_ACTOR_VARIABLE
+		i = pop();
+		a->setAnimVar(pop(), i);
+		break;
+	case 215:		// SO_ACTOR_IGNORE_TURNS_ON
+		a->_ignoreTurns = true;
+		break;
+	case 216:		// SO_ACTOR_IGNORE_TURNS_OFF
+		a->_ignoreTurns = false;
+		break;
+	case 217:		// SO_ACTOR_NEW
+		a->initActor(2);
+		break;
+	case 218:
+		a->drawActorToBackBuf(a->_pos.x, a->_pos.y);
+		break;
+	case 219:
+		a->_drawToBackBuf = false;
+		a->_needRedraw = true;
+		a->_needBgReset = true;
+		break;
+	case 225:
+		{
+		byte string[128];
+		copyScriptString(string);
+		int slot = pop();
+
+		int len = resStrLen(string) + 1;
+		convertMessageToString(string, a->_heTalkQueue[slot].sentence, len);
+
+		a->_heTalkQueue[slot].posX = a->_talkPosX;
+		a->_heTalkQueue[slot].posY = a->_talkPosY;
+		a->_heTalkQueue[slot].color = a->_talkColor;
+		break;
+		}
+	default:
+		error("o60_actorOps: default case %d", subOp);
+	}
+}
+
+void ScummEngine_v60he::o60_kernelSetFunctions() {
+	int args[29];
+	int num;
+
+	num = getStackList(args, ARRAYSIZE(args));
+
+	switch (args[0]) {
+	case 1:
+		// Used to restore images when decorating cake in
+		// Fatty Bear's Birthday Surprise
+		virtScreenLoad(args[1], args[2], args[3], args[4], args[5]);
+		break;
+	case 3:
+	case 4:
+	case 5:
+	case 6:
+	case 8:
+		//Used before mini games in 3DO versions, seems safe to ignore.
+		break;
+	default:
+		error("o60_kernelSetFunctions: default case %d (param count %d)", args[0], num);
+	}
+}
+
+void ScummEngine_v60he::virtScreenLoad(int resIdx, int x1, int y1, int x2, int y2) {
+	vsUnpackCtx ctx;
+	memset(&ctx, 0, sizeof(ctx));
+	VirtScreen &vs = virtscr[kMainVirtScreen];
+
+	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, resIdx);
+	virtScreenLoadUnpack(&ctx, ah->data);
+	for (int j = y1; j <= y2; ++j) {
+		uint8 *p1 = vs.getPixels(x1, j - vs.topline);
+		uint8 *p2 = vs.getBackPixels(x1, j - vs.topline);
+		if (x2 >= x1) {
+			uint32 w = x2 - x1 + 1;
+			while (w--) {
+				uint8 decByte = virtScreenLoadUnpack(&ctx, 0);
+				*p1++ = decByte;
+				*p2++ = decByte;
+			}
+		}
+	}
+	markRectAsDirty(kMainVirtScreen, x1, x2, y1, y2 + 1, USAGE_BIT_RESTORED);
+}
+
+uint8 virtScreenLoadUnpack(vsUnpackCtx *ctx, byte *data) {
+	uint8 decByte;
+	if (data != 0) {
+		ctx->type = 0;
+		ctx->ptr = data;
+		decByte = 0;
+	} else {
+		uint8 a;
+		if (ctx->type == 0) {
+			a = *(ctx->ptr)++;
+			if (a & 1) {
+				ctx->type = 1;
+				ctx->b = *(ctx->ptr)++;
+			} else {
+				ctx->type = 2;
+			}
+			ctx->size = a;
+			a = (a >> 1) + 1;
+		} else {
+ 			a = ctx->size;
+		}
+  		if (ctx->type == 2) {
+  			ctx->b = *(ctx->ptr)++;
+  		}
+  		ctx->size = a - 1;
+  		if (ctx->size == 0) {
+  			ctx->type = 0;
+  		}
+  		decByte = ctx->b;
+	}
+	return decByte;
+}
+
+
+void ScummEngine_v60he::o60_kernelGetFunctions() {
+	int args[29];
+	ArrayHeader *ah;
+	getStackList(args, ARRAYSIZE(args));
+
+	switch (args[0]) {
+	case 1:
+		// Used to store images when decorating cake in
+		// Fatty Bear's Birthday Surprise
+		writeVar(0, 0);
+		ah = defineArray(0, kByteArray, 0, virtScreenSave(0, args[1], args[2], args[3], args[4]));
+		virtScreenSave(ah->data, args[1], args[2], args[3], args[4]);
+		push(readVar(0));
+		break;
+	default:
+		error("o60_kernelGetFunctions: default case %d", args[0]);
+	}
+}
+
+int ScummEngine_v60he::virtScreenSave(byte *dst, int x1, int y1, int x2, int y2) {
+	int packedSize = 0;
+	VirtScreen &vs = virtscr[kMainVirtScreen];
+
+	for (int j = y1; j <= y2; ++j) {
+		uint8 *p = vs.getBackPixels(x1, j - vs.topline);
+
+		int size = virtScreenSavePack(dst, p, x2 - x1 + 1, 0);
+		if (dst != 0) {
+			dst += size;
+		}
+		packedSize += size;
+	}
+	return packedSize;
+}
+
+int virtScreenSavePack(byte *dst, byte *src, int len, int unk) {
+	vsPackCtx ctx;
+	memset(&ctx, 0, sizeof(ctx));
+
+	uint8 prevByte, curByte;
+
+	ctx.buf[0] = prevByte = *src++;
+	int flag = 0;
+	int iend = 1;
+	int ibeg = 0;
+
+	for (--len; len != 0; --len, prevByte = curByte) {
+		bool pass = false;
+
+		assert(iend < 0x100);
+		ctx.buf[iend] = curByte = *src++;
+		++iend;
+
+		if (flag == 0) {
+			if (iend > 0x80) {
+				virtScreenSavePackBuf(&ctx, dst, iend - 1);
+				ctx.buf[0] = curByte;
+				iend = 1;
+				ibeg = 0;
+				continue;
+			}
+			if (prevByte != curByte) {
+				ibeg = iend - 1;
+				continue;
+			}
+			if (iend - ibeg < 3) {
+				if (ibeg != 0) {
+					pass = true;
+				} else {
+					flag = 1;
+				}
+			} else {
+				if (ibeg > 0) {
+					virtScreenSavePackBuf(&ctx, dst, ibeg);
+				}
+				flag = 1;
+			}
+		}
+		if (flag == 1 || pass) {
+			if (prevByte != curByte || iend - ibeg > 0x80) {
+				virtScreenSavePackByte(&ctx, dst, iend - ibeg - 1, prevByte);
+				ctx.buf[0] = curByte;
+				iend = 1;
+				ibeg = 0;
+				flag = 0;
+			}
+		}
+	}
+
+	if (flag == 0) {
+		virtScreenSavePackBuf(&ctx, dst, iend);
+	} else if (flag == 1) {
+		virtScreenSavePackByte(&ctx, dst, iend - ibeg, prevByte);
+	}
+	return ctx.size;
+}
+
+void virtScreenSavePackBuf(vsPackCtx *ctx, uint8 *&dst, int len) {
+	if (dst) {
+		*dst++ = (len - 1) * 2;
+	}
+	++ctx->size;
+	if (len > 0) {
+		ctx->size += len;
+		if (dst) {
+			memcpy(dst, ctx->buf, len);
+			dst += len;
+		}
+	}
+}
+
+void virtScreenSavePackByte(vsPackCtx *ctx, uint8 *&dst, int len, uint8 b) {
+	if (dst) {
+		*dst++ = ((len - 1) * 2) | 1;
+	}
+	++ctx->size;
+	if (dst) {
+		*dst++ = b;
+	}
+	++ctx->size;
+}
+
+void ScummEngine_v60he::o60_openFile() {
+	int mode, len, slot, l, r;
+	byte filename[100];
+
+	convertMessageToString(_scriptPointer, filename, sizeof(filename));
+
+	len = resStrLen(_scriptPointer);
+	_scriptPointer += len + 1;
+
+	for (r = strlen((char*)filename); r != 0; r--) {
+		if (filename[r - 1] == '\\')
+			break;
+	}
+
+	mode = pop();
+	slot = -1;
+	for (l = 0; l < 17; l++) {
+		if (_hFileTable[l].isOpen() == false) {
+			slot = l;
+			break;
+		}
+	}
+
+	if (slot != -1) {
+		switch(mode) {
+		case 1:
+			_hFileTable[slot].open((char*)filename + r, Common::File::kFileReadMode, _saveFileMan->getSavePath());
+			if (_hFileTable[slot].isOpen() == false)
+				_hFileTable[slot].open((char*)filename + r, Common::File::kFileReadMode);
+			break;
+		case 2:
+			_hFileTable[slot].open((char*)filename + r, Common::File::kFileWriteMode, _saveFileMan->getSavePath());
+			break;
+		default:
+			error("o60_openFile(): wrong open file mode %d", mode);
+		}
+
+		if (_hFileTable[slot].isOpen() == false)
+			slot = -1;
+
+	}
+	push(slot);
+}
+
+void ScummEngine_v60he::o60_closeFile() {
+	int slot = pop();
+	if (slot != -1)
+		_hFileTable[slot].close();
+}
+
+void ScummEngine_v60he::o60_deleteFile() {
+	int len, r;
+	byte filename[100];
+
+	convertMessageToString(_scriptPointer, filename, sizeof(filename));
+
+	len = resStrLen(_scriptPointer);
+	_scriptPointer += len + 1;
+
+	for (r = strlen((char*)filename); r != 0; r--) {
+		if (filename[r - 1] == '\\')
+			break;
+	}
+
+	debug(1, "stub o60_deleteFile(\"%s\")", filename + r);
+}
+
+void ScummEngine_v60he::o60_rename() {
+	int len, r1, r2;
+	byte filename[100],filename2[100];
+
+	convertMessageToString(_scriptPointer, filename, sizeof(filename));
+
+	len = resStrLen(_scriptPointer);
+	_scriptPointer += len + 1;
+
+	for (r1 = strlen((char*)filename); r1 != 0; r1--) {
+		if (filename[r1 - 1] == '\\')
+			break;
+	}
+
+	convertMessageToString(_scriptPointer, filename2, sizeof(filename2));
+
+	len = resStrLen(_scriptPointer);
+	_scriptPointer += len + 1;
+
+	for (r2 = strlen((char*)filename2); r2 != 0; r2--) {
+		if (filename2[r2 - 1] == '\\')
+			break;
+	}
+
+	debug(1, "stub o60_rename(\"%s\" to \"%s\")", filename + r1, filename2 + r2);
+}
+
+int ScummEngine_v60he::readFileToArray(int slot, int32 size) {
+	if (size == 0)
+		size = _hFileTable[slot].size() - _hFileTable[slot].pos();
+
+	writeVar(0, 0);
+
+	ArrayHeader *ah = defineArray(0, kByteArray, 0, size);
+	_hFileTable[slot].read(ah->data, size);
+
+	return readVar(0);
+}
+
+void ScummEngine_v60he::o60_readFile() {
+	int32 size = pop();
+	int slot = pop();
+	int val;
+
+	// Fatty Bear uses positive values
+	if ((_platform == Common::kPlatformPC) && (_gameId == GID_FBEAR))
+		size = -size;
+
+	if (size == -2) {
+		val = _hFileTable[slot].readUint16LE();
+		push(val);
+	} else if (size == -1) {
+		val = _hFileTable[slot].readByte();
+		push(val);
+	} else {
+		val = readFileToArray(slot, size);
+		push(val);
+	}
+}
+
+void ScummEngine_v60he::writeFileFromArray(int slot, int resID) {
+	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, resID);
+	int32 size = FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2);
+
+	_hFileTable[slot].write(ah->data, size);
+}
+
+void ScummEngine_v60he::o60_writeFile() {
+	int32 size = pop();
+	int16 resID = pop();
+	int slot = pop();
+
+	// Fatty Bear uses positive values
+	if ((_platform == Common::kPlatformPC) && (_gameId == GID_FBEAR))
+		size = -size;
+
+	if (size == -2) {
+		_hFileTable[slot].writeUint16LE(resID);
+	} else if (size == -1) {
+		_hFileTable[slot].writeByte(resID);
+	} else {
+		writeFileFromArray(slot, resID);
+	}
+}
+
+void ScummEngine_v60he::o60_soundOps() {
+	byte subOp = fetchScriptByte();
+	int arg = pop();
+
+	switch (subOp) {
+	case 0xde:
+		_imuse->setMusicVolume(arg);
+		break;
+	case 0xdf:
+		// Used in fbear introduction
+		break;
+	case 0xe0:
+		// Fatty Bear's Birthday surprise uses this when playing the
+		// piano, but only when using one of the digitized instruments.
+		// See also o6_startSound().
+		_sound->setOverrideFreq(arg);
+		break;
+	default:
+		error("o60_soundOps: default case 0x%x", subOp);
+	}
+}
+
+void ScummEngine_v60he::localizeArray(int slot, byte scriptSlot) {
+	if (_heversion >= 80)
+		slot &= ~0x33539000;
+
+	if (slot >= _numArray)
+		error("o60_localizeArrayToScript(%d): array slot out of range", slot);
+
+	_arraySlot[slot] = scriptSlot;
+}
+
+void ScummEngine_v60he::o60_localizeArrayToScript() {
+	int slot = pop();
+	localizeArray(slot, _currentScript);
+}
+
+void ScummEngine_v60he::o60_seekFilePos() {
+	int mode, offset, slot;
+
+	mode = pop();
+	offset = pop();
+	slot = pop();
+
+	if (slot == -1)
+		return;
+
+	switch (mode) {
+	case 1:
+		_hFileTable[slot].seek(offset, SEEK_SET);
+		break;
+	case 2:
+		_hFileTable[slot].seek(offset, SEEK_CUR);
+		break;
+	case 3:
+		_hFileTable[slot].seek(offset, SEEK_END);
+		break;
+	default:
+		error("o60_seekFilePos: default case %d", mode);
+	}
+}
+
+void ScummEngine_v60he::o60_readFilePos() {
+	int slot = pop();
+
+	if (slot == -1) {
+		push(0);
+		return;
+	}
+
+	push(_hFileTable[slot].pos());
+}
+
+void ScummEngine_v60he::o60_redimArray() {
+	int newX, newY;
+	newY = pop();
+	newX = pop();
+
+	if (newY == 0)
+		SWAP(newX, newY);
+
+	byte subOp = fetchScriptByte();
+	switch (subOp) {
+	case 199:
+		redimArray(fetchScriptWord(), newX, newY, kIntArray);
+		break;
+	case 202:
+		redimArray(fetchScriptWord(), newX, newY, kByteArray);
+		break;
+	default:
+		error("o60_redimArray: default type %d", subOp);
+	}
+}
+
+void ScummEngine_v60he::redimArray(int arrayId, int newX, int newY, int type) {
+	// Used in mini game at Cosmic Dust Diner in puttmoon
+	int newSize, oldSize;
+
+	if (readVar(arrayId) == 0)
+		error("redimArray: Reference to zeroed array pointer");
+
+	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(arrayId));
+
+	if (!ah)
+		error("redimArray: Invalid array (%d) reference", readVar(arrayId));
+
+	newSize = (type == kIntArray) ? 2 : 1;
+	oldSize = (ah->type == kIntArray) ? 2 : 1;
+
+	newSize *= (newX + 1) * (newY + 1);
+	oldSize *= FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2);
+
+	if (newSize != oldSize)
+		error("redimArray: array %d redim mismatch", readVar(arrayId));
+
+	ah->type = TO_LE_16(type);
+	ah->dim1 = TO_LE_16(newY + 1);
+	ah->dim2 = TO_LE_16(newX + 1);
+}
+
+void ScummEngine_v60he::decodeParseString(int m, int n) {
+	int i, colors;
+	int args[31];
+
+	byte b = fetchScriptByte();
+
+	switch (b) {
+	case 65:		// SO_AT
+		_string[m].ypos = pop();
+		_string[m].xpos = pop();
+		_string[m].overhead = false;
+		break;
+	case 66:		// SO_COLOR
+		_string[m].color = pop();
+		break;
+	case 67:		// SO_CLIPPED
+		_string[m].right = pop();
+		break;
+	case 69:		// SO_CENTER
+		_string[m].center = true;
+		_string[m].overhead = false;
+		break;
+	case 71:		// SO_LEFT
+		_string[m].center = false;
+		_string[m].overhead = false;
+		break;
+	case 72:		// SO_OVERHEAD
+		_string[m].overhead = true;
+		_string[m].no_talk_anim = false;
+		break;
+	case 74:		// SO_MUMBLE
+		_string[m].no_talk_anim = true;
+		break;
+	case 75:		// SO_TEXTSTRING
+		printString(m, _scriptPointer);
+		_scriptPointer += resStrLen(_scriptPointer) + 1;
+		break;
+	case 0xF9:
+		colors = pop();
+		if (colors == 1) {
+			_string[m].color = pop();
+		} else {
+			push(colors);
+			getStackList(args, ARRAYSIZE(args));
+			for (i = 0; i < 16; i++)
+				_charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
+			_string[m].color = _charsetColorMap[0];
+		}
+		break;
+	case 0xFE:
+		_string[m].loadDefault();
+		if (n)
+			_actorToPrintStrFor = pop();
+		break;
+	case 0xFF:
+		_string[m].saveDefault();
+		break;
+	default:
+		error("decodeParseString: default case 0x%x", b);
+	}
+}
+
+} // End of namespace Scumm

Deleted: scummvm/trunk/engines/scumm/he/script_v6he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v6he.cpp	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/he/script_v6he.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -1,1276 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001  Ludvig Strigeus
- * 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 "common/savefile.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/imuse.h"
-#include "scumm/he/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/usage_bits.h"
-#include "scumm/util.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-struct vsUnpackCtx {
-	uint8 size;
-	uint8 type;
-	uint8 b;
-	uint8 *ptr;
-};
-
-struct vsPackCtx {
-	int size;
-	uint8 buf[256];
-};
-
-static void virtScreenSavePackBuf(vsPackCtx *ctx, uint8 *&dst, int len);
-static void virtScreenSavePackByte(vsPackCtx *ctx, uint8 *&dst, int len, uint8 b);
-static uint8 virtScreenLoadUnpack(vsUnpackCtx *ctx, byte *data);
-static int virtScreenSavePack(byte *dst, byte *src, int len, int unk);
-
-// Compatibility notes:
-//
-// FBEAR (fbear, fbeardemo)
-//     transparency in akos.cpp
-//     negative size in file read/write
-
-#define OPCODE(x)	_OPCODE(ScummEngine_v60he, x)
-
-void ScummEngine_v60he::setupOpcodes() {
-	static const OpcodeEntryv60he opcodes[256] = {
-		/* 00 */
-		OPCODE(o6_pushByte),
-		OPCODE(o6_pushWord),
-		OPCODE(o6_pushByteVar),
-		OPCODE(o6_pushWordVar),
-		/* 04 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayRead),
-		OPCODE(o6_wordArrayRead),
-		/* 08 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayIndexedRead),
-		OPCODE(o6_wordArrayIndexedRead),
-		/* 0C */
-		OPCODE(o6_dup),
-		OPCODE(o6_not),
-		OPCODE(o6_eq),
-		OPCODE(o6_neq),
-		/* 10 */
-		OPCODE(o6_gt),
-		OPCODE(o6_lt),
-		OPCODE(o6_le),
-		OPCODE(o6_ge),
-		/* 14 */
-		OPCODE(o6_add),
-		OPCODE(o6_sub),
-		OPCODE(o6_mul),
-		OPCODE(o6_div),
-		/* 18 */
-		OPCODE(o6_land),
-		OPCODE(o6_lor),
-		OPCODE(o6_pop),
-		OPCODE(o6_invalid),
-		/* 1C */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 20 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 24 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 28 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 2C */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 30 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 34 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 38 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 3C */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 40 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_writeByteVar),
-		OPCODE(o6_writeWordVar),
-		/* 44 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayWrite),
-		OPCODE(o6_wordArrayWrite),
-		/* 48 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayIndexedWrite),
-		OPCODE(o6_wordArrayIndexedWrite),
-		/* 4C */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteVarInc),
-		OPCODE(o6_wordVarInc),
-		/* 50 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayInc),
-		OPCODE(o6_wordArrayInc),
-		/* 54 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteVarDec),
-		OPCODE(o6_wordVarDec),
-		/* 58 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayDec),
-		OPCODE(o6_wordArrayDec),
-		/* 5C */
-		OPCODE(o6_if),
-		OPCODE(o6_ifNot),
-		OPCODE(o6_startScript),
-		OPCODE(o6_startScriptQuick),
-		/* 60 */
-		OPCODE(o6_startObject),
-		OPCODE(o6_drawObject),
-		OPCODE(o6_drawObjectAt),
-		OPCODE(o6_invalid),
-		/* 64 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_stopObjectCode),
-		OPCODE(o6_stopObjectCode),
-		OPCODE(o6_endCutscene),
-		/* 68 */
-		OPCODE(o6_cutscene),
-		OPCODE(o6_stopMusic),
-		OPCODE(o6_freezeUnfreeze),
-		OPCODE(o6_cursorCommand),
-		/* 6C */
-		OPCODE(o6_breakHere),
-		OPCODE(o6_ifClassOfIs),
-		OPCODE(o6_setClass),
-		OPCODE(o6_getState),
-		/* 70 */
-		OPCODE(o60_setState),
-		OPCODE(o6_setOwner),
-		OPCODE(o6_getOwner),
-		OPCODE(o6_jump),
-		/* 74 */
-		OPCODE(o6_startSound),
-		OPCODE(o6_stopSound),
-		OPCODE(o6_startMusic),
-		OPCODE(o6_stopObjectScript),
-		/* 78 */
-		OPCODE(o6_panCameraTo),
-		OPCODE(o6_actorFollowCamera),
-		OPCODE(o6_setCameraAt),
-		OPCODE(o6_loadRoom),
-		/* 7C */
-		OPCODE(o6_stopScript),
-		OPCODE(o6_walkActorToObj),
-		OPCODE(o6_walkActorTo),
-		OPCODE(o6_putActorAtXY),
-		/* 80 */
-		OPCODE(o6_putActorAtObject),
-		OPCODE(o6_faceActor),
-		OPCODE(o6_animateActor),
-		OPCODE(o6_doSentence),
-		/* 84 */
-		OPCODE(o6_pickupObject),
-		OPCODE(o6_loadRoomWithEgo),
-		OPCODE(o6_invalid),
-		OPCODE(o6_getRandomNumber),
-		/* 88 */
-		OPCODE(o6_getRandomNumberRange),
-		OPCODE(o6_invalid),
-		OPCODE(o6_getActorMoving),
-		OPCODE(o6_isScriptRunning),
-		/* 8C */
-		OPCODE(o6_getActorRoom),
-		OPCODE(o6_getObjectX),
-		OPCODE(o6_getObjectY),
-		OPCODE(o6_getObjectOldDir),
-		/* 90 */
-		OPCODE(o6_getActorWalkBox),
-		OPCODE(o6_getActorCostume),
-		OPCODE(o6_findInventory),
-		OPCODE(o6_getInventoryCount),
-		/* 94 */
-		OPCODE(o6_getVerbFromXY),
-		OPCODE(o6_beginOverride),
-		OPCODE(o6_endOverride),
-		OPCODE(o6_setObjectName),
-		/* 98 */
-		OPCODE(o6_isSoundRunning),
-		OPCODE(o6_setBoxFlags),
-		OPCODE(o6_invalid),
-		OPCODE(o6_resourceRoutines),
-		/* 9C */
-		OPCODE(o60_roomOps),
-		OPCODE(o60_actorOps),
-		OPCODE(o6_verbOps),
-		OPCODE(o6_getActorFromXY),
-		/* A0 */
-		OPCODE(o6_findObject),
-		OPCODE(o6_pseudoRoom),
-		OPCODE(o6_getActorElevation),
-		OPCODE(o6_getVerbEntrypoint),
-		/* A4 */
-		OPCODE(o6_arrayOps),
-		OPCODE(o6_saveRestoreVerbs),
-		OPCODE(o6_drawBox),
-		OPCODE(o6_pop),
-		/* A8 */
-		OPCODE(o6_getActorWidth),
-		OPCODE(o6_wait),
-		OPCODE(o6_getActorScaleX),
-		OPCODE(o6_getActorAnimCounter1),
-		/* AC */
-		OPCODE(o6_invalid),
-		OPCODE(o6_isAnyOf),
-		OPCODE(o6_systemOps),
-		OPCODE(o6_isActorInBox),
-		/* B0 */
-		OPCODE(o6_delay),
-		OPCODE(o6_delaySeconds),
-		OPCODE(o6_delayMinutes),
-		OPCODE(o6_stopSentence),
-		/* B4 */
-		OPCODE(o6_printLine),
-		OPCODE(o6_printText),
-		OPCODE(o6_printDebug),
-		OPCODE(o6_printSystem),
-		/* B8 */
-		OPCODE(o6_printActor),
-		OPCODE(o6_printEgo),
-		OPCODE(o6_talkActor),
-		OPCODE(o6_talkEgo),
-		/* BC */
-		OPCODE(o6_dimArray),
-		OPCODE(o6_stopObjectCode),
-		OPCODE(o6_startObjectQuick),
-		OPCODE(o6_startScriptQuick2),
-		/* C0 */
-		OPCODE(o6_dim2dimArray),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* C4 */
-		OPCODE(o6_abs),
-		OPCODE(o6_distObjectObject),
-		OPCODE(o6_distObjectPt),
-		OPCODE(o6_distPtPt),
-		/* C8 */
-		OPCODE(o60_kernelGetFunctions),
-		OPCODE(o60_kernelSetFunctions),
-		OPCODE(o6_delayFrames),
-		OPCODE(o6_pickOneOf),
-		/* CC */
-		OPCODE(o6_pickOneOfDefault),
-		OPCODE(o6_stampObject),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* D0 */
-		OPCODE(o6_getDateTime),
-		OPCODE(o6_stopTalking),
-		OPCODE(o6_getAnimateVariable),
-		OPCODE(o6_invalid),
-		/* D4 */
-		OPCODE(o6_shuffle),
-		OPCODE(o6_jumpToScript),
-		OPCODE(o6_band),
-		OPCODE(o6_bor),
-		/* D8 */
-		OPCODE(o6_isRoomScriptRunning),
-		OPCODE(o60_closeFile),
-		OPCODE(o60_openFile),
-		OPCODE(o60_readFile),
-		/* DC */
-		OPCODE(o60_writeFile),
-		OPCODE(o6_findAllObjects),
-		OPCODE(o60_deleteFile),
-		OPCODE(o60_rename),
-		/* E0 */
-		OPCODE(o60_soundOps),
-		OPCODE(o6_getPixel),
-		OPCODE(o60_localizeArrayToScript),
-		OPCODE(o6_pickVarRandom),
-		/* E4 */
-		OPCODE(o6_setBoxSet),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* E8 */
-		OPCODE(o6_invalid),
-		OPCODE(o60_seekFilePos),
-		OPCODE(o60_redimArray),
-		OPCODE(o60_readFilePos),
-		/* EC */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* F0 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* F4 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* F8 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* FC */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-	};
-
-	_opcodesv60he = opcodes;
-}
-
-void ScummEngine_v60he::executeOpcode(byte i) {
-	OpcodeProcv60he op = _opcodesv60he[i].proc;
-	(this->*op) ();
-}
-
-const char *ScummEngine_v60he::getOpcodeDesc(byte i) {
-	return _opcodesv60he[i].desc;
-}
-
-void ScummEngine_v60he::o60_setState() {
-	int state = pop();
-	int obj = pop();
-
-	if (state & 0x8000) {
-		state &= 0x7FFF;
-		putState(obj, state);
-		if (_heversion >= 72)
-			removeObjectFromDrawQue(obj);
-	} else {
-		putState(obj, state);
-		markObjectRectAsDirty(obj);
-		if (_bgNeedsRedraw)
-			clearDrawObjectQueue();
-	}
-}
-
-void ScummEngine_v60he::o60_roomOps() {
-	int a, b, c, d, e;
-
-	byte subOp = fetchScriptByte();
-
-	switch (subOp) {
-	case 172:		// SO_ROOM_SCROLL
-		b = pop();
-		a = pop();
-		if (a < (_screenWidth / 2))
-			a = (_screenWidth / 2);
-		if (b < (_screenWidth / 2))
-			b = (_screenWidth / 2);
-		if (a > _roomWidth - (_screenWidth / 2))
-			a = _roomWidth - (_screenWidth / 2);
-		if (b > _roomWidth - (_screenWidth / 2))
-			b = _roomWidth - (_screenWidth / 2);
-		VAR(VAR_CAMERA_MIN_X) = a;
-		VAR(VAR_CAMERA_MAX_X) = b;
-		break;
-
-	case 174:		// SO_ROOM_SCREEN
-		b = pop();
-		a = pop();
-		if (_heversion >= 71)
-			initScreens(a, _screenHeight);
-		else
-			initScreens(a, b);
-		break;
-
-	case 175:		// SO_ROOM_PALETTE
-		d = pop();
-		c = pop();
-		b = pop();
-		a = pop();
-		setPalColor(d, a, b, c);
-		break;
-
-	case 176:		// SO_ROOM_SHAKE_ON
-		setShake(1);
-		break;
-
-	case 177:		// SO_ROOM_SHAKE_OFF
-		setShake(0);
-		break;
-
-	case 179:		// SO_ROOM_INTENSITY
-		c = pop();
-		b = pop();
-		a = pop();
-		darkenPalette(a, a, a, b, c);
-		break;
-
-	case 180:		// SO_ROOM_SAVEGAME
-		_saveTemporaryState = true;
-		_saveLoadSlot = pop();
-		_saveLoadFlag = pop();
-		break;
-
-	case 181:		// SO_ROOM_FADE
-		a = pop();
-		if (_heversion >= 70) {
-			// Defaults to 1 but doesn't use fade effects
-		} else if (a) {
-			_switchRoomEffect = (byte)(a & 0xFF);
-			_switchRoomEffect2 = (byte)(a >> 8);
-		} else {
-			fadeIn(_newEffect);
-		}
-		break;
-
-	case 182:		// SO_RGB_ROOM_INTENSITY
-		e = pop();
-		d = pop();
-		c = pop();
-		b = pop();
-		a = pop();
-		darkenPalette(a, b, c, d, e);
-		break;
-
-	case 183:		// SO_ROOM_SHADOW
-		e = pop();
-		d = pop();
-		c = pop();
-		b = pop();
-		a = pop();
-		if (_heversion == 60)
-			setupShadowPalette(a, b, c, d, e, 0, 256);
-		break;
-
-	case 186:		// SO_ROOM_TRANSFORM
-		d = pop();
-		c = pop();
-		b = pop();
-		a = pop();
-		palManipulateInit(a, b, c, d);
-		break;
-
-	case 187:		// SO_CYCLE_SPEED
-		b = pop();
-		a = pop();
-		checkRange(16, 1, a, "o60_roomOps: 187: color cycle out of range (%d)");
-		_colorCycle[a - 1].delay = (b != 0) ? 0x4000 / (b * 0x4C) : 0;
-		break;
-
-	case 213:		// SO_ROOM_NEW_PALETTE
-		a = pop();
-		setPalette(a);
-		break;
-	case 220:
-		a = pop();
-		b = pop();
-		copyPalColor(a, b);
-		break;
-	case 221:
-		int len;
-		len = resStrLen(_scriptPointer);
-		_scriptPointer += len + 1;
-		_saveLoadFlag = pop();
-		_saveLoadSlot = 1;
-		_saveTemporaryState = true;
-		break;
-	case 234:		// HE 7.2
-		b = pop();
-		a = pop();
-		swapObjects(a, b);
-		break;
-	case 236:		// HE 7.2
-		b = pop();
-		a = pop();
-		setRoomPalette(a, b);
-		break;
-	default:
-		error("o60_roomOps: default case %d", subOp);
-	}
-}
-
-void ScummEngine_v60he::swapObjects(int object1, int object2) {
-	int idx1 = -1, idx2 = -1;
-
-	for (int i = 0; i < _numLocalObjects; i++) {
-		if (_objs[i].obj_nr == object1)
-			idx1 = i;
-
-		if (_objs[i].obj_nr == object2)
-			idx2 = i;
-	}
-
-	if (idx1 == -1 || idx2 == -1 || idx1 <= idx2)
-		return;
-
-	stopObjectScript(object1);
-	stopObjectScript(object2);
-
-	ObjectData tmpOd;
-
-	memcpy(&tmpOd, &_objs[idx1], sizeof(tmpOd));
-	memcpy(&_objs[idx1], &_objs[idx2], sizeof(tmpOd));
-	memcpy(&_objs[idx2], &tmpOd, sizeof(tmpOd));
-}
-
-void ScummEngine_v60he::o60_actorOps() {
-	Actor *a;
-	int i, j, k;
-	int args[8];
-
-	byte subOp = fetchScriptByte();
-	if (subOp == 197) {
-		_curActor = pop();
-		return;
-	}
-
-	a = derefActorSafe(_curActor, "o60_actorOps");
-	if (!a)
-		return;
-
-	switch (subOp) {
-	case 30:
-		// _heversion >= 70
-		_actorClipOverride.bottom = pop();
-		_actorClipOverride.right = pop();
-		_actorClipOverride.top = pop();
-		_actorClipOverride.left = pop();
-		break;
-	case 76:		// SO_COSTUME
-		a->setActorCostume(pop());
-		break;
-	case 77:		// SO_STEP_DIST
-		j = pop();
-		i = pop();
-		a->setActorWalkSpeed(i, j);
-		break;
-	case 78:		// SO_SOUND
-		k = getStackList(args, ARRAYSIZE(args));
-		for (i = 0; i < k; i++)
-			a->_sound[i] = args[i];
-		break;
-	case 79:		// SO_WALK_ANIMATION
-		a->_walkFrame = pop();
-		break;
-	case 80:		// SO_TALK_ANIMATION
-		a->_talkStopFrame = pop();
-		a->_talkStartFrame = pop();
-		break;
-	case 81:		// SO_STAND_ANIMATION
-		a->_standFrame = pop();
-		break;
-	case 82:		// SO_ANIMATION
-		// dummy case in scumm6
-		pop();
-		pop();
-		pop();
-		break;
-	case 83:		// SO_DEFAULT
-		a->initActor(0);
-		break;
-	case 84:		// SO_ELEVATION
-		a->setElevation(pop());
-		break;
-	case 85:		// SO_ANIMATION_DEFAULT
-		a->_initFrame = 1;
-		a->_walkFrame = 2;
-		a->_standFrame = 3;
-		a->_talkStartFrame = 4;
-		a->_talkStopFrame = 5;
-		break;
-	case 86:		// SO_PALETTE
-		j = pop();
-		i = pop();
-		checkRange(255, 0, i, "Illegal palette slot %d");
-		a->remapActorPaletteColor(i, j);
-		a->_needRedraw = true;
-		break;
-	case 87:		// SO_TALK_COLOR
-		a->_talkColor = pop();
-		break;
-	case 88:		// SO_ACTOR_NAME
-		loadPtrToResource(rtActorName, a->_number, NULL);
-		break;
-	case 89:		// SO_INIT_ANIMATION
-		a->_initFrame = pop();
-		break;
-	case 91:		// SO_ACTOR_WIDTH
-		a->_width = pop();
-		break;
-	case 92:		// SO_SCALE
-		i = pop();
-		a->setScale(i, i);
-		break;
-	case 93:		// SO_NEVER_ZCLIP
-		a->_forceClip = 0;
-		break;
-	case 94:		// SO_ALWAYS_ZCLIP
-		a->_forceClip = pop();
-		break;
-	case 95:		// SO_IGNORE_BOXES
-		a->_ignoreBoxes = 1;
-		a->_forceClip = 0;
-		if (a->isInCurrentRoom())
-			a->putActor(a->_pos.x, a->_pos.y, a->_room);
-		break;
-	case 96:		// SO_FOLLOW_BOXES
-		a->_ignoreBoxes = 0;
-		a->_forceClip = 0;
-		if (a->isInCurrentRoom())
-			a->putActor(a->_pos.x, a->_pos.y, a->_room);
-		break;
-	case 97:		// SO_ANIMATION_SPEED
-		a->setAnimSpeed(pop());
-		break;
-	case 98:		// SO_SHADOW
-		a->_shadowMode = pop();
-		a->_needRedraw = true;
-		break;
-	case 99:		// SO_TEXT_OFFSET
-		a->_talkPosY = pop();
-		a->_talkPosX = pop();
-		break;
-	case 156:		// HE 7.2
-		a->_charset = pop();
-		break;
-	case 198:		// SO_ACTOR_VARIABLE
-		i = pop();
-		a->setAnimVar(pop(), i);
-		break;
-	case 215:		// SO_ACTOR_IGNORE_TURNS_ON
-		a->_ignoreTurns = true;
-		break;
-	case 216:		// SO_ACTOR_IGNORE_TURNS_OFF
-		a->_ignoreTurns = false;
-		break;
-	case 217:		// SO_ACTOR_NEW
-		a->initActor(2);
-		break;
-	case 218:
-		a->drawActorToBackBuf(a->_pos.x, a->_pos.y);
-		break;
-	case 219:
-		a->_drawToBackBuf = false;
-		a->_needRedraw = true;
-		a->_needBgReset = true;
-		break;
-	case 225:
-		{
-		byte string[128];
-		copyScriptString(string);
-		int slot = pop();
-
-		int len = resStrLen(string) + 1;
-		convertMessageToString(string, a->_heTalkQueue[slot].sentence, len);
-
-		a->_heTalkQueue[slot].posX = a->_talkPosX;
-		a->_heTalkQueue[slot].posY = a->_talkPosY;
-		a->_heTalkQueue[slot].color = a->_talkColor;
-		break;
-		}
-	default:
-		error("o60_actorOps: default case %d", subOp);
-	}
-}
-
-void ScummEngine_v60he::o60_kernelSetFunctions() {
-	int args[29];
-	int num;
-
-	num = getStackList(args, ARRAYSIZE(args));
-
-	switch (args[0]) {
-	case 1:
-		// Used to restore images when decorating cake in
-		// Fatty Bear's Birthday Surprise
-		virtScreenLoad(args[1], args[2], args[3], args[4], args[5]);
-		break;
-	case 3:
-	case 4:
-	case 5:
-	case 6:
-	case 8:
-		//Used before mini games in 3DO versions, seems safe to ignore.
-		break;
-	default:
-		error("o60_kernelSetFunctions: default case %d (param count %d)", args[0], num);
-	}
-}
-
-void ScummEngine_v60he::virtScreenLoad(int resIdx, int x1, int y1, int x2, int y2) {
-	vsUnpackCtx ctx;
-	memset(&ctx, 0, sizeof(ctx));
-	VirtScreen &vs = virtscr[kMainVirtScreen];
-
-	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, resIdx);
-	virtScreenLoadUnpack(&ctx, ah->data);
-	for (int j = y1; j <= y2; ++j) {
-		uint8 *p1 = vs.getPixels(x1, j - vs.topline);
-		uint8 *p2 = vs.getBackPixels(x1, j - vs.topline);
-		if (x2 >= x1) {
-			uint32 w = x2 - x1 + 1;
-			while (w--) {
-				uint8 decByte = virtScreenLoadUnpack(&ctx, 0);
-				*p1++ = decByte;
-				*p2++ = decByte;
-			}
-		}
-	}
-	markRectAsDirty(kMainVirtScreen, x1, x2, y1, y2 + 1, USAGE_BIT_RESTORED);
-}
-
-uint8 virtScreenLoadUnpack(vsUnpackCtx *ctx, byte *data) {
-	uint8 decByte;
-	if (data != 0) {
-		ctx->type = 0;
-		ctx->ptr = data;
-		decByte = 0;
-	} else {
-		uint8 a;
-		if (ctx->type == 0) {
-			a = *(ctx->ptr)++;
-			if (a & 1) {
-				ctx->type = 1;
-				ctx->b = *(ctx->ptr)++;
-			} else {
-				ctx->type = 2;
-			}
-			ctx->size = a;
-			a = (a >> 1) + 1;
-		} else {
- 			a = ctx->size;
-		}
-  		if (ctx->type == 2) {
-  			ctx->b = *(ctx->ptr)++;
-  		}
-  		ctx->size = a - 1;
-  		if (ctx->size == 0) {
-  			ctx->type = 0;
-  		}
-  		decByte = ctx->b;
-	}
-	return decByte;
-}
-
-
-void ScummEngine_v60he::o60_kernelGetFunctions() {
-	int args[29];
-	ArrayHeader *ah;
-	getStackList(args, ARRAYSIZE(args));
-
-	switch (args[0]) {
-	case 1:
-		// Used to store images when decorating cake in
-		// Fatty Bear's Birthday Surprise
-		writeVar(0, 0);
-		ah = defineArray(0, kByteArray, 0, virtScreenSave(0, args[1], args[2], args[3], args[4]));
-		virtScreenSave(ah->data, args[1], args[2], args[3], args[4]);
-		push(readVar(0));
-		break;
-	default:
-		error("o60_kernelGetFunctions: default case %d", args[0]);
-	}
-}
-
-int ScummEngine_v60he::virtScreenSave(byte *dst, int x1, int y1, int x2, int y2) {
-	int packedSize = 0;
-	VirtScreen &vs = virtscr[kMainVirtScreen];
-
-	for (int j = y1; j <= y2; ++j) {
-		uint8 *p = vs.getBackPixels(x1, j - vs.topline);
-
-		int size = virtScreenSavePack(dst, p, x2 - x1 + 1, 0);
-		if (dst != 0) {
-			dst += size;
-		}
-		packedSize += size;
-	}
-	return packedSize;
-}
-
-int virtScreenSavePack(byte *dst, byte *src, int len, int unk) {
-	vsPackCtx ctx;
-	memset(&ctx, 0, sizeof(ctx));
-
-	uint8 prevByte, curByte;
-
-	ctx.buf[0] = prevByte = *src++;
-	int flag = 0;
-	int iend = 1;
-	int ibeg = 0;
-
-	for (--len; len != 0; --len, prevByte = curByte) {
-		bool pass = false;
-
-		assert(iend < 0x100);
-		ctx.buf[iend] = curByte = *src++;
-		++iend;
-
-		if (flag == 0) {
-			if (iend > 0x80) {
-				virtScreenSavePackBuf(&ctx, dst, iend - 1);
-				ctx.buf[0] = curByte;
-				iend = 1;
-				ibeg = 0;
-				continue;
-			}
-			if (prevByte != curByte) {
-				ibeg = iend - 1;
-				continue;
-			}
-			if (iend - ibeg < 3) {
-				if (ibeg != 0) {
-					pass = true;
-				} else {
-					flag = 1;
-				}
-			} else {
-				if (ibeg > 0) {
-					virtScreenSavePackBuf(&ctx, dst, ibeg);
-				}
-				flag = 1;
-			}
-		}
-		if (flag == 1 || pass) {
-			if (prevByte != curByte || iend - ibeg > 0x80) {
-				virtScreenSavePackByte(&ctx, dst, iend - ibeg - 1, prevByte);
-				ctx.buf[0] = curByte;
-				iend = 1;
-				ibeg = 0;
-				flag = 0;
-			}
-		}
-	}
-
-	if (flag == 0) {
-		virtScreenSavePackBuf(&ctx, dst, iend);
-	} else if (flag == 1) {
-		virtScreenSavePackByte(&ctx, dst, iend - ibeg, prevByte);
-	}
-	return ctx.size;
-}
-
-void virtScreenSavePackBuf(vsPackCtx *ctx, uint8 *&dst, int len) {
-	if (dst) {
-		*dst++ = (len - 1) * 2;
-	}
-	++ctx->size;
-	if (len > 0) {
-		ctx->size += len;
-		if (dst) {
-			memcpy(dst, ctx->buf, len);
-			dst += len;
-		}
-	}
-}
-
-void virtScreenSavePackByte(vsPackCtx *ctx, uint8 *&dst, int len, uint8 b) {
-	if (dst) {
-		*dst++ = ((len - 1) * 2) | 1;
-	}
-	++ctx->size;
-	if (dst) {
-		*dst++ = b;
-	}
-	++ctx->size;
-}
-
-void ScummEngine_v60he::o60_openFile() {
-	int mode, len, slot, l, r;
-	byte filename[100];
-
-	convertMessageToString(_scriptPointer, filename, sizeof(filename));
-
-	len = resStrLen(_scriptPointer);
-	_scriptPointer += len + 1;
-
-	for (r = strlen((char*)filename); r != 0; r--) {
-		if (filename[r - 1] == '\\')
-			break;
-	}
-
-	mode = pop();
-	slot = -1;
-	for (l = 0; l < 17; l++) {
-		if (_hFileTable[l].isOpen() == false) {
-			slot = l;
-			break;
-		}
-	}
-
-	if (slot != -1) {
-		switch(mode) {
-		case 1:
-			_hFileTable[slot].open((char*)filename + r, Common::File::kFileReadMode, _saveFileMan->getSavePath());
-			if (_hFileTable[slot].isOpen() == false)
-				_hFileTable[slot].open((char*)filename + r, Common::File::kFileReadMode);
-			break;
-		case 2:
-			_hFileTable[slot].open((char*)filename + r, Common::File::kFileWriteMode, _saveFileMan->getSavePath());
-			break;
-		default:
-			error("o60_openFile(): wrong open file mode %d", mode);
-		}
-
-		if (_hFileTable[slot].isOpen() == false)
-			slot = -1;
-
-	}
-	push(slot);
-}
-
-void ScummEngine_v60he::o60_closeFile() {
-	int slot = pop();
-	if (slot != -1)
-		_hFileTable[slot].close();
-}
-
-void ScummEngine_v60he::o60_deleteFile() {
-	int len, r;
-	byte filename[100];
-
-	convertMessageToString(_scriptPointer, filename, sizeof(filename));
-
-	len = resStrLen(_scriptPointer);
-	_scriptPointer += len + 1;
-
-	for (r = strlen((char*)filename); r != 0; r--) {
-		if (filename[r - 1] == '\\')
-			break;
-	}
-
-	debug(1, "stub o60_deleteFile(\"%s\")", filename + r);
-}
-
-void ScummEngine_v60he::o60_rename() {
-	int len, r1, r2;
-	byte filename[100],filename2[100];
-
-	convertMessageToString(_scriptPointer, filename, sizeof(filename));
-
-	len = resStrLen(_scriptPointer);
-	_scriptPointer += len + 1;
-
-	for (r1 = strlen((char*)filename); r1 != 0; r1--) {
-		if (filename[r1 - 1] == '\\')
-			break;
-	}
-
-	convertMessageToString(_scriptPointer, filename2, sizeof(filename2));
-
-	len = resStrLen(_scriptPointer);
-	_scriptPointer += len + 1;
-
-	for (r2 = strlen((char*)filename2); r2 != 0; r2--) {
-		if (filename2[r2 - 1] == '\\')
-			break;
-	}
-
-	debug(1, "stub o60_rename(\"%s\" to \"%s\")", filename + r1, filename2 + r2);
-}
-
-int ScummEngine_v60he::readFileToArray(int slot, int32 size) {
-	if (size == 0)
-		size = _hFileTable[slot].size() - _hFileTable[slot].pos();
-
-	writeVar(0, 0);
-
-	ArrayHeader *ah = defineArray(0, kByteArray, 0, size);
-	_hFileTable[slot].read(ah->data, size);
-
-	return readVar(0);
-}
-
-void ScummEngine_v60he::o60_readFile() {
-	int32 size = pop();
-	int slot = pop();
-	int val;
-
-	// Fatty Bear uses positive values
-	if ((_platform == Common::kPlatformPC) && (_gameId == GID_FBEAR))
-		size = -size;
-
-	if (size == -2) {
-		val = _hFileTable[slot].readUint16LE();
-		push(val);
-	} else if (size == -1) {
-		val = _hFileTable[slot].readByte();
-		push(val);
-	} else {
-		val = readFileToArray(slot, size);
-		push(val);
-	}
-}
-
-void ScummEngine_v60he::writeFileFromArray(int slot, int resID) {
-	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, resID);
-	int32 size = FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2);
-
-	_hFileTable[slot].write(ah->data, size);
-}
-
-void ScummEngine_v60he::o60_writeFile() {
-	int32 size = pop();
-	int16 resID = pop();
-	int slot = pop();
-
-	// Fatty Bear uses positive values
-	if ((_platform == Common::kPlatformPC) && (_gameId == GID_FBEAR))
-		size = -size;
-
-	if (size == -2) {
-		_hFileTable[slot].writeUint16LE(resID);
-	} else if (size == -1) {
-		_hFileTable[slot].writeByte(resID);
-	} else {
-		writeFileFromArray(slot, resID);
-	}
-}
-
-void ScummEngine_v60he::o60_soundOps() {
-	byte subOp = fetchScriptByte();
-	int arg = pop();
-
-	switch (subOp) {
-	case 0xde:
-		_imuse->setMusicVolume(arg);
-		break;
-	case 0xdf:
-		// Used in fbear introduction
-		break;
-	case 0xe0:
-		// Fatty Bear's Birthday surprise uses this when playing the
-		// piano, but only when using one of the digitized instruments.
-		// See also o6_startSound().
-		_sound->setOverrideFreq(arg);
-		break;
-	default:
-		error("o60_soundOps: default case 0x%x", subOp);
-	}
-}
-
-void ScummEngine_v60he::localizeArray(int slot, byte scriptSlot) {
-	if (_heversion >= 80)
-		slot &= ~0x33539000;
-
-	if (slot >= _numArray)
-		error("o60_localizeArrayToScript(%d): array slot out of range", slot);
-
-	_arraySlot[slot] = scriptSlot;
-}
-
-void ScummEngine_v60he::o60_localizeArrayToScript() {
-	int slot = pop();
-	localizeArray(slot, _currentScript);
-}
-
-void ScummEngine_v60he::o60_seekFilePos() {
-	int mode, offset, slot;
-
-	mode = pop();
-	offset = pop();
-	slot = pop();
-
-	if (slot == -1)
-		return;
-
-	switch (mode) {
-	case 1:
-		_hFileTable[slot].seek(offset, SEEK_SET);
-		break;
-	case 2:
-		_hFileTable[slot].seek(offset, SEEK_CUR);
-		break;
-	case 3:
-		_hFileTable[slot].seek(offset, SEEK_END);
-		break;
-	default:
-		error("o60_seekFilePos: default case %d", mode);
-	}
-}
-
-void ScummEngine_v60he::o60_readFilePos() {
-	int slot = pop();
-
-	if (slot == -1) {
-		push(0);
-		return;
-	}
-
-	push(_hFileTable[slot].pos());
-}
-
-void ScummEngine_v60he::o60_redimArray() {
-	int newX, newY;
-	newY = pop();
-	newX = pop();
-
-	if (newY == 0)
-		SWAP(newX, newY);
-
-	byte subOp = fetchScriptByte();
-	switch (subOp) {
-	case 199:
-		redimArray(fetchScriptWord(), newX, newY, kIntArray);
-		break;
-	case 202:
-		redimArray(fetchScriptWord(), newX, newY, kByteArray);
-		break;
-	default:
-		error("o60_redimArray: default type %d", subOp);
-	}
-}
-
-void ScummEngine_v60he::redimArray(int arrayId, int newX, int newY, int type) {
-	// Used in mini game at Cosmic Dust Diner in puttmoon
-	int newSize, oldSize;
-
-	if (readVar(arrayId) == 0)
-		error("redimArray: Reference to zeroed array pointer");
-
-	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(arrayId));
-
-	if (!ah)
-		error("redimArray: Invalid array (%d) reference", readVar(arrayId));
-
-	newSize = (type == kIntArray) ? 2 : 1;
-	oldSize = (ah->type == kIntArray) ? 2 : 1;
-
-	newSize *= (newX + 1) * (newY + 1);
-	oldSize *= FROM_LE_16(ah->dim1) * FROM_LE_16(ah->dim2);
-
-	if (newSize != oldSize)
-		error("redimArray: array %d redim mismatch", readVar(arrayId));
-
-	ah->type = TO_LE_16(type);
-	ah->dim1 = TO_LE_16(newY + 1);
-	ah->dim2 = TO_LE_16(newX + 1);
-}
-
-void ScummEngine_v60he::decodeParseString(int m, int n) {
-	int i, colors;
-	int args[31];
-
-	byte b = fetchScriptByte();
-
-	switch (b) {
-	case 65:		// SO_AT
-		_string[m].ypos = pop();
-		_string[m].xpos = pop();
-		_string[m].overhead = false;
-		break;
-	case 66:		// SO_COLOR
-		_string[m].color = pop();
-		break;
-	case 67:		// SO_CLIPPED
-		_string[m].right = pop();
-		break;
-	case 69:		// SO_CENTER
-		_string[m].center = true;
-		_string[m].overhead = false;
-		break;
-	case 71:		// SO_LEFT
-		_string[m].center = false;
-		_string[m].overhead = false;
-		break;
-	case 72:		// SO_OVERHEAD
-		_string[m].overhead = true;
-		_string[m].no_talk_anim = false;
-		break;
-	case 74:		// SO_MUMBLE
-		_string[m].no_talk_anim = true;
-		break;
-	case 75:		// SO_TEXTSTRING
-		printString(m, _scriptPointer);
-		_scriptPointer += resStrLen(_scriptPointer) + 1;
-		break;
-	case 0xF9:
-		colors = pop();
-		if (colors == 1) {
-			_string[m].color = pop();
-		} else {
-			push(colors);
-			getStackList(args, ARRAYSIZE(args));
-			for (i = 0; i < 16; i++)
-				_charsetColorMap[i] = _charsetData[_string[1]._default.charset][i] = (unsigned char)args[i];
-			_string[m].color = _charsetColorMap[0];
-		}
-		break;
-	case 0xFE:
-		_string[m].loadDefault();
-		if (n)
-			_actorToPrintStrFor = pop();
-		break;
-	case 0xFF:
-		_string[m].saveDefault();
-		break;
-	default:
-		error("decodeParseString: default case 0x%x", b);
-	}
-}
-
-} // End of namespace Scumm

Copied: scummvm/trunk/engines/scumm/he/script_v70he.cpp (from rev 20696, scummvm/trunk/engines/scumm/he/script_v7he.cpp)
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v70he.cpp	                        (rev 0)
+++ scummvm/trunk/engines/scumm/he/script_v70he.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -0,0 +1,1153 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001  Ludvig Strigeus
+ * 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 "common/config-manager.h"
+#include "common/system.h"
+
+#include "scumm/actor.h"
+#include "scumm/charset.h"
+#include "scumm/he/intern_he.h"
+#include "scumm/object.h"
+#include "scumm/resource.h"
+#include "scumm/he/resource_he.h"
+#include "scumm/scumm.h"
+#include "scumm/sound.h"
+#include "scumm/verbs.h"
+
+namespace Scumm {
+
+#define OPCODE(x)	_OPCODE(ScummEngine_v70he, x)
+
+void ScummEngine_v70he::setupOpcodes() {
+	static const OpcodeEntryv70he opcodes[256] = {
+		/* 00 */
+		OPCODE(o6_pushByte),
+		OPCODE(o6_pushWord),
+		OPCODE(o6_pushByteVar),
+		OPCODE(o6_pushWordVar),
+		/* 04 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayRead),
+		OPCODE(o6_wordArrayRead),
+		/* 08 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayIndexedRead),
+		OPCODE(o6_wordArrayIndexedRead),
+		/* 0C */
+		OPCODE(o6_dup),
+		OPCODE(o6_not),
+		OPCODE(o6_eq),
+		OPCODE(o6_neq),
+		/* 10 */
+		OPCODE(o6_gt),
+		OPCODE(o6_lt),
+		OPCODE(o6_le),
+		OPCODE(o6_ge),
+		/* 14 */
+		OPCODE(o6_add),
+		OPCODE(o6_sub),
+		OPCODE(o6_mul),
+		OPCODE(o6_div),
+		/* 18 */
+		OPCODE(o6_land),
+		OPCODE(o6_lor),
+		OPCODE(o6_pop),
+		OPCODE(o6_invalid),
+		/* 1C */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 20 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 24 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 28 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 2C */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 30 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 34 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 38 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 3C */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* 40 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_writeByteVar),
+		OPCODE(o6_writeWordVar),
+		/* 44 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayWrite),
+		OPCODE(o6_wordArrayWrite),
+		/* 48 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayIndexedWrite),
+		OPCODE(o6_wordArrayIndexedWrite),
+		/* 4C */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteVarInc),
+		OPCODE(o6_wordVarInc),
+		/* 50 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayInc),
+		OPCODE(o6_wordArrayInc),
+		/* 54 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteVarDec),
+		OPCODE(o6_wordVarDec),
+		/* 58 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_byteArrayDec),
+		OPCODE(o6_wordArrayDec),
+		/* 5C */
+		OPCODE(o6_if),
+		OPCODE(o6_ifNot),
+		OPCODE(o6_startScript),
+		OPCODE(o6_startScriptQuick),
+		/* 60 */
+		OPCODE(o6_startObject),
+		OPCODE(o6_drawObject),
+		OPCODE(o6_drawObjectAt),
+		OPCODE(o6_invalid),
+		/* 64 */
+		OPCODE(o6_invalid),
+		OPCODE(o6_stopObjectCode),
+		OPCODE(o6_stopObjectCode),
+		OPCODE(o6_endCutscene),
+		/* 68 */
+		OPCODE(o6_cutscene),
+		OPCODE(o6_stopMusic),
+		OPCODE(o6_freezeUnfreeze),
+		OPCODE(o6_cursorCommand),
+		/* 6C */
+		OPCODE(o6_breakHere),
+		OPCODE(o6_ifClassOfIs),
+		OPCODE(o6_setClass),
+		OPCODE(o6_getState),
+		/* 70 */
+		OPCODE(o60_setState),
+		OPCODE(o6_setOwner),
+		OPCODE(o6_getOwner),
+		OPCODE(o6_jump),
+		/* 74 */
+		OPCODE(o70_startSound),
+		OPCODE(o6_stopSound),
+		OPCODE(o6_startMusic),
+		OPCODE(o6_stopObjectScript),
+		/* 78 */
+		OPCODE(o6_panCameraTo),
+		OPCODE(o6_actorFollowCamera),
+		OPCODE(o6_setCameraAt),
+		OPCODE(o6_loadRoom),
+		/* 7C */
+		OPCODE(o6_stopScript),
+		OPCODE(o6_walkActorToObj),
+		OPCODE(o6_walkActorTo),
+		OPCODE(o6_putActorAtXY),
+		/* 80 */
+		OPCODE(o6_putActorAtObject),
+		OPCODE(o6_faceActor),
+		OPCODE(o6_animateActor),
+		OPCODE(o6_doSentence),
+		/* 84 */
+		OPCODE(o70_pickupObject),
+		OPCODE(o6_loadRoomWithEgo),
+		OPCODE(o6_invalid),
+		OPCODE(o6_getRandomNumber),
+		/* 88 */
+		OPCODE(o6_getRandomNumberRange),
+		OPCODE(o6_invalid),
+		OPCODE(o6_getActorMoving),
+		OPCODE(o6_isScriptRunning),
+		/* 8C */
+		OPCODE(o70_getActorRoom),
+		OPCODE(o6_getObjectX),
+		OPCODE(o6_getObjectY),
+		OPCODE(o6_getObjectOldDir),
+		/* 90 */
+		OPCODE(o6_getActorWalkBox),
+		OPCODE(o6_getActorCostume),
+		OPCODE(o6_findInventory),
+		OPCODE(o6_getInventoryCount),
+		/* 94 */
+		OPCODE(o6_getVerbFromXY),
+		OPCODE(o6_beginOverride),
+		OPCODE(o6_endOverride),
+		OPCODE(o6_setObjectName),
+		/* 98 */
+		OPCODE(o6_isSoundRunning),
+		OPCODE(o6_setBoxFlags),
+		OPCODE(o6_invalid),
+		OPCODE(o70_resourceRoutines),
+		/* 9C */
+		OPCODE(o60_roomOps),
+		OPCODE(o60_actorOps),
+		OPCODE(o6_verbOps),
+		OPCODE(o6_getActorFromXY),
+		/* A0 */
+		OPCODE(o6_findObject),
+		OPCODE(o6_pseudoRoom),
+		OPCODE(o6_getActorElevation),
+		OPCODE(o6_getVerbEntrypoint),
+		/* A4 */
+		OPCODE(o6_arrayOps),
+		OPCODE(o6_saveRestoreVerbs),
+		OPCODE(o6_drawBox),
+		OPCODE(o6_pop),
+		/* A8 */
+		OPCODE(o6_getActorWidth),
+		OPCODE(o6_wait),
+		OPCODE(o6_getActorScaleX),
+		OPCODE(o6_getActorAnimCounter1),
+		/* AC */
+		OPCODE(o6_invalid),
+		OPCODE(o6_isAnyOf),
+		OPCODE(o70_systemOps),
+		OPCODE(o6_isActorInBox),
+		/* B0 */
+		OPCODE(o6_delay),
+		OPCODE(o6_delaySeconds),
+		OPCODE(o6_delayMinutes),
+		OPCODE(o6_stopSentence),
+		/* B4 */
+		OPCODE(o6_printLine),
+		OPCODE(o6_printText),
+		OPCODE(o6_printDebug),
+		OPCODE(o6_printSystem),
+		/* B8 */
+		OPCODE(o6_printActor),
+		OPCODE(o6_printEgo),
+		OPCODE(o6_talkActor),
+		OPCODE(o6_talkEgo),
+		/* BC */
+		OPCODE(o6_dimArray),
+		OPCODE(o6_stopObjectCode),
+		OPCODE(o6_startObjectQuick),
+		OPCODE(o6_startScriptQuick2),
+		/* C0 */
+		OPCODE(o6_dim2dimArray),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* C4 */
+		OPCODE(o6_abs),
+		OPCODE(o6_distObjectObject),
+		OPCODE(o6_distObjectPt),
+		OPCODE(o6_distPtPt),
+		/* C8 */
+		OPCODE(o60_kernelGetFunctions),
+		OPCODE(o70_kernelSetFunctions),
+		OPCODE(o6_delayFrames),
+		OPCODE(o6_pickOneOf),
+		/* CC */
+		OPCODE(o6_pickOneOfDefault),
+		OPCODE(o6_stampObject),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* D0 */
+		OPCODE(o6_getDateTime),
+		OPCODE(o6_stopTalking),
+		OPCODE(o6_getAnimateVariable),
+		OPCODE(o6_invalid),
+		/* D4 */
+		OPCODE(o6_shuffle),
+		OPCODE(o6_jumpToScript),
+		OPCODE(o6_band),
+		OPCODE(o6_bor),
+		/* D8 */
+		OPCODE(o6_isRoomScriptRunning),
+		OPCODE(o60_closeFile),
+		OPCODE(o60_openFile),
+		OPCODE(o60_readFile),
+		/* DC */
+		OPCODE(o60_writeFile),
+		OPCODE(o6_findAllObjects),
+		OPCODE(o60_deleteFile),
+		OPCODE(o60_rename),
+		/* E0 */
+		OPCODE(o60_soundOps),
+		OPCODE(o6_getPixel),
+		OPCODE(o60_localizeArrayToScript),
+		OPCODE(o6_pickVarRandom),
+		/* E4 */
+		OPCODE(o6_setBoxSet),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		/* E8 */
+		OPCODE(o6_invalid),
+		OPCODE(o70_seekFilePos),
+		OPCODE(o60_redimArray),
+		OPCODE(o60_readFilePos),
+		/* EC */
+		OPCODE(o70_copyString),
+		OPCODE(o70_getStringWidth),
+		OPCODE(o70_getStringLen),
+		OPCODE(o70_appendString),
+		/* F0 */
+		OPCODE(o70_concatString),
+		OPCODE(o70_compareString),
+		OPCODE(o70_isResourceLoaded),
+		OPCODE(o70_readINI),
+		/* F4 */
+		OPCODE(o70_writeINI),
+		OPCODE(o70_getStringLenForWidth),
+		OPCODE(o70_getCharIndexInString),
+		OPCODE(o6_invalid),
+		/* F8 */
+		OPCODE(o6_invalid),
+		OPCODE(o70_setFilePath),
+		OPCODE(o70_setSystemMessage),
+		OPCODE(o70_polygonOps),
+		/* FC */
+		OPCODE(o70_polygonHit),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+		OPCODE(o6_invalid),
+	};
+
+	_opcodesv70he = opcodes;
+}
+
+void ScummEngine_v70he::executeOpcode(byte i) {
+	OpcodeProcv70he op = _opcodesv70he[i].proc;
+	(this->*op) ();
+}
+
+const char *ScummEngine_v70he::getOpcodeDesc(byte i) {
+	return _opcodesv70he[i].desc;
+}
+
+int ScummEngine_v70he::getStringCharWidth(byte chr) {
+	int charset = _string[0]._default.charset;
+
+	byte *ptr = getResourceAddress(rtCharset, charset);
+	assert(ptr);
+	ptr += 29;
+
+	int spacing = 0;
+
+	int offs = READ_LE_UINT32(ptr + chr * 4 + 4);
+	if (offs) {
+		spacing = ptr[offs] + (signed char)ptr[offs + 2];
+	}
+
+	return spacing;
+}
+
+int ScummEngine_v70he::setupStringArray(int size) {
+	writeVar(0, 0);
+	defineArray(0, kStringArray, 0, size + 1);
+	writeArray(0, 0, 0, 0);
+	return readVar(0);
+}
+
+void ScummEngine_v70he::appendSubstring(int dst, int src, int srcOffs, int len) {
+	int dstOffs, value;
+	int i = 0;
+
+	if (len == -1) {
+		len = resStrLen(getStringAddress(src));
+		srcOffs = 0;
+	}
+
+	dstOffs = resStrLen(getStringAddress(dst));
+
+	len -= srcOffs;
+	len++;
+
+	while (i < len) {
+		writeVar(0, src);
+		value = readArray(0, 0, srcOffs + i);
+		writeVar(0, dst);
+		writeArray(0, 0, dstOffs + i, value);
+		i++;
+	}
+
+	writeArray(0, 0, dstOffs + i, 0);
+}
+
+void ScummEngine_v70he::o70_startSound() {
+	int var, value;
+
+	byte subOp = fetchScriptByte();
+
+	switch (subOp) {
+	case 9:
+		_heSndFlags |= 4;
+		break;
+	case 23:
+		value = pop();
+		var = pop();
+		_heSndSoundId = pop();
+		_sound->setSoundVar(_heSndSoundId, var, value);
+		break;
+	case 25:
+		value = pop();
+		_heSndSoundId = pop();
+		_sound->addSoundToQueue(_heSndSoundId, 0, 0, 8);
+	case 56:
+		_heSndFlags |= 16;
+		break;
+	case 164:
+		_heSndFlags |= 2;
+		break;
+	case 224:
+		_heSndSoundFreq = pop();
+		break;
+	case 230:
+		_heSndChannel = pop();
+		break;
+	case 231:
+		_heSndOffset = pop();
+		break;
+	case 232:
+		_heSndSoundId = pop();
+		_heSndOffset = 0;
+		_heSndSoundFreq = 11025;
+		_heSndChannel = VAR(VAR_SOUND_CHANNEL);
+		break;
+	case 245:
+		_heSndFlags |= 1;
+		break;
+	case 255:
+		_sound->addSoundToQueue(_heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags);
+		_heSndFlags = 0;
+		break;
+
+	default:
+		error("o70_startSound invalid case %d", subOp);
+	}
+}
+
+void ScummEngine_v70he::o70_pickupObject() {
+	int obj, room;
+
+	room = pop();
+	obj = pop();
+	if (room == 0)
+		room = getObjectRoom(obj);
+
+	addObjectToInventory(obj, room);
+	putOwner(obj, VAR(VAR_EGO));
+	if (_heversion <= 70) {
+		putClass(obj, kObjectClassUntouchable, 1);
+		putState(obj, 1);
+		markObjectRectAsDirty(obj);
+		clearDrawObjectQueue();
+	}
+	runInventoryScript(obj);									/* Difference */
+}
+
+void ScummEngine_v70he::o70_getActorRoom() {
+	int act = pop();
+
+	if (act < _numActors) {
+		Actor *a = derefActor(act, "o70_getActorRoom");
+		push(a->_room);
+	} else
+		push(getObjectRoom(act));
+}
+
+void ScummEngine_v70he::o70_resourceRoutines() {
+	int objidx, resid;
+
+	byte subOp = fetchScriptByte();
+
+	switch (subOp) {
+	case 100:		// SO_LOAD_SCRIPT
+		resid = pop();
+		ensureResourceLoaded(rtScript, resid);
+		break;
+	case 101:		// SO_LOAD_SOUND
+		resid = pop();
+		ensureResourceLoaded(rtSound, resid);
+		break;
+	case 102:		// SO_LOAD_COSTUME
+		resid = pop();
+		ensureResourceLoaded(rtCostume, resid);
+		break;
+	case 103:		// SO_LOAD_ROOM
+		resid = pop();
+		ensureResourceLoaded(rtRoomImage, resid);
+		ensureResourceLoaded(rtRoom, resid);
+		break;
+	case 104:		// SO_NUKE_SCRIPT
+		resid = pop();
+		res.nukeResource(rtScript, resid);
+		break;
+	case 105:		// SO_NUKE_SOUND
+		resid = pop();
+		res.nukeResource(rtSound, resid);
+		break;
+	case 106:		// SO_NUKE_COSTUME
+		resid = pop();
+		res.nukeResource(rtCostume, resid);
+		break;
+	case 107:		// SO_NUKE_ROOM
+		resid = pop();
+		res.nukeResource(rtRoom, resid);
+		res.nukeResource(rtRoomImage, resid);
+		break;
+	case 108:		// SO_LOCK_SCRIPT
+		resid = pop();
+		if (resid >= _numGlobalScripts)
+			break;
+		res.lock(rtScript, resid);
+		break;
+	case 109:		// SO_LOCK_SOUND
+		resid = pop();
+		res.lock(rtSound, resid);
+		break;
+	case 110:		// SO_LOCK_COSTUME
+		resid = pop();
+		res.lock(rtCostume, resid);
+		break;
+	case 111:		// SO_LOCK_ROOM
+		resid = pop();
+		if (_heversion <= 71 && resid > 0x7F)
+			resid = _resourceMapper[resid & 0x7F];
+		res.lock(rtRoom, resid);
+		res.lock(rtRoomImage, resid);
+		break;
+	case 112:		// SO_UNLOCK_SCRIPT
+		resid = pop();
+		if (resid >= _numGlobalScripts)
+			break;
+		res.unlock(rtScript, resid);
+		break;
+	case 113:		// SO_UNLOCK_SOUND
+		resid = pop();
+		res.unlock(rtSound, resid);
+		break;
+	case 114:		// SO_UNLOCK_COSTUME
+		resid = pop();
+		res.unlock(rtCostume, resid);
+		break;
+	case 115:		// SO_UNLOCK_ROOM
+		resid = pop();
+		if (_heversion <= 71 && resid > 0x7F)
+			resid = _resourceMapper[resid & 0x7F];
+		res.unlock(rtRoom, resid);
+		res.unlock(rtRoomImage, resid);
+		break;
+	case 116:
+		break;
+	case 117:		// SO_LOAD_CHARSET
+		resid = pop();
+		loadCharset(resid);
+		break;
+	case 118:		// SO_NUKE_CHARSET
+		resid = pop();
+		nukeCharset(resid);
+		break;
+	case 119:		// SO_LOAD_OBJECT
+		{
+			int obj = pop();
+			int room = getObjectRoom(obj);
+			loadFlObject(obj, room);
+			break;
+		}
+	case 120:
+		resid = pop();
+		if (resid >= _numGlobalScripts)
+			break;
+		//queueLoadResource(rtScript, resid);
+		break;
+	case 121:
+		resid = pop();
+		//queueLoadResource(rtSound, resid);
+		break;
+	case 122:
+		resid = pop();
+		//queueLoadResource(rtCostume, resid);
+		break;
+	case 123:
+		resid = pop();
+		//queueLoadResource(rtRoomImage, resid);
+		break;
+	case 159:
+		resid = pop();
+		res.unlock(rtImage, resid);
+		break;
+	case 192:
+		resid = pop();
+		res.nukeResource(rtImage, resid);
+		break;
+	case 201:
+		resid = pop();
+		ensureResourceLoaded(rtImage, resid);
+		break;
+	case 202:
+		resid = pop();
+		res.lock(rtImage, resid);
+		break;
+	case 203:
+		resid = pop();
+		//queueLoadResource(rtImage, resid);
+		break;
+	case 233:
+		resid = pop();
+		objidx = getObjectIndex(resid);
+		if (objidx == -1)
+			break;
+		res.lock(rtFlObject, _objs[objidx].fl_object_index);
+		break;
+	case 235:
+		resid = pop();
+		objidx = getObjectIndex(resid);
+		if (objidx == -1)
+			break;
+		res.unlock(rtFlObject, _objs[objidx].fl_object_index);
+		break;
+	case 239:
+		// Used in airport
+		break;
+	default:
+		error("o70_resourceRoutines: default case %d", subOp);
+	}
+}
+
+void ScummEngine_v70he::o70_systemOps() {
+	byte *src, string[256];
+	int id, len;
+
+	byte subOp = fetchScriptByte();
+
+	switch (subOp) {
+	case 158:
+		restart();
+		break;
+	case 160:
+		// Confirm shutdown
+		shutDown();
+		break;
+	case 244:
+		shutDown();
+		break;
+	case 250:
+		id = pop();
+		src = getStringAddress(id);
+		len = resStrLen(src) + 1;
+		memcpy(string, src, len);
+		debug(0, "Start executable (%s)", string);
+		break;
+	case 251:
+		convertMessageToString(_scriptPointer, string, sizeof(string));
+		len = resStrLen(_scriptPointer);
+		_scriptPointer += len + 1;
+		debug(0, "Start executable (%s)", string);
+		break;
+	case 252:
+		convertMessageToString(_scriptPointer, string, sizeof(string));
+		len = resStrLen(_scriptPointer);
+		_scriptPointer += len + 1;
+		debug(0, "Start game (%s)", string);
+		break;
+	case 253:
+		id = pop();
+		src = getStringAddress(id);
+		len = resStrLen(src) + 1;
+		memcpy(string, src, len);
+		debug(0, "Start game (%s)", string);
+		break;
+	default:
+		error("o70_systemOps invalid case %d", subOp);
+	}
+}
+
+void ScummEngine_v70he::o70_seekFilePos() {
+	int mode, offset, slot;
+	mode = pop();
+	offset = pop();
+	slot = pop();
+
+	if (slot == -1)
+		return;
+
+	switch (mode) {
+	case 1:
+		_hFileTable[slot].seek(offset, SEEK_SET);
+		break;
+	case 2:
+		_hFileTable[slot].seek(offset, SEEK_CUR);
+		break;
+	case 3:
+		_hFileTable[slot].seek(offset, SEEK_END);
+		break;
+	default:
+		error("o70_seekFilePos: default case 0x%x", mode);
+	}
+}
+
+void ScummEngine_v70he::o70_copyString() {
+	int dst, size;
+	int src = pop();
+
+	size = resStrLen(getStringAddress(src)) + 1;
+	dst = setupStringArray(size);
+
+	appendSubstring(dst, src, -1, -1);
+
+	push(dst);
+}
+
+void ScummEngine_v70he::o70_getStringWidth() {
+	int array, pos, len;
+	int chr, width = 0;
+
+	len = pop();
+	pos = pop();
+	array = pop();
+
+	if (len == -1) {
+		pos = 0;
+		len = resStrLen(getStringAddress(array));
+	}
+
+	writeVar(0, array);
+	while (pos <= len) {
+		chr = readArray(0, 0, pos);
+		if (chr == 0)
+			break;
+		width += getStringCharWidth(chr);
+		pos++;
+	}
+
+	push(width);
+}
+
+void ScummEngine_v70he::o70_kernelSetFunctions() {
+	int args[29];
+	int num;
+	Actor *a;
+
+	num = getStackList(args, ARRAYSIZE(args));
+
+	switch (args[0]) {
+	case 1:
+		// Used to restore images when decorating cake in
+		// Fatty Bear's Birthday Surprise
+		virtScreenLoad(args[1], args[2], args[3], args[4], args[5]);
+		break;
+	case 20: // HE72+
+		a = derefActor(args[1], "o70_kernelSetFunctions: 20");
+		((ScummEngine_v71he *)this)->queueAuxBlock(a);
+		break;
+	case 21:
+		_skipDrawObject = 1;
+		break;
+	case 22:
+		_skipDrawObject = 0;
+		break;
+	case 23:
+		_charset->clearCharsetMask();
+		_fullRedraw = true;
+		break;
+	case 24:
+		_skipProcessActors = 1;
+		redrawAllActors();
+		break;
+	case 25:
+		_skipProcessActors = 0;
+		redrawAllActors();
+		break;
+	case 26:
+		a = derefActor(args[1], "o70_kernelSetFunctions: 26");
+		a->_auxBlock.r.left = 0;
+		a->_auxBlock.r.right = -1;
+		a->_auxBlock.r.top = 0;
+		a->_auxBlock.r.bottom = -2;
+		break;
+	case 30:
+		a = derefActor(args[1], "o70_kernelSetFunctions: 30");
+		a->_clipOverride.bottom = args[2];
+		break;
+	case 42:
+		_wiz->_rectOverrideEnabled = true;
+		_wiz->_rectOverride.left = args[1];
+		_wiz->_rectOverride.top = args[2];
+		_wiz->_rectOverride.right = args[3];
+		_wiz->_rectOverride.bottom = args[4];
+		break;
+	case 43:
+		_wiz->_rectOverrideEnabled = false;
+		break;
+	default:
+		error("o70_kernelSetFunctions: default case %d (param count %d)", args[0], num);
+	}
+}
+
+void ScummEngine_v70he::o70_getStringLen() {
+	int id, len;
+	byte *addr;
+
+	id = pop();
+
+	addr = getStringAddress(id);
+	if (!addr)
+		error("o70_getStringLen: Reference to zeroed array pointer (%d)", id);
+
+	len = resStrLen(getStringAddress(id));
+	push(len);
+}
+
+void ScummEngine_v70he::o70_appendString() {
+	int dst, size;
+
+	int len = pop();
+	int srcOffs = pop();
+	int src = pop();
+
+	size = len - srcOffs + 2;
+	dst = setupStringArray(size);
+
+	appendSubstring(dst, src, srcOffs, len);
+
+	push(dst);
+}
+
+void ScummEngine_v70he::o70_concatString() {
+	int dst, size;
+
+	int src2 = pop();
+	int src1 = pop();
+
+	size = resStrLen(getStringAddress(src1));
+	size += resStrLen(getStringAddress(src2)) + 1;
+	dst = setupStringArray(size);
+
+	appendSubstring(dst, src1, 0, -1);
+	appendSubstring(dst, src2, 0, -1);
+
+	push(dst);
+}
+
+void ScummEngine_v70he::o70_compareString() {
+	int result;
+
+	int array1 = pop();
+	int array2 = pop();
+
+	byte *string1 = getStringAddress(array1);
+	if (!string1)
+		error("o70_compareString: Reference to zeroed array pointer (%d)", array1);
+
+	byte *string2 = getStringAddress(array2);
+	if (!string2)
+		error("o70_compareString: Reference to zeroed array pointer (%d)", array2);
+
+	while (*string1 == *string2) {
+		if (*string2 == 0) {
+			push(0);
+			return;
+		}
+
+		string1++;
+		string2++;
+	}
+
+	result = (*string1 > *string2) ? -1 : 1;
+	push(result);
+}
+
+void ScummEngine_v70he::o70_isResourceLoaded() {
+	// Reports percentage of resource loaded by queue
+	int type;
+
+	byte subOp = fetchScriptByte();
+	/* int idx = */ pop();
+
+	switch (subOp) {
+	case 18:
+		type = rtImage;
+		break;
+	case 226:
+		type = rtRoom;
+		break;
+	case 227:
+		type = rtCostume;
+		break;
+	case 228:
+		type = rtSound;
+		break;
+	case 229:
+		type = rtScript;
+		break;
+	default:
+		error("o70_isResourceLoaded: default case %d", subOp);
+	}
+
+	push(100);
+}
+
+void ScummEngine_v70he::o70_readINI() {
+	byte option[256];
+	ArrayHeader *ah;
+	const char *entry;
+	int len, type;
+
+	convertMessageToString(_scriptPointer, option, sizeof(option));
+	len = resStrLen(_scriptPointer);
+	_scriptPointer += len + 1;
+
+	type = pop();
+	switch (type) {
+	case 1: // number
+		if (!strcmp((char *)option, "NoPrinting")) {
+			push(1);
+		} else if (!strcmp((char *)option, "TextOn")) {
+			push(ConfMan.getBool("subtitles"));
+		} else {
+			push(ConfMan.getInt((char *)option));
+		}
+		break;
+	case 2: // string
+		entry = (ConfMan.get((char *)option).c_str());
+
+		writeVar(0, 0);
+		len = resStrLen((const byte *)entry);
+		ah = defineArray(0, kStringArray, 0, len);
+		memcpy(ah->data, entry, len);
+
+		push(readVar(0));
+		break;
+	default:
+		error("o70_readINI: default type %d", type);
+	}
+	debug(1, "o70_readINI: Option %s", option);
+}
+
+void ScummEngine_v70he::o70_writeINI() {
+	int type, value;
+	byte option[256], string[256];
+	int len;
+
+	type = pop();
+	value = pop();
+
+	convertMessageToString(_scriptPointer, option, sizeof(option));
+	len = resStrLen(_scriptPointer);
+	_scriptPointer += len + 1;
+
+	switch (type) {
+	case 1: // number
+		ConfMan.set((char *)option, value);
+		debug(1, "o70_writeINI: Option %s Value %d", option, value);
+		break;
+	case 2: // string
+		convertMessageToString(_scriptPointer, string, sizeof(string));
+		len = resStrLen(_scriptPointer);
+		_scriptPointer += len + 1;
+		ConfMan.set((char *)option, (char *)string);
+		debug(1, "o70_writeINI: Option %s String %s", option, string);
+		break;
+	default:
+		error("o70_writeINI: default type %d", type);
+	}
+}
+
+void ScummEngine_v70he::o70_getStringLenForWidth() {
+	int chr, max;
+	int array, len, pos, width = 0;
+
+	max = pop();
+	pos = pop();
+	array = pop();
+
+	len = resStrLen(getStringAddress(array));
+
+	writeVar(0, array);
+	while (pos <= len) {
+		chr = readArray(0, 0, pos);
+		width += getStringCharWidth(chr);
+		if (width >= max) {
+			push(pos);
+			return;
+		}
+		pos++;
+	}
+
+	push(len);
+}
+
+void ScummEngine_v70he::o70_getCharIndexInString() {
+	int array, end, len, pos, value;
+
+	value = pop();
+	end = pop();
+	pos = pop();
+	array = pop();
+
+	if (end >= 0) {
+		len = resStrLen(getStringAddress(array));
+		if (len < end)
+			end = len;
+	} else {
+		end = 0;
+	}
+
+	if (pos < 0)
+		pos = 0;
+
+	writeVar(0, array);
+	if (end > pos) {
+		while (end >= pos) {
+			if (readArray(0, 0, pos) == value) {
+				push(pos);
+				return;
+			}
+			pos++;
+		}
+	} else {
+		while (end <= pos) {
+			if (readArray(0, 0, pos) == value) {
+				push(pos);
+				return;
+			}
+			pos--;
+		}
+	}
+
+	push(-1);
+}
+
+void ScummEngine_v70he::o70_setFilePath() {
+	int len;
+	byte filename[100];
+
+	convertMessageToString(_scriptPointer, filename, sizeof(filename));
+	len = resStrLen(_scriptPointer);
+	_scriptPointer += len + 1;
+
+	debug(1,"stub o70_setFilePath(%s)", filename);
+}
+
+void ScummEngine_v70he::o70_setSystemMessage() {
+	int len;
+	byte name[255];
+
+	byte subOp = fetchScriptByte();
+
+	convertMessageToString(_scriptPointer, name, sizeof(name));
+	len = resStrLen(_scriptPointer);
+	_scriptPointer += len + 1;
+
+	switch (subOp) {
+	case 240:
+		debug(1,"o70_setSystemMessage: (%d) %s", subOp, name);
+		break;
+	case 241:  // Set Version
+		debug(1,"o70_setSystemMessage: (%d) %s", subOp, name);
+		break;
+	case 242:
+		debug(1,"o70_setSystemMessage: (%d) %s", subOp, name);
+		break;
+	case 243: // Set Window Caption
+		_system->setWindowCaption((const char *)name);
+		break;
+	default:
+		error("o70_setSystemMessage: default case %d", subOp);
+	}
+}
+
+void ScummEngine_v70he::o70_polygonOps() {
+	int vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y;
+	int id, fromId, toId;
+	bool flag;
+
+	byte subOp = fetchScriptByte();
+
+	switch (subOp) {
+	case 68: // HE 100
+	case 69: // HE 100
+	case 246:
+	case 248:
+		vert4y = pop();
+		vert4x = pop();
+		vert3y = pop();
+		vert3x = pop();
+		vert2y = pop();
+		vert2x = pop();
+		vert1y = pop();
+		vert1x = pop();
+		flag = (subOp == 69 || subOp == 248);
+		id = pop();
+		_wiz->polygonStore(id, flag, vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y);
+		break;
+	case 28: // HE 100
+	case 247:
+		toId = pop();
+		fromId = pop();
+		_wiz->polygonErase(fromId, toId);
+		break;
+	default:
+		error("o70_polygonOps: default case %d", subOp);
+	}
+}
+
+void ScummEngine_v70he::o70_polygonHit() {
+	int y = pop();
+	int x = pop();
+	push(_wiz->polygonHit(0, x, y));
+}
+
+} // End of namespace Scumm

Modified: scummvm/trunk/engines/scumm/he/script_v72he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v72he.cpp	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/he/script_v72he.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -32,7 +32,7 @@
 #include "scumm/he/intern_he.h"
 #include "scumm/object.h"
 #include "scumm/resource.h"
-#include "scumm/he/resource_v7he.h"
+#include "scumm/he/resource_he.h"
 #include "scumm/scumm.h"
 #include "scumm/sound.h"
 #include "scumm/util.h"

Deleted: scummvm/trunk/engines/scumm/he/script_v7he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v7he.cpp	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/he/script_v7he.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -1,1153 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001  Ludvig Strigeus
- * 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 "common/config-manager.h"
-#include "common/system.h"
-
-#include "scumm/actor.h"
-#include "scumm/charset.h"
-#include "scumm/he/intern_he.h"
-#include "scumm/object.h"
-#include "scumm/resource.h"
-#include "scumm/he/resource_v7he.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/verbs.h"
-
-namespace Scumm {
-
-#define OPCODE(x)	_OPCODE(ScummEngine_v70he, x)
-
-void ScummEngine_v70he::setupOpcodes() {
-	static const OpcodeEntryv70he opcodes[256] = {
-		/* 00 */
-		OPCODE(o6_pushByte),
-		OPCODE(o6_pushWord),
-		OPCODE(o6_pushByteVar),
-		OPCODE(o6_pushWordVar),
-		/* 04 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayRead),
-		OPCODE(o6_wordArrayRead),
-		/* 08 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayIndexedRead),
-		OPCODE(o6_wordArrayIndexedRead),
-		/* 0C */
-		OPCODE(o6_dup),
-		OPCODE(o6_not),
-		OPCODE(o6_eq),
-		OPCODE(o6_neq),
-		/* 10 */
-		OPCODE(o6_gt),
-		OPCODE(o6_lt),
-		OPCODE(o6_le),
-		OPCODE(o6_ge),
-		/* 14 */
-		OPCODE(o6_add),
-		OPCODE(o6_sub),
-		OPCODE(o6_mul),
-		OPCODE(o6_div),
-		/* 18 */
-		OPCODE(o6_land),
-		OPCODE(o6_lor),
-		OPCODE(o6_pop),
-		OPCODE(o6_invalid),
-		/* 1C */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 20 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 24 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 28 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 2C */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 30 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 34 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 38 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 3C */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* 40 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_writeByteVar),
-		OPCODE(o6_writeWordVar),
-		/* 44 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayWrite),
-		OPCODE(o6_wordArrayWrite),
-		/* 48 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayIndexedWrite),
-		OPCODE(o6_wordArrayIndexedWrite),
-		/* 4C */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteVarInc),
-		OPCODE(o6_wordVarInc),
-		/* 50 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayInc),
-		OPCODE(o6_wordArrayInc),
-		/* 54 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteVarDec),
-		OPCODE(o6_wordVarDec),
-		/* 58 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_byteArrayDec),
-		OPCODE(o6_wordArrayDec),
-		/* 5C */
-		OPCODE(o6_if),
-		OPCODE(o6_ifNot),
-		OPCODE(o6_startScript),
-		OPCODE(o6_startScriptQuick),
-		/* 60 */
-		OPCODE(o6_startObject),
-		OPCODE(o6_drawObject),
-		OPCODE(o6_drawObjectAt),
-		OPCODE(o6_invalid),
-		/* 64 */
-		OPCODE(o6_invalid),
-		OPCODE(o6_stopObjectCode),
-		OPCODE(o6_stopObjectCode),
-		OPCODE(o6_endCutscene),
-		/* 68 */
-		OPCODE(o6_cutscene),
-		OPCODE(o6_stopMusic),
-		OPCODE(o6_freezeUnfreeze),
-		OPCODE(o6_cursorCommand),
-		/* 6C */
-		OPCODE(o6_breakHere),
-		OPCODE(o6_ifClassOfIs),
-		OPCODE(o6_setClass),
-		OPCODE(o6_getState),
-		/* 70 */
-		OPCODE(o60_setState),
-		OPCODE(o6_setOwner),
-		OPCODE(o6_getOwner),
-		OPCODE(o6_jump),
-		/* 74 */
-		OPCODE(o70_startSound),
-		OPCODE(o6_stopSound),
-		OPCODE(o6_startMusic),
-		OPCODE(o6_stopObjectScript),
-		/* 78 */
-		OPCODE(o6_panCameraTo),
-		OPCODE(o6_actorFollowCamera),
-		OPCODE(o6_setCameraAt),
-		OPCODE(o6_loadRoom),
-		/* 7C */
-		OPCODE(o6_stopScript),
-		OPCODE(o6_walkActorToObj),
-		OPCODE(o6_walkActorTo),
-		OPCODE(o6_putActorAtXY),
-		/* 80 */
-		OPCODE(o6_putActorAtObject),
-		OPCODE(o6_faceActor),
-		OPCODE(o6_animateActor),
-		OPCODE(o6_doSentence),
-		/* 84 */
-		OPCODE(o70_pickupObject),
-		OPCODE(o6_loadRoomWithEgo),
-		OPCODE(o6_invalid),
-		OPCODE(o6_getRandomNumber),
-		/* 88 */
-		OPCODE(o6_getRandomNumberRange),
-		OPCODE(o6_invalid),
-		OPCODE(o6_getActorMoving),
-		OPCODE(o6_isScriptRunning),
-		/* 8C */
-		OPCODE(o70_getActorRoom),
-		OPCODE(o6_getObjectX),
-		OPCODE(o6_getObjectY),
-		OPCODE(o6_getObjectOldDir),
-		/* 90 */
-		OPCODE(o6_getActorWalkBox),
-		OPCODE(o6_getActorCostume),
-		OPCODE(o6_findInventory),
-		OPCODE(o6_getInventoryCount),
-		/* 94 */
-		OPCODE(o6_getVerbFromXY),
-		OPCODE(o6_beginOverride),
-		OPCODE(o6_endOverride),
-		OPCODE(o6_setObjectName),
-		/* 98 */
-		OPCODE(o6_isSoundRunning),
-		OPCODE(o6_setBoxFlags),
-		OPCODE(o6_invalid),
-		OPCODE(o70_resourceRoutines),
-		/* 9C */
-		OPCODE(o60_roomOps),
-		OPCODE(o60_actorOps),
-		OPCODE(o6_verbOps),
-		OPCODE(o6_getActorFromXY),
-		/* A0 */
-		OPCODE(o6_findObject),
-		OPCODE(o6_pseudoRoom),
-		OPCODE(o6_getActorElevation),
-		OPCODE(o6_getVerbEntrypoint),
-		/* A4 */
-		OPCODE(o6_arrayOps),
-		OPCODE(o6_saveRestoreVerbs),
-		OPCODE(o6_drawBox),
-		OPCODE(o6_pop),
-		/* A8 */
-		OPCODE(o6_getActorWidth),
-		OPCODE(o6_wait),
-		OPCODE(o6_getActorScaleX),
-		OPCODE(o6_getActorAnimCounter1),
-		/* AC */
-		OPCODE(o6_invalid),
-		OPCODE(o6_isAnyOf),
-		OPCODE(o70_systemOps),
-		OPCODE(o6_isActorInBox),
-		/* B0 */
-		OPCODE(o6_delay),
-		OPCODE(o6_delaySeconds),
-		OPCODE(o6_delayMinutes),
-		OPCODE(o6_stopSentence),
-		/* B4 */
-		OPCODE(o6_printLine),
-		OPCODE(o6_printText),
-		OPCODE(o6_printDebug),
-		OPCODE(o6_printSystem),
-		/* B8 */
-		OPCODE(o6_printActor),
-		OPCODE(o6_printEgo),
-		OPCODE(o6_talkActor),
-		OPCODE(o6_talkEgo),
-		/* BC */
-		OPCODE(o6_dimArray),
-		OPCODE(o6_stopObjectCode),
-		OPCODE(o6_startObjectQuick),
-		OPCODE(o6_startScriptQuick2),
-		/* C0 */
-		OPCODE(o6_dim2dimArray),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* C4 */
-		OPCODE(o6_abs),
-		OPCODE(o6_distObjectObject),
-		OPCODE(o6_distObjectPt),
-		OPCODE(o6_distPtPt),
-		/* C8 */
-		OPCODE(o60_kernelGetFunctions),
-		OPCODE(o70_kernelSetFunctions),
-		OPCODE(o6_delayFrames),
-		OPCODE(o6_pickOneOf),
-		/* CC */
-		OPCODE(o6_pickOneOfDefault),
-		OPCODE(o6_stampObject),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* D0 */
-		OPCODE(o6_getDateTime),
-		OPCODE(o6_stopTalking),
-		OPCODE(o6_getAnimateVariable),
-		OPCODE(o6_invalid),
-		/* D4 */
-		OPCODE(o6_shuffle),
-		OPCODE(o6_jumpToScript),
-		OPCODE(o6_band),
-		OPCODE(o6_bor),
-		/* D8 */
-		OPCODE(o6_isRoomScriptRunning),
-		OPCODE(o60_closeFile),
-		OPCODE(o60_openFile),
-		OPCODE(o60_readFile),
-		/* DC */
-		OPCODE(o60_writeFile),
-		OPCODE(o6_findAllObjects),
-		OPCODE(o60_deleteFile),
-		OPCODE(o60_rename),
-		/* E0 */
-		OPCODE(o60_soundOps),
-		OPCODE(o6_getPixel),
-		OPCODE(o60_localizeArrayToScript),
-		OPCODE(o6_pickVarRandom),
-		/* E4 */
-		OPCODE(o6_setBoxSet),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		/* E8 */
-		OPCODE(o6_invalid),
-		OPCODE(o70_seekFilePos),
-		OPCODE(o60_redimArray),
-		OPCODE(o60_readFilePos),
-		/* EC */
-		OPCODE(o70_copyString),
-		OPCODE(o70_getStringWidth),
-		OPCODE(o70_getStringLen),
-		OPCODE(o70_appendString),
-		/* F0 */
-		OPCODE(o70_concatString),
-		OPCODE(o70_compareString),
-		OPCODE(o70_isResourceLoaded),
-		OPCODE(o70_readINI),
-		/* F4 */
-		OPCODE(o70_writeINI),
-		OPCODE(o70_getStringLenForWidth),
-		OPCODE(o70_getCharIndexInString),
-		OPCODE(o6_invalid),
-		/* F8 */
-		OPCODE(o6_invalid),
-		OPCODE(o70_setFilePath),
-		OPCODE(o70_setSystemMessage),
-		OPCODE(o70_polygonOps),
-		/* FC */
-		OPCODE(o70_polygonHit),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-		OPCODE(o6_invalid),
-	};
-
-	_opcodesv70he = opcodes;
-}
-
-void ScummEngine_v70he::executeOpcode(byte i) {
-	OpcodeProcv70he op = _opcodesv70he[i].proc;
-	(this->*op) ();
-}
-
-const char *ScummEngine_v70he::getOpcodeDesc(byte i) {
-	return _opcodesv70he[i].desc;
-}
-
-int ScummEngine_v70he::getStringCharWidth(byte chr) {
-	int charset = _string[0]._default.charset;
-
-	byte *ptr = getResourceAddress(rtCharset, charset);
-	assert(ptr);
-	ptr += 29;
-
-	int spacing = 0;
-
-	int offs = READ_LE_UINT32(ptr + chr * 4 + 4);
-	if (offs) {
-		spacing = ptr[offs] + (signed char)ptr[offs + 2];
-	}
-
-	return spacing;
-}
-
-int ScummEngine_v70he::setupStringArray(int size) {
-	writeVar(0, 0);
-	defineArray(0, kStringArray, 0, size + 1);
-	writeArray(0, 0, 0, 0);
-	return readVar(0);
-}
-
-void ScummEngine_v70he::appendSubstring(int dst, int src, int srcOffs, int len) {
-	int dstOffs, value;
-	int i = 0;
-
-	if (len == -1) {
-		len = resStrLen(getStringAddress(src));
-		srcOffs = 0;
-	}
-
-	dstOffs = resStrLen(getStringAddress(dst));
-
-	len -= srcOffs;
-	len++;
-
-	while (i < len) {
-		writeVar(0, src);
-		value = readArray(0, 0, srcOffs + i);
-		writeVar(0, dst);
-		writeArray(0, 0, dstOffs + i, value);
-		i++;
-	}
-
-	writeArray(0, 0, dstOffs + i, 0);
-}
-
-void ScummEngine_v70he::o70_startSound() {
-	int var, value;
-
-	byte subOp = fetchScriptByte();
-
-	switch (subOp) {
-	case 9:
-		_heSndFlags |= 4;
-		break;
-	case 23:
-		value = pop();
-		var = pop();
-		_heSndSoundId = pop();
-		_sound->setSoundVar(_heSndSoundId, var, value);
-		break;
-	case 25:
-		value = pop();
-		_heSndSoundId = pop();
-		_sound->addSoundToQueue(_heSndSoundId, 0, 0, 8);
-	case 56:
-		_heSndFlags |= 16;
-		break;
-	case 164:
-		_heSndFlags |= 2;
-		break;
-	case 224:
-		_heSndSoundFreq = pop();
-		break;
-	case 230:
-		_heSndChannel = pop();
-		break;
-	case 231:
-		_heSndOffset = pop();
-		break;
-	case 232:
-		_heSndSoundId = pop();
-		_heSndOffset = 0;
-		_heSndSoundFreq = 11025;
-		_heSndChannel = VAR(VAR_SOUND_CHANNEL);
-		break;
-	case 245:
-		_heSndFlags |= 1;
-		break;
-	case 255:
-		_sound->addSoundToQueue(_heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags);
-		_heSndFlags = 0;
-		break;
-
-	default:
-		error("o70_startSound invalid case %d", subOp);
-	}
-}
-
-void ScummEngine_v70he::o70_pickupObject() {
-	int obj, room;
-
-	room = pop();
-	obj = pop();
-	if (room == 0)
-		room = getObjectRoom(obj);
-
-	addObjectToInventory(obj, room);
-	putOwner(obj, VAR(VAR_EGO));
-	if (_heversion <= 70) {
-		putClass(obj, kObjectClassUntouchable, 1);
-		putState(obj, 1);
-		markObjectRectAsDirty(obj);
-		clearDrawObjectQueue();
-	}
-	runInventoryScript(obj);									/* Difference */
-}
-
-void ScummEngine_v70he::o70_getActorRoom() {
-	int act = pop();
-
-	if (act < _numActors) {
-		Actor *a = derefActor(act, "o70_getActorRoom");
-		push(a->_room);
-	} else
-		push(getObjectRoom(act));
-}
-
-void ScummEngine_v70he::o70_resourceRoutines() {
-	int objidx, resid;
-
-	byte subOp = fetchScriptByte();
-
-	switch (subOp) {
-	case 100:		// SO_LOAD_SCRIPT
-		resid = pop();
-		ensureResourceLoaded(rtScript, resid);
-		break;
-	case 101:		// SO_LOAD_SOUND
-		resid = pop();
-		ensureResourceLoaded(rtSound, resid);
-		break;
-	case 102:		// SO_LOAD_COSTUME
-		resid = pop();
-		ensureResourceLoaded(rtCostume, resid);
-		break;
-	case 103:		// SO_LOAD_ROOM
-		resid = pop();
-		ensureResourceLoaded(rtRoomImage, resid);
-		ensureResourceLoaded(rtRoom, resid);
-		break;
-	case 104:		// SO_NUKE_SCRIPT
-		resid = pop();
-		res.nukeResource(rtScript, resid);
-		break;
-	case 105:		// SO_NUKE_SOUND
-		resid = pop();
-		res.nukeResource(rtSound, resid);
-		break;
-	case 106:		// SO_NUKE_COSTUME
-		resid = pop();
-		res.nukeResource(rtCostume, resid);
-		break;
-	case 107:		// SO_NUKE_ROOM
-		resid = pop();
-		res.nukeResource(rtRoom, resid);
-		res.nukeResource(rtRoomImage, resid);
-		break;
-	case 108:		// SO_LOCK_SCRIPT
-		resid = pop();
-		if (resid >= _numGlobalScripts)
-			break;
-		res.lock(rtScript, resid);
-		break;
-	case 109:		// SO_LOCK_SOUND
-		resid = pop();
-		res.lock(rtSound, resid);
-		break;
-	case 110:		// SO_LOCK_COSTUME
-		resid = pop();
-		res.lock(rtCostume, resid);
-		break;
-	case 111:		// SO_LOCK_ROOM
-		resid = pop();
-		if (_heversion <= 71 && resid > 0x7F)
-			resid = _resourceMapper[resid & 0x7F];
-		res.lock(rtRoom, resid);
-		res.lock(rtRoomImage, resid);
-		break;
-	case 112:		// SO_UNLOCK_SCRIPT
-		resid = pop();
-		if (resid >= _numGlobalScripts)
-			break;
-		res.unlock(rtScript, resid);
-		break;
-	case 113:		// SO_UNLOCK_SOUND
-		resid = pop();
-		res.unlock(rtSound, resid);
-		break;
-	case 114:		// SO_UNLOCK_COSTUME
-		resid = pop();
-		res.unlock(rtCostume, resid);
-		break;
-	case 115:		// SO_UNLOCK_ROOM
-		resid = pop();
-		if (_heversion <= 71 && resid > 0x7F)
-			resid = _resourceMapper[resid & 0x7F];
-		res.unlock(rtRoom, resid);
-		res.unlock(rtRoomImage, resid);
-		break;
-	case 116:
-		break;
-	case 117:		// SO_LOAD_CHARSET
-		resid = pop();
-		loadCharset(resid);
-		break;
-	case 118:		// SO_NUKE_CHARSET
-		resid = pop();
-		nukeCharset(resid);
-		break;
-	case 119:		// SO_LOAD_OBJECT
-		{
-			int obj = pop();
-			int room = getObjectRoom(obj);
-			loadFlObject(obj, room);
-			break;
-		}
-	case 120:
-		resid = pop();
-		if (resid >= _numGlobalScripts)
-			break;
-		//queueLoadResource(rtScript, resid);
-		break;
-	case 121:
-		resid = pop();
-		//queueLoadResource(rtSound, resid);
-		break;
-	case 122:
-		resid = pop();
-		//queueLoadResource(rtCostume, resid);
-		break;
-	case 123:
-		resid = pop();
-		//queueLoadResource(rtRoomImage, resid);
-		break;
-	case 159:
-		resid = pop();
-		res.unlock(rtImage, resid);
-		break;
-	case 192:
-		resid = pop();
-		res.nukeResource(rtImage, resid);
-		break;
-	case 201:
-		resid = pop();
-		ensureResourceLoaded(rtImage, resid);
-		break;
-	case 202:
-		resid = pop();
-		res.lock(rtImage, resid);
-		break;
-	case 203:
-		resid = pop();
-		//queueLoadResource(rtImage, resid);
-		break;
-	case 233:
-		resid = pop();
-		objidx = getObjectIndex(resid);
-		if (objidx == -1)
-			break;
-		res.lock(rtFlObject, _objs[objidx].fl_object_index);
-		break;
-	case 235:
-		resid = pop();
-		objidx = getObjectIndex(resid);
-		if (objidx == -1)
-			break;
-		res.unlock(rtFlObject, _objs[objidx].fl_object_index);
-		break;
-	case 239:
-		// Used in airport
-		break;
-	default:
-		error("o70_resourceRoutines: default case %d", subOp);
-	}
-}
-
-void ScummEngine_v70he::o70_systemOps() {
-	byte *src, string[256];
-	int id, len;
-
-	byte subOp = fetchScriptByte();
-
-	switch (subOp) {
-	case 158:
-		restart();
-		break;
-	case 160:
-		// Confirm shutdown
-		shutDown();
-		break;
-	case 244:
-		shutDown();
-		break;
-	case 250:
-		id = pop();
-		src = getStringAddress(id);
-		len = resStrLen(src) + 1;
-		memcpy(string, src, len);
-		debug(0, "Start executable (%s)", string);
-		break;
-	case 251:
-		convertMessageToString(_scriptPointer, string, sizeof(string));
-		len = resStrLen(_scriptPointer);
-		_scriptPointer += len + 1;
-		debug(0, "Start executable (%s)", string);
-		break;
-	case 252:
-		convertMessageToString(_scriptPointer, string, sizeof(string));
-		len = resStrLen(_scriptPointer);
-		_scriptPointer += len + 1;
-		debug(0, "Start game (%s)", string);
-		break;
-	case 253:
-		id = pop();
-		src = getStringAddress(id);
-		len = resStrLen(src) + 1;
-		memcpy(string, src, len);
-		debug(0, "Start game (%s)", string);
-		break;
-	default:
-		error("o70_systemOps invalid case %d", subOp);
-	}
-}
-
-void ScummEngine_v70he::o70_seekFilePos() {
-	int mode, offset, slot;
-	mode = pop();
-	offset = pop();
-	slot = pop();
-
-	if (slot == -1)
-		return;
-
-	switch (mode) {
-	case 1:
-		_hFileTable[slot].seek(offset, SEEK_SET);
-		break;
-	case 2:
-		_hFileTable[slot].seek(offset, SEEK_CUR);
-		break;
-	case 3:
-		_hFileTable[slot].seek(offset, SEEK_END);
-		break;
-	default:
-		error("o70_seekFilePos: default case 0x%x", mode);
-	}
-}
-
-void ScummEngine_v70he::o70_copyString() {
-	int dst, size;
-	int src = pop();
-
-	size = resStrLen(getStringAddress(src)) + 1;
-	dst = setupStringArray(size);
-
-	appendSubstring(dst, src, -1, -1);
-
-	push(dst);
-}
-
-void ScummEngine_v70he::o70_getStringWidth() {
-	int array, pos, len;
-	int chr, width = 0;
-
-	len = pop();
-	pos = pop();
-	array = pop();
-
-	if (len == -1) {
-		pos = 0;
-		len = resStrLen(getStringAddress(array));
-	}
-
-	writeVar(0, array);
-	while (pos <= len) {
-		chr = readArray(0, 0, pos);
-		if (chr == 0)
-			break;
-		width += getStringCharWidth(chr);
-		pos++;
-	}
-
-	push(width);
-}
-
-void ScummEngine_v70he::o70_kernelSetFunctions() {
-	int args[29];
-	int num;
-	Actor *a;
-
-	num = getStackList(args, ARRAYSIZE(args));
-
-	switch (args[0]) {
-	case 1:
-		// Used to restore images when decorating cake in
-		// Fatty Bear's Birthday Surprise
-		virtScreenLoad(args[1], args[2], args[3], args[4], args[5]);
-		break;
-	case 20: // HE72+
-		a = derefActor(args[1], "o70_kernelSetFunctions: 20");
-		((ScummEngine_v71he *)this)->queueAuxBlock(a);
-		break;
-	case 21:
-		_skipDrawObject = 1;
-		break;
-	case 22:
-		_skipDrawObject = 0;
-		break;
-	case 23:
-		_charset->clearCharsetMask();
-		_fullRedraw = true;
-		break;
-	case 24:
-		_skipProcessActors = 1;
-		redrawAllActors();
-		break;
-	case 25:
-		_skipProcessActors = 0;
-		redrawAllActors();
-		break;
-	case 26:
-		a = derefActor(args[1], "o70_kernelSetFunctions: 26");
-		a->_auxBlock.r.left = 0;
-		a->_auxBlock.r.right = -1;
-		a->_auxBlock.r.top = 0;
-		a->_auxBlock.r.bottom = -2;
-		break;
-	case 30:
-		a = derefActor(args[1], "o70_kernelSetFunctions: 30");
-		a->_clipOverride.bottom = args[2];
-		break;
-	case 42:
-		_wiz->_rectOverrideEnabled = true;
-		_wiz->_rectOverride.left = args[1];
-		_wiz->_rectOverride.top = args[2];
-		_wiz->_rectOverride.right = args[3];
-		_wiz->_rectOverride.bottom = args[4];
-		break;
-	case 43:
-		_wiz->_rectOverrideEnabled = false;
-		break;
-	default:
-		error("o70_kernelSetFunctions: default case %d (param count %d)", args[0], num);
-	}
-}
-
-void ScummEngine_v70he::o70_getStringLen() {
-	int id, len;
-	byte *addr;
-
-	id = pop();
-
-	addr = getStringAddress(id);
-	if (!addr)
-		error("o70_getStringLen: Reference to zeroed array pointer (%d)", id);
-
-	len = resStrLen(getStringAddress(id));
-	push(len);
-}
-
-void ScummEngine_v70he::o70_appendString() {
-	int dst, size;
-
-	int len = pop();
-	int srcOffs = pop();
-	int src = pop();
-
-	size = len - srcOffs + 2;
-	dst = setupStringArray(size);
-
-	appendSubstring(dst, src, srcOffs, len);
-
-	push(dst);
-}
-
-void ScummEngine_v70he::o70_concatString() {
-	int dst, size;
-
-	int src2 = pop();
-	int src1 = pop();
-
-	size = resStrLen(getStringAddress(src1));
-	size += resStrLen(getStringAddress(src2)) + 1;
-	dst = setupStringArray(size);
-
-	appendSubstring(dst, src1, 0, -1);
-	appendSubstring(dst, src2, 0, -1);
-
-	push(dst);
-}
-
-void ScummEngine_v70he::o70_compareString() {
-	int result;
-
-	int array1 = pop();
-	int array2 = pop();
-
-	byte *string1 = getStringAddress(array1);
-	if (!string1)
-		error("o70_compareString: Reference to zeroed array pointer (%d)", array1);
-
-	byte *string2 = getStringAddress(array2);
-	if (!string2)
-		error("o70_compareString: Reference to zeroed array pointer (%d)", array2);
-
-	while (*string1 == *string2) {
-		if (*string2 == 0) {
-			push(0);
-			return;
-		}
-
-		string1++;
-		string2++;
-	}
-
-	result = (*string1 > *string2) ? -1 : 1;
-	push(result);
-}
-
-void ScummEngine_v70he::o70_isResourceLoaded() {
-	// Reports percentage of resource loaded by queue
-	int type;
-
-	byte subOp = fetchScriptByte();
-	/* int idx = */ pop();
-
-	switch (subOp) {
-	case 18:
-		type = rtImage;
-		break;
-	case 226:
-		type = rtRoom;
-		break;
-	case 227:
-		type = rtCostume;
-		break;
-	case 228:
-		type = rtSound;
-		break;
-	case 229:
-		type = rtScript;
-		break;
-	default:
-		error("o70_isResourceLoaded: default case %d", subOp);
-	}
-
-	push(100);
-}
-
-void ScummEngine_v70he::o70_readINI() {
-	byte option[256];
-	ArrayHeader *ah;
-	const char *entry;
-	int len, type;
-
-	convertMessageToString(_scriptPointer, option, sizeof(option));
-	len = resStrLen(_scriptPointer);
-	_scriptPointer += len + 1;
-
-	type = pop();
-	switch (type) {
-	case 1: // number
-		if (!strcmp((char *)option, "NoPrinting")) {
-			push(1);
-		} else if (!strcmp((char *)option, "TextOn")) {
-			push(ConfMan.getBool("subtitles"));
-		} else {
-			push(ConfMan.getInt((char *)option));
-		}
-		break;
-	case 2: // string
-		entry = (ConfMan.get((char *)option).c_str());
-
-		writeVar(0, 0);
-		len = resStrLen((const byte *)entry);
-		ah = defineArray(0, kStringArray, 0, len);
-		memcpy(ah->data, entry, len);
-
-		push(readVar(0));
-		break;
-	default:
-		error("o70_readINI: default type %d", type);
-	}
-	debug(1, "o70_readINI: Option %s", option);
-}
-
-void ScummEngine_v70he::o70_writeINI() {
-	int type, value;
-	byte option[256], string[256];
-	int len;
-
-	type = pop();
-	value = pop();
-
-	convertMessageToString(_scriptPointer, option, sizeof(option));
-	len = resStrLen(_scriptPointer);
-	_scriptPointer += len + 1;
-
-	switch (type) {
-	case 1: // number
-		ConfMan.set((char *)option, value);
-		debug(1, "o70_writeINI: Option %s Value %d", option, value);
-		break;
-	case 2: // string
-		convertMessageToString(_scriptPointer, string, sizeof(string));
-		len = resStrLen(_scriptPointer);
-		_scriptPointer += len + 1;
-		ConfMan.set((char *)option, (char *)string);
-		debug(1, "o70_writeINI: Option %s String %s", option, string);
-		break;
-	default:
-		error("o70_writeINI: default type %d", type);
-	}
-}
-
-void ScummEngine_v70he::o70_getStringLenForWidth() {
-	int chr, max;
-	int array, len, pos, width = 0;
-
-	max = pop();
-	pos = pop();
-	array = pop();
-
-	len = resStrLen(getStringAddress(array));
-
-	writeVar(0, array);
-	while (pos <= len) {
-		chr = readArray(0, 0, pos);
-		width += getStringCharWidth(chr);
-		if (width >= max) {
-			push(pos);
-			return;
-		}
-		pos++;
-	}
-
-	push(len);
-}
-
-void ScummEngine_v70he::o70_getCharIndexInString() {
-	int array, end, len, pos, value;
-
-	value = pop();
-	end = pop();
-	pos = pop();
-	array = pop();
-
-	if (end >= 0) {
-		len = resStrLen(getStringAddress(array));
-		if (len < end)
-			end = len;
-	} else {
-		end = 0;
-	}
-
-	if (pos < 0)
-		pos = 0;
-
-	writeVar(0, array);
-	if (end > pos) {
-		while (end >= pos) {
-			if (readArray(0, 0, pos) == value) {
-				push(pos);
-				return;
-			}
-			pos++;
-		}
-	} else {
-		while (end <= pos) {
-			if (readArray(0, 0, pos) == value) {
-				push(pos);
-				return;
-			}
-			pos--;
-		}
-	}
-
-	push(-1);
-}
-
-void ScummEngine_v70he::o70_setFilePath() {
-	int len;
-	byte filename[100];
-
-	convertMessageToString(_scriptPointer, filename, sizeof(filename));
-	len = resStrLen(_scriptPointer);
-	_scriptPointer += len + 1;
-
-	debug(1,"stub o70_setFilePath(%s)", filename);
-}
-
-void ScummEngine_v70he::o70_setSystemMessage() {
-	int len;
-	byte name[255];
-
-	byte subOp = fetchScriptByte();
-
-	convertMessageToString(_scriptPointer, name, sizeof(name));
-	len = resStrLen(_scriptPointer);
-	_scriptPointer += len + 1;
-
-	switch (subOp) {
-	case 240:
-		debug(1,"o70_setSystemMessage: (%d) %s", subOp, name);
-		break;
-	case 241:  // Set Version
-		debug(1,"o70_setSystemMessage: (%d) %s", subOp, name);
-		break;
-	case 242:
-		debug(1,"o70_setSystemMessage: (%d) %s", subOp, name);
-		break;
-	case 243: // Set Window Caption
-		_system->setWindowCaption((const char *)name);
-		break;
-	default:
-		error("o70_setSystemMessage: default case %d", subOp);
-	}
-}
-
-void ScummEngine_v70he::o70_polygonOps() {
-	int vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y;
-	int id, fromId, toId;
-	bool flag;
-
-	byte subOp = fetchScriptByte();
-
-	switch (subOp) {
-	case 68: // HE 100
-	case 69: // HE 100
-	case 246:
-	case 248:
-		vert4y = pop();
-		vert4x = pop();
-		vert3y = pop();
-		vert3x = pop();
-		vert2y = pop();
-		vert2x = pop();
-		vert1y = pop();
-		vert1x = pop();
-		flag = (subOp == 69 || subOp == 248);
-		id = pop();
-		_wiz->polygonStore(id, flag, vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y);
-		break;
-	case 28: // HE 100
-	case 247:
-		toId = pop();
-		fromId = pop();
-		_wiz->polygonErase(fromId, toId);
-		break;
-	default:
-		error("o70_polygonOps: default case %d", subOp);
-	}
-}
-
-void ScummEngine_v70he::o70_polygonHit() {
-	int y = pop();
-	int x = pop();
-	push(_wiz->polygonHit(0, x, y));
-}
-
-} // End of namespace Scumm

Modified: scummvm/trunk/engines/scumm/he/script_v80he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v80he.cpp	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/he/script_v80he.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -32,7 +32,7 @@
 #include "scumm/he/intern_he.h"
 #include "scumm/object.h"
 #include "scumm/resource.h"
-#include "scumm/he/resource_v7he.h"
+#include "scumm/he/resource_he.h"
 #include "scumm/scumm.h"
 #include "scumm/sound.h"
 #include "scumm/util.h"

Modified: scummvm/trunk/engines/scumm/he/script_v90he.cpp
===================================================================
--- scummvm/trunk/engines/scumm/he/script_v90he.cpp	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/he/script_v90he.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -29,7 +29,7 @@
 #include "scumm/he/logic_he.h"
 #include "scumm/object.h"
 #include "scumm/resource.h"
-#include "scumm/he/resource_v7he.h"
+#include "scumm/he/resource_he.h"
 #include "scumm/scumm.h"
 #include "scumm/sound.h"
 #include "scumm/he/sprite_he.h"

Modified: scummvm/trunk/engines/scumm/module.mk
===================================================================
--- scummvm/trunk/engines/scumm/module.mk	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/module.mk	2006-02-15 18:48:49 UTC (rev 20703)
@@ -39,7 +39,7 @@
 	script_v2.o \
 	script_v5.o \
 	script_v6.o \
-	he/script_v6he.o \
+	he/script_v60he.o \
 	scumm.o \
 	sound.o \
 	he/sound_he.o \
@@ -83,8 +83,8 @@
 	he/floodfill_he.o \
 	he/logic_he.o \
 	he/palette_he.o \
-	he/resource_v7he.o \
-	he/script_v7he.o \
+	he/resource_he.o \
+	he/script_v70he.o \
 	he/script_v72he.o \
 	he/script_v80he.o \
 	he/script_v90he.o \

Modified: scummvm/trunk/engines/scumm/scumm.cpp
===================================================================
--- scummvm/trunk/engines/scumm/scumm.cpp	2006-02-15 18:48:56 UTC (rev 20702)
+++ scummvm/trunk/engines/scumm/scumm.cpp	2006-02-15 18:48:49 UTC (rev 20703)
@@ -51,7 +51,7 @@
 #include "scumm/player_v2.h"
 #include "scumm/player_v2a.h"
 #include "scumm/player_v3a.h"
-#include "scumm/he/resource_v7he.h"
+#include "scumm/he/resource_he.h"
 #include "scumm/scumm.h"
 #include "scumm/sound.h"
 #include "scumm/he/sprite_he.h"







More information about the Scummvm-git-logs mailing list