diff options
| -rw-r--r-- | engines/sci/engine/int_hashmap.h | 88 | ||||
| -rw-r--r-- | engines/sci/engine/intmap.cpp (renamed from engines/sci/engine/int_hashmap.cpp) | 44 | ||||
| -rw-r--r-- | engines/sci/engine/intmap.h | 95 | ||||
| -rw-r--r-- | engines/sci/engine/savegame.cfsml | 108 | ||||
| -rw-r--r-- | engines/sci/engine/savegame.cpp | 408 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.cpp | 26 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.h | 4 | ||||
| -rw-r--r-- | engines/sci/include/vm.h | 9 | ||||
| -rw-r--r-- | engines/sci/module.mk | 2 | 
9 files changed, 391 insertions, 393 deletions
| diff --git a/engines/sci/engine/int_hashmap.h b/engines/sci/engine/int_hashmap.h deleted file mode 100644 index e191f76c0f..0000000000 --- a/engines/sci/engine/int_hashmap.h +++ /dev/null @@ -1,88 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef INT_HASHMAP_H -#define INT_HASHMAP_H - -#include "common/scummsys.h" - -namespace Sci { - -/* - * Defines a hash map that maps values to small integers. - * The name "hashmap" here is a bit misleading, because the - * value associated to each key are generated automatically, - * using the lowest "unused" value. - */ - - -// Assumes that the ints are relatively evenly distributed - -#define DCS_INT_HASH_MAX 255 - - -struct int_hash_map_t { -	struct node_t { -		int name; -		int value; -		node_t *next; -	}; - -	int base_value;  // Starts at zero, counts upwards -	node_t *nodes[DCS_INT_HASH_MAX + 1]; -	node_t *holes; /* List of freed entries to minimize -				     ** memory operations and modifications -				     ** to base_value  */ - -	void free_node_recursive(node_t *node); - -public: -	int_hash_map_t(); -	~int_hash_map_t(); - -	/** -	 * Checks whether a value is in the map, adds it if neccessary. -	 * @param value		The value to check for/add -	 * @param add		Whether to add the value if it's not in there -	 * @param was_added	Set to non-zero iff the value is new, ignored if NULL. -	 * @return The new (or old) index, or -1 if add was zero and -	 *                   the value couldn't be found -	 */ -	int check_value(int value, bool add, char *was_added = 0); - -	/** -	 * Removes a value from the hash map. -	 * @param value		The value to remove -	 * @return	The ID of the value, or -1 if it wasn't present -	 */ -	int remove_value(int value); - -}; - -typedef int_hash_map_t *int_hash_map_ptr; - -} // End of namespace Sci - -#endif // INT_HASHMAP_H diff --git a/engines/sci/engine/int_hashmap.cpp b/engines/sci/engine/intmap.cpp index b48653ede1..5fe02ba0b4 100644 --- a/engines/sci/engine/int_hashmap.cpp +++ b/engines/sci/engine/intmap.cpp @@ -23,31 +23,31 @@   *   */ -#include "sci/engine/int_hashmap.h" +#include "sci/engine/intmap.h"  namespace Sci { -#define HASH_MAX DCS_INT_HASH_MAX  #define HASH(x) (x & 0xff) -int_hash_map_t::int_hash_map_t() { +IntMapper::IntMapper() {  	base_value = 0;  	memset(nodes, 0, sizeof(nodes));  	holes = 0;  } -void int_hash_map_t::free_node_recursive(node_t *node) { +void IntMapper::free_node_recursive(Node *node) {  	if (node) {  		free_node_recursive(node->next); +		node->next = 0;  		free(node);  	}  } -int_hash_map_t::~int_hash_map_t() { +IntMapper::~IntMapper() {  	int i; -	for (i = 0; i <= HASH_MAX; i++) +	for (i = 0; i < DCS_INT_HASH_MAX; i++)  		free_node_recursive(nodes[i]);  	free_node_recursive(holes); @@ -56,17 +56,17 @@ int_hash_map_t::~int_hash_map_t() {  	base_value = -42000;  } -int int_hash_map_t::check_value(int value, bool add, char *was_added) { -	node_t **node = &(nodes[HASH(value)]); +int IntMapper::checkKey(int key, bool add, bool *was_added) { +	Node **node = &(nodes[HASH(key)]); -	while (*node && (value != (*node)->name)) +	while (*node && (key != (*node)->key))  		node = &((*node)->next);  	if (was_added) -		*was_added = 0; +		*was_added = false;  	if (*node) { -		return (*node)->value; +		return (*node)->idx;  	}  	// Not found @@ -74,36 +74,36 @@ int int_hash_map_t::check_value(int value, bool add, char *was_added) {  		return -1;  	if (was_added) -		*was_added = 1; +		*was_added = true;  	if (holes) { // Re-use old node  		(*node) = holes;  		holes = (*node)->next;  		(*node)->next = NULL; -		(*node)->name = value; +		(*node)->key = key;  	} else { -		*node = (node_t*)malloc(sizeof(node_t)); -		(*node)->name = value; -		(*node)->value = base_value++; +		*node = (Node*)malloc(sizeof(Node)); +		(*node)->key = key; +		(*node)->idx = base_value++;  		(*node)->next = NULL;  	} -	return (*node)->value; +	return (*node)->idx;  } -int int_hash_map_t::remove_value(int value) { -	node_t **node = &(nodes[HASH(value)]); +int IntMapper::removeKey(int key) { +	Node **node = &(nodes[HASH(key)]); -	while (*node && (value != (*node)->name)) +	while (*node && (key != (*node)->key))  		node = &((*node)->next);  	if (*node) { -		node_t *oldnode = *node; +		Node *oldnode = *node;  		*node = (*node)->next;  		oldnode->next = holes; // Old node is now a 'hole'  		holes = oldnode; -		return oldnode->value; +		return oldnode->key;  	} else  		return -1; // Not found  } diff --git a/engines/sci/engine/intmap.h b/engines/sci/engine/intmap.h new file mode 100644 index 0000000000..fe00fa8621 --- /dev/null +++ b/engines/sci/engine/intmap.h @@ -0,0 +1,95 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef SCI_INTMAP_H +#define SCI_INTMAP_H + +#include "common/scummsys.h" + +namespace Sci { + + + + +// Assumes that the ints are relatively evenly distributed +enum { +	DCS_INT_HASH_MAX = 256 +}; + +/** + * Defines a map from arbitrary integers to "small" integers, useable as index + * into small arrays. This class is somewhat like a hashmap, but not quite: + * Unlike a hashmap, it generates the values associated to each key. It does + * not try to be very clever about it, either, e.g. using a linked list of + * values to keep track of what is mapped where. + * Another important feature is that it reclaims unused values when they + * are removed. + * + * All in all, this implementation is not very elegant, and wastes memory. + * But it does the job. Any rewrite of this class would have to provide a + * way to load the old savegames made using the current implementation. + */ +struct IntMapper { + +	struct Node { +		int key; +		int idx; +		Node *next; +	}; + +	int base_value;  // Starts at zero, counts upwards +	Node *nodes[DCS_INT_HASH_MAX]; +	Node *holes; /* List of freed entries to minimize +				     ** memory operations and modifications +				     ** to base_value  */ + +	void free_node_recursive(Node *node); + +public: +	IntMapper(); +	~IntMapper(); + +	/** +	 * Checks whether a key is in the map, adds it if neccessary. +	 * @param value		The key to check for/add +	 * @param add		Whether to add the key if it's not in there +	 * @param was_added	Set to non-zero if and only if the key is new, ignored if NULL. +	 * @return The new (or old) index, or -1 if add was zero and +	 *                   the key couldn't be found +	 */ +	int checkKey(int key, bool add, bool *wasAdded = 0); + +	/** +	 * Removes a key from the map. +	 * @param key		The key to remove +	 * @return	The index of the key, or -1 if it wasn't present +	 */ +	int removeKey(int key); + +}; + +} // End of namespace Sci + +#endif // SCI_INTMAP_H diff --git a/engines/sci/engine/savegame.cfsml b/engines/sci/engine/savegame.cfsml index ba4164692e..3d5da9b89e 100644 --- a/engines/sci/engine/savegame.cfsml +++ b/engines/sci/engine/savegame.cfsml @@ -200,17 +200,17 @@ int read_menubar_tp(Common::SeekableReadStream *fh, menubar_t **foo, const char  void write_mem_obj_tp(Common::WriteStream *fh, mem_obj_t **foo);  int read_mem_obj_tp(Common::SeekableReadStream *fh, mem_obj_t **foo, const char *lastval, int *line, int *hiteof); -void write_int_hash_map_tp(Common::WriteStream *fh, int_hash_map_t **foo); -int read_int_hash_map_tp(Common::SeekableReadStream *fh, int_hash_map_t **foo, const char *lastval, int *line, int *hiteof); -  void write_songlib_t(Common::WriteStream *fh, songlib_t *foo);  int read_songlib_t(Common::SeekableReadStream *fh, songlib_t *foo, const char *lastval, int *line, int *hiteof); -void write_int_hash_map_node_tp(Common::WriteStream *fh, int_hash_map_t::node_t **foo); -int read_int_hash_map_node_tp(Common::SeekableReadStream *fh, int_hash_map_t::node_t **foo, const char *lastval, int *line, int *hiteof); -  int read_song_tp(Common::SeekableReadStream *fh, song_t **foo, const char *lastval, int *line, int *hiteof); +void write_IntMapperPtr(Common::WriteStream *fh, IntMapper **foo); +int read_IntMapperPtr(Common::SeekableReadStream *fh, IntMapper **foo, const char *lastval, int *line, int *hiteof); + +void write_IntMapperNodePtr(Common::WriteStream *fh, IntMapper::Node **foo); +int read_IntMapperNodePtr(Common::SeekableReadStream *fh, IntMapper::Node **foo, const char *lastval, int *line, int *hiteof); +  void write_SegManagerPtr(Common::WriteStream *fh, SegManager **foo);  int read_SegManagerPtr(Common::SeekableReadStream *fh, SegManager **foo, const char *lastval, int *line, int *hiteof); @@ -238,8 +238,8 @@ TYPE mem_obj_t "mem_obj_t" USING write_mem_obj_t read_mem_obj_t;  TYPE mem_obj_ptr "mem_obj_t *" USING write_mem_obj_tp read_mem_obj_tp;  TYPE reg_t "reg_t" USING write_reg_t read_reg_t;  TYPE size_t "size_t" LIKE int; -TYPE int_hash_map_tp "int_hash_map_t *" USING write_int_hash_map_tp read_int_hash_map_tp; -TYPE int_hash_map_node_tp "int_hash_map_t::node_t *" USING write_int_hash_map_node_tp read_int_hash_map_node_tp; +TYPE IntMapperPtr "IntMapper *" USING write_IntMapperPtr read_IntMapperPtr; +TYPE IntMapperNodePtr "IntMapper::Node *" USING write_IntMapperNodePtr read_IntMapperNodePtr;  TYPE songlib_t "songlib_t" USING write_songlib_t read_songlib_t;  TYPE song_tp "song_t *" USING write_song_tp read_song_tp;  TYPE song_iterator_t "song_iterator_t" USING write_song_iterator_t read_song_iterator_t; @@ -257,9 +257,9 @@ RECORD song_t "song_t" {  	int hold;  } -RECORD int_hash_map_t "int_hash_map_t" { +RECORD IntMapper "IntMapper" {  	int base_value; -	int_hash_map_node_tp nodes[STATIC DCS_INT_HASH_MAX+1]; +	IntMapperNodePtr nodes[STATIC DCS_INT_HASH_MAX];  }  RECORD menu_item_t "menu_item_t" { @@ -291,7 +291,7 @@ RECORD menubar_t "menubar_t" {  }  RECORD SegManager "SegManager" { -	int_hash_map_tp id_seg_map; +	IntMapperPtr id_seg_map;  	mem_obj_ptr heap[DYNAMIC heap_size];  	int heap_size;  	int reserved_id; @@ -417,7 +417,7 @@ RECORD script_t "script_t" {  	size_t script_size;  	size_t heap_size; -	int_hash_map_tp obj_indices; +	IntMapperPtr obj_indices;  	int exports_nr;  	int synonyms_nr;  	int lockers; @@ -492,36 +492,6 @@ int read_songlib_t(Common::SeekableReadStream *fh, songlib_t *songlib, const cha  	return 0;  } -static struct { -	int type; -	const char *name; -} mem_obj_string_names[] = { -	{MEM_OBJ_INVALID, "INVALID"}, -	{MEM_OBJ_SCRIPT, "SCRIPT"}, -	{MEM_OBJ_CLONES, "CLONES"}, -	{MEM_OBJ_LOCALS, "LOCALS"}, -	{MEM_OBJ_STACK, "STACK"}, -	{MEM_OBJ_SYS_STRINGS,"SYS_STRINGS"}, -	{MEM_OBJ_LISTS,"LISTS"}, -	{MEM_OBJ_NODES,"NODES"}, -	{MEM_OBJ_HUNK,"HUNK"}, -	{MEM_OBJ_DYNMEM,"DYNMEM"}}; - -int mem_obj_string_to_enum(const char *str) { -	int i; - -	for (i = 0; i <= MEM_OBJ_MAX; i++) { -		if (!scumm_stricmp(mem_obj_string_names[i].name, str)) -			return i; -	} - -	return -1; -} - -void write_int_hash_map_tp(Common::WriteStream *fh, int_hash_map_t **foo) { -	%CFSMLWRITE int_hash_map_t *foo INTO fh; -} -  void write_song_tp(Common::WriteStream *fh, song_t **foo) {  	%CFSMLWRITE song_t *foo INTO fh;  } @@ -540,33 +510,37 @@ int read_song_tp(Common::SeekableReadStream *fh, song_t **foo, const char *lastv  	return 0;  } -int read_int_hash_map_tp(Common::SeekableReadStream *fh, int_hash_map_t **foo, const char *lastval, int *line, int *hiteof) { -	*foo = new int_hash_map_t; -	%CFSMLREAD int_hash_map_t (*foo) FROM fh ERRVAR *hiteof FIRSTTOKEN lastval LINECOUNTER *line; +void write_IntMapperPtr(Common::WriteStream *fh, IntMapper **foo) { +	%CFSMLWRITE IntMapper *foo INTO fh; +} + +int read_IntMapperPtr(Common::SeekableReadStream *fh, IntMapper **foo, const char *lastval, int *line, int *hiteof) { +	*foo = new IntMapper(); +	%CFSMLREAD IntMapper (*foo) FROM fh ERRVAR *hiteof FIRSTTOKEN lastval LINECOUNTER *line;  	(*foo)->holes = NULL;  	return 0;  } -void write_int_hash_map_node_tp(Common::WriteStream *fh, int_hash_map_t::node_t **foo) { +void write_IntMapperNodePtr(Common::WriteStream *fh, IntMapper::Node **foo) {  	if (!(*foo)) {  		WSprintf(fh, "\\null");  	} else { -		WSprintf(fh,"[\n%d=>%d\n", (*foo)->name, (*foo)->value); +		WSprintf(fh,"[\n%d=>%d\n", (*foo)->key, (*foo)->idx);  		if ((*foo)->next) { -			%CFSMLWRITE int_hash_map_node_tp &((*foo)->next) INTO fh; +			%CFSMLWRITE IntMapperNodePtr &((*foo)->next) INTO fh;  		} else  			WSprintf(fh, "L");  		WSprintf(fh, "]");  	}  } -int read_int_hash_map_node_tp(Common::SeekableReadStream *fh, int_hash_map_t::node_t **foo, const char *lastval, int *line, int *hiteof) { +int read_IntMapperNodePtr(Common::SeekableReadStream *fh, IntMapper::Node **foo, const char *lastval, int *line, int *hiteof) {  	static char buffer[80];  	if (lastval[0] == '\\') {  		*foo = NULL; // No hash map node  	} else { -		*foo = (int_hash_map_t::node_t*)malloc(sizeof(int_hash_map_t::node_t)); +		*foo = (IntMapper::Node*)malloc(sizeof(IntMapper::Node));  		if (lastval[0] != '[') {  			sciprintf("Expected opening bracket in hash_map_node_t on line %d\n", *line);  			return 1; @@ -581,12 +555,10 @@ int read_int_hash_map_node_tp(Common::SeekableReadStream *fh, int_hash_map_t::no  			} // HACK: deliberately no else clause here  			if (buffer[0] == ']')  {  				break; -			} -			else if (buffer[0] == '[') { -				if (read_int_hash_map_node_tp(fh, &((*foo)->next), buffer, line, hiteof)) +			} else if (buffer[0] == '[') { +				if (read_IntMapperNodePtr(fh, &((*foo)->next), buffer, line, hiteof))  					return 1; -			} -			else if (sscanf(buffer, "%d=>%d", &((*foo)->name), &((*foo)->value))<2) { +			} else if (sscanf(buffer, "%d=>%d", &((*foo)->key), &((*foo)->idx))<2) {  				sciprintf("Error parsing hash_map_node_t on line %d\n", *line);  				return 1;  			} @@ -615,6 +587,32 @@ int read_menubar_tp(Common::SeekableReadStream *fh, menubar_t **foo, const char  	return *hiteof;  } +static struct { +	int type; +	const char *name; +} mem_obj_string_names[] = { +	{MEM_OBJ_INVALID, "INVALID"}, +	{MEM_OBJ_SCRIPT, "SCRIPT"}, +	{MEM_OBJ_CLONES, "CLONES"}, +	{MEM_OBJ_LOCALS, "LOCALS"}, +	{MEM_OBJ_STACK, "STACK"}, +	{MEM_OBJ_SYS_STRINGS,"SYS_STRINGS"}, +	{MEM_OBJ_LISTS,"LISTS"}, +	{MEM_OBJ_NODES,"NODES"}, +	{MEM_OBJ_HUNK,"HUNK"}, +	{MEM_OBJ_DYNMEM,"DYNMEM"}}; + +int mem_obj_string_to_enum(const char *str) { +	int i; + +	for (i = 0; i <= MEM_OBJ_MAX; i++) { +		if (!scumm_stricmp(mem_obj_string_names[i].name, str)) +			return i; +	} + +	return -1; +} +  void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	WSprintf(fh, "%s\n", mem_obj_string_names[foo->type].name);  	%CFSMLWRITE int &foo->segmgr_id INTO fh; diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 1ecb65b5e6..363f519759 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -200,17 +200,17 @@ int read_menubar_tp(Common::SeekableReadStream *fh, menubar_t **foo, const char  void write_mem_obj_tp(Common::WriteStream *fh, mem_obj_t **foo);  int read_mem_obj_tp(Common::SeekableReadStream *fh, mem_obj_t **foo, const char *lastval, int *line, int *hiteof); -void write_int_hash_map_tp(Common::WriteStream *fh, int_hash_map_t **foo); -int read_int_hash_map_tp(Common::SeekableReadStream *fh, int_hash_map_t **foo, const char *lastval, int *line, int *hiteof); -  void write_songlib_t(Common::WriteStream *fh, songlib_t *foo);  int read_songlib_t(Common::SeekableReadStream *fh, songlib_t *foo, const char *lastval, int *line, int *hiteof); -void write_int_hash_map_node_tp(Common::WriteStream *fh, int_hash_map_t::node_t **foo); -int read_int_hash_map_node_tp(Common::SeekableReadStream *fh, int_hash_map_t::node_t **foo, const char *lastval, int *line, int *hiteof); -  int read_song_tp(Common::SeekableReadStream *fh, song_t **foo, const char *lastval, int *line, int *hiteof); +void write_IntMapperPtr(Common::WriteStream *fh, IntMapper **foo); +int read_IntMapperPtr(Common::SeekableReadStream *fh, IntMapper **foo, const char *lastval, int *line, int *hiteof); + +void write_IntMapperNodePtr(Common::WriteStream *fh, IntMapper::Node **foo); +int read_IntMapperNodePtr(Common::SeekableReadStream *fh, IntMapper::Node **foo, const char *lastval, int *line, int *hiteof); +  void write_SegManagerPtr(Common::WriteStream *fh, SegManager **foo);  int read_SegManagerPtr(Common::SeekableReadStream *fh, SegManager **foo, const char *lastval, int *line, int *hiteof); @@ -480,10 +480,6 @@ static void _cfsml_write_list_entry_t(Common::WriteStream *fh, list_entry_t* sav  static int _cfsml_read_list_entry_t(Common::SeekableReadStream *fh, list_entry_t* save_struc, const char *lastval, int *line, int *hiteof);  #line 383 "engines/sci/engine/savegame.cfsml" -static void _cfsml_write_int_hash_map_t(Common::WriteStream *fh, int_hash_map_t* save_struc); -static int _cfsml_read_int_hash_map_t(Common::SeekableReadStream *fh, int_hash_map_t* save_struc, const char *lastval, int *line, int *hiteof); - -#line 383 "engines/sci/engine/savegame.cfsml"  static void _cfsml_write_SegManager(Common::WriteStream *fh, SegManager* save_struc);  static int _cfsml_read_SegManager(Common::SeekableReadStream *fh, SegManager* save_struc, const char *lastval, int *line, int *hiteof); @@ -556,6 +552,10 @@ static void _cfsml_write_SavegameMetadata(Common::WriteStream *fh, SavegameMetad  static int _cfsml_read_SavegameMetadata(Common::SeekableReadStream *fh, SavegameMetadata* save_struc, const char *lastval, int *line, int *hiteof);  #line 383 "engines/sci/engine/savegame.cfsml" +static void _cfsml_write_IntMapper(Common::WriteStream *fh, IntMapper* save_struc); +static int _cfsml_read_IntMapper(Common::SeekableReadStream *fh, IntMapper* save_struc, const char *lastval, int *line, int *hiteof); + +#line 383 "engines/sci/engine/savegame.cfsml"  static void _cfsml_write_menu_t(Common::WriteStream *fh, menu_t* save_struc);  static int _cfsml_read_menu_t(Common::SeekableReadStream *fh, menu_t* save_struc, const char *lastval, int *line, int *hiteof); @@ -1141,118 +1141,12 @@ _cfsml_read_list_entry_t(Common::SeekableReadStream *fh, list_entry_t* save_stru  #line 395 "engines/sci/engine/savegame.cfsml"  static void -_cfsml_write_int_hash_map_t(Common::WriteStream *fh, int_hash_map_t* save_struc) -{ -#line 412 "engines/sci/engine/savegame.cfsml" -	WSprintf(fh, "{\n"); -	WSprintf(fh, "base_value = "); -	_cfsml_write_int(fh, (int*) &(save_struc->base_value)); -	WSprintf(fh, "\n"); -	WSprintf(fh, "nodes = "); -	int min, max; -	min = max = DCS_INT_HASH_MAX+1; -#line 439 "engines/sci/engine/savegame.cfsml" -	WSprintf(fh, "[%d][\n", max); -	for (int i = 0; i < min; i++) { -		write_int_hash_map_node_tp(fh, &(save_struc->nodes[i])); -		WSprintf(fh, "\n"); -	} -	WSprintf(fh, "]"); -	WSprintf(fh, "\n"); -	WSprintf(fh, "}"); -} - -#line 486 "engines/sci/engine/savegame.cfsml" -static int -_cfsml_read_int_hash_map_t(Common::SeekableReadStream *fh, int_hash_map_t* save_struc, const char *lastval, int *line, int *hiteof) -{ -#line 541 "engines/sci/engine/savegame.cfsml" -	char *token; -	int assignment, closed; - -	if (strcmp(lastval, "{")) { -		_cfsml_error("Reading record int_hash_map_t; expected opening braces in line %d, got \"%s\"\n", *line, lastval); -		return CFSML_FAILURE; -	}; -	closed = 0; -	do { -		const char *value; -		token = _cfsml_get_identifier(fh, line, hiteof, &assignment); - -		if (!token) { -			_cfsml_error("Expected token at line %d\n", *line); -			return CFSML_FAILURE; -		} -		if (!assignment) { -			if (!strcmp(token, "}")) -				closed = 1; -			else { -				_cfsml_error("Expected assignment or closing braces in line %d\n", *line); -				return CFSML_FAILURE; -			} -		} else { -			value = ""; -			while (!value || !strcmp(value, "")) -				value = _cfsml_get_value(fh, line, hiteof); -			if (!value) { -				_cfsml_error("Expected token at line %d\n", *line); -				return CFSML_FAILURE; -			} -				if (!strcmp(token, "base_value")) { -#line 690 "engines/sci/engine/savegame.cfsml" -				if (_cfsml_read_int(fh, (int*) &(save_struc->base_value), value, line, hiteof)) { -					_cfsml_error("Token expected by _cfsml_read_int() for base_value at line %d\n", *line); -					return CFSML_FAILURE; -				} -			} else -				if (!strcmp(token, "nodes")) { -#line 604 "engines/sci/engine/savegame.cfsml" -			if ((value[0] != '[') || (value[strlen(value) - 1] != '[')) { -				_cfsml_error("Opening brackets expected at line %d\n", *line); -				return CFSML_FAILURE; -			} -			int max,done,i; -			// Prepare to restore static array -			max = DCS_INT_HASH_MAX+1; -#line 639 "engines/sci/engine/savegame.cfsml" -			done = i = 0; -			do { -			if (!(value = _cfsml_get_identifier(fh, line, hiteof, NULL))) { -#line 647 "engines/sci/engine/savegame.cfsml" -				_cfsml_error("Token expected at line %d\n", *line); -				return 1; -			} -			if (strcmp(value, "]")) { -				if (i == max) { -					_cfsml_error("More elements than space available (%d) in '%s' at line %d\n", max, token, *line); -					return CFSML_FAILURE; -				} -				if (read_int_hash_map_node_tp(fh, &(save_struc->nodes[i++]), value, line, hiteof)) { -					_cfsml_error("Token expected by read_int_hash_map_node_tp() for nodes[i++] at line %d\n", *line); -					return CFSML_FAILURE; -				} -			} else -				done = 1; -			} while (!done); -			} else -#line 699 "engines/sci/engine/savegame.cfsml" -			{ -				_cfsml_error("int_hash_map_t: Assignment to invalid identifier '%s' in line %d\n", token, *line); -				return CFSML_FAILURE; -			} -		} -	} while (!closed); // Until closing braces are hit -	return CFSML_SUCCESS; -} - -#line 395 "engines/sci/engine/savegame.cfsml" -static void  _cfsml_write_SegManager(Common::WriteStream *fh, SegManager* save_struc)  {  #line 412 "engines/sci/engine/savegame.cfsml"  	WSprintf(fh, "{\n");  	WSprintf(fh, "id_seg_map = "); -	write_int_hash_map_tp(fh, (int_hash_map_t **) &(save_struc->id_seg_map)); +	write_IntMapperPtr(fh, (IntMapper **) &(save_struc->id_seg_map));  	WSprintf(fh, "\n");  	WSprintf(fh, "heap = ");  	int min, max; @@ -1332,8 +1226,8 @@ _cfsml_read_SegManager(Common::SeekableReadStream *fh, SegManager* save_struc, c  			}  				if (!strcmp(token, "id_seg_map")) {  #line 690 "engines/sci/engine/savegame.cfsml" -				if (read_int_hash_map_tp(fh, (int_hash_map_t **) &(save_struc->id_seg_map), value, line, hiteof)) { -					_cfsml_error("Token expected by read_int_hash_map_tp() for id_seg_map at line %d\n", *line); +				if (read_IntMapperPtr(fh, (IntMapper **) &(save_struc->id_seg_map), value, line, hiteof)) { +					_cfsml_error("Token expected by read_IntMapperPtr() for id_seg_map at line %d\n", *line);  					return CFSML_FAILURE;  				}  			} else @@ -3152,6 +3046,112 @@ _cfsml_read_SavegameMetadata(Common::SeekableReadStream *fh, SavegameMetadata* s  #line 395 "engines/sci/engine/savegame.cfsml"  static void +_cfsml_write_IntMapper(Common::WriteStream *fh, IntMapper* save_struc) +{ +#line 412 "engines/sci/engine/savegame.cfsml" +	WSprintf(fh, "{\n"); +	WSprintf(fh, "base_value = "); +	_cfsml_write_int(fh, (int*) &(save_struc->base_value)); +	WSprintf(fh, "\n"); +	WSprintf(fh, "nodes = "); +	int min, max; +	min = max = DCS_INT_HASH_MAX; +#line 439 "engines/sci/engine/savegame.cfsml" +	WSprintf(fh, "[%d][\n", max); +	for (int i = 0; i < min; i++) { +		write_IntMapperNodePtr(fh, &(save_struc->nodes[i])); +		WSprintf(fh, "\n"); +	} +	WSprintf(fh, "]"); +	WSprintf(fh, "\n"); +	WSprintf(fh, "}"); +} + +#line 486 "engines/sci/engine/savegame.cfsml" +static int +_cfsml_read_IntMapper(Common::SeekableReadStream *fh, IntMapper* save_struc, const char *lastval, int *line, int *hiteof) +{ +#line 541 "engines/sci/engine/savegame.cfsml" +	char *token; +	int assignment, closed; + +	if (strcmp(lastval, "{")) { +		_cfsml_error("Reading record IntMapper; expected opening braces in line %d, got \"%s\"\n", *line, lastval); +		return CFSML_FAILURE; +	}; +	closed = 0; +	do { +		const char *value; +		token = _cfsml_get_identifier(fh, line, hiteof, &assignment); + +		if (!token) { +			_cfsml_error("Expected token at line %d\n", *line); +			return CFSML_FAILURE; +		} +		if (!assignment) { +			if (!strcmp(token, "}")) +				closed = 1; +			else { +				_cfsml_error("Expected assignment or closing braces in line %d\n", *line); +				return CFSML_FAILURE; +			} +		} else { +			value = ""; +			while (!value || !strcmp(value, "")) +				value = _cfsml_get_value(fh, line, hiteof); +			if (!value) { +				_cfsml_error("Expected token at line %d\n", *line); +				return CFSML_FAILURE; +			} +				if (!strcmp(token, "base_value")) { +#line 690 "engines/sci/engine/savegame.cfsml" +				if (_cfsml_read_int(fh, (int*) &(save_struc->base_value), value, line, hiteof)) { +					_cfsml_error("Token expected by _cfsml_read_int() for base_value at line %d\n", *line); +					return CFSML_FAILURE; +				} +			} else +				if (!strcmp(token, "nodes")) { +#line 604 "engines/sci/engine/savegame.cfsml" +			if ((value[0] != '[') || (value[strlen(value) - 1] != '[')) { +				_cfsml_error("Opening brackets expected at line %d\n", *line); +				return CFSML_FAILURE; +			} +			int max,done,i; +			// Prepare to restore static array +			max = DCS_INT_HASH_MAX; +#line 639 "engines/sci/engine/savegame.cfsml" +			done = i = 0; +			do { +			if (!(value = _cfsml_get_identifier(fh, line, hiteof, NULL))) { +#line 647 "engines/sci/engine/savegame.cfsml" +				_cfsml_error("Token expected at line %d\n", *line); +				return 1; +			} +			if (strcmp(value, "]")) { +				if (i == max) { +					_cfsml_error("More elements than space available (%d) in '%s' at line %d\n", max, token, *line); +					return CFSML_FAILURE; +				} +				if (read_IntMapperNodePtr(fh, &(save_struc->nodes[i++]), value, line, hiteof)) { +					_cfsml_error("Token expected by read_IntMapperNodePtr() for nodes[i++] at line %d\n", *line); +					return CFSML_FAILURE; +				} +			} else +				done = 1; +			} while (!done); +			} else +#line 699 "engines/sci/engine/savegame.cfsml" +			{ +				_cfsml_error("IntMapper: Assignment to invalid identifier '%s' in line %d\n", token, *line); +				return CFSML_FAILURE; +			} +		} +	} while (!closed); // Until closing braces are hit +	return CFSML_SUCCESS; +} + +#line 395 "engines/sci/engine/savegame.cfsml" +static void  _cfsml_write_menu_t(Common::WriteStream *fh, menu_t* save_struc)  {  #line 412 "engines/sci/engine/savegame.cfsml" @@ -3788,7 +3788,7 @@ _cfsml_write_script_t(Common::WriteStream *fh, script_t* save_struc)  	_cfsml_write_size_t(fh, (size_t*) &(save_struc->heap_size));  	WSprintf(fh, "\n");  	WSprintf(fh, "obj_indices = "); -	write_int_hash_map_tp(fh, (int_hash_map_t **) &(save_struc->obj_indices)); +	write_IntMapperPtr(fh, (IntMapper **) &(save_struc->obj_indices));  	WSprintf(fh, "\n");  	WSprintf(fh, "exports_nr = ");  	_cfsml_write_int(fh, (int*) &(save_struc->exports_nr)); @@ -3896,8 +3896,8 @@ _cfsml_read_script_t(Common::SeekableReadStream *fh, script_t* save_struc, const  			} else  				if (!strcmp(token, "obj_indices")) {  #line 690 "engines/sci/engine/savegame.cfsml" -				if (read_int_hash_map_tp(fh, (int_hash_map_t **) &(save_struc->obj_indices), value, line, hiteof)) { -					_cfsml_error("Token expected by read_int_hash_map_tp() for obj_indices at line %d\n", *line); +				if (read_IntMapperPtr(fh, (IntMapper **) &(save_struc->obj_indices), value, line, hiteof)) { +					_cfsml_error("Token expected by read_IntMapperPtr() for obj_indices at line %d\n", *line);  					return CFSML_FAILURE;  				}  			} else @@ -4089,48 +4089,13 @@ int read_songlib_t(Common::SeekableReadStream *fh, songlib_t *songlib, const cha  	return 0;  } -static struct { -	int type; -	const char *name; -} mem_obj_string_names[] = { -	{MEM_OBJ_INVALID, "INVALID"}, -	{MEM_OBJ_SCRIPT, "SCRIPT"}, -	{MEM_OBJ_CLONES, "CLONES"}, -	{MEM_OBJ_LOCALS, "LOCALS"}, -	{MEM_OBJ_STACK, "STACK"}, -	{MEM_OBJ_SYS_STRINGS,"SYS_STRINGS"}, -	{MEM_OBJ_LISTS,"LISTS"}, -	{MEM_OBJ_NODES,"NODES"}, -	{MEM_OBJ_HUNK,"HUNK"}, -	{MEM_OBJ_DYNMEM,"DYNMEM"}}; - -int mem_obj_string_to_enum(const char *str) { -	int i; - -	for (i = 0; i <= MEM_OBJ_MAX; i++) { -		if (!scumm_stricmp(mem_obj_string_names[i].name, str)) -			return i; -	} - -	return -1; -} - -void write_int_hash_map_tp(Common::WriteStream *fh, int_hash_map_t **foo) { -#line 819 "engines/sci/engine/savegame.cfsml" -// Auto-generated CFSML data writer code -	_cfsml_write_int_hash_map_t(fh, *foo); -	WSprintf(fh, "\n"); -// End of auto-generated CFSML data writer code -#line 523 "engines/sci/engine/savegame.cfsml" -} -  void write_song_tp(Common::WriteStream *fh, song_t **foo) {  #line 819 "engines/sci/engine/savegame.cfsml"  // Auto-generated CFSML data writer code  	_cfsml_write_song_t(fh, *foo);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 527 "engines/sci/engine/savegame.cfsml" +#line 497 "engines/sci/engine/savegame.cfsml"  }  song_iterator_t *build_iterator(EngineState *s, int song_nr, int type, songit_id_t id); @@ -4164,15 +4129,24 @@ int read_song_tp(Common::SeekableReadStream *fh, song_t **foo, const char *lastv  		}  	}  // End of auto-generated CFSML data reader code -#line 537 "engines/sci/engine/savegame.cfsml" +#line 507 "engines/sci/engine/savegame.cfsml"  	(*foo)->delay = 0;  	(*foo)->it = NULL;  	(*foo)->next_playing = (*foo)->next_stopping = (*foo)->next = NULL;  	return 0;  } -int read_int_hash_map_tp(Common::SeekableReadStream *fh, int_hash_map_t **foo, const char *lastval, int *line, int *hiteof) { -	*foo = new int_hash_map_t; +void write_IntMapperPtr(Common::WriteStream *fh, IntMapper **foo) { +#line 819 "engines/sci/engine/savegame.cfsml" +// Auto-generated CFSML data writer code +	_cfsml_write_IntMapper(fh, *foo); +	WSprintf(fh, "\n"); +// End of auto-generated CFSML data writer code +#line 515 "engines/sci/engine/savegame.cfsml" +} + +int read_IntMapperPtr(Common::SeekableReadStream *fh, IntMapper **foo, const char *lastval, int *line, int *hiteof) { +	*foo = new IntMapper();  // Auto-generated CFSML data reader code  #line 763 "engines/sci/engine/savegame.cfsml"  	{ @@ -4182,7 +4156,7 @@ int read_int_hash_map_tp(Common::SeekableReadStream *fh, int_hash_map_t **foo, c  		const char *_cfsml_inp = lastval;  		{  #line 789 "engines/sci/engine/savegame.cfsml" -			_cfsml_error = _cfsml_read_int_hash_map_t(fh, (*foo), _cfsml_inp, &(*line), &_cfsml_eof); +			_cfsml_error = _cfsml_read_IntMapper(fh, (*foo), _cfsml_inp, &(*line), &_cfsml_eof);  		}  #line 794 "engines/sci/engine/savegame.cfsml"  		*hiteof = _cfsml_error; @@ -4197,36 +4171,36 @@ int read_int_hash_map_tp(Common::SeekableReadStream *fh, int_hash_map_t **foo, c  		}  	}  // End of auto-generated CFSML data reader code -#line 546 "engines/sci/engine/savegame.cfsml" +#line 520 "engines/sci/engine/savegame.cfsml"  	(*foo)->holes = NULL;  	return 0;  } -void write_int_hash_map_node_tp(Common::WriteStream *fh, int_hash_map_t::node_t **foo) { +void write_IntMapperNodePtr(Common::WriteStream *fh, IntMapper::Node **foo) {  	if (!(*foo)) {  		WSprintf(fh, "\\null");  	} else { -		WSprintf(fh,"[\n%d=>%d\n", (*foo)->name, (*foo)->value); +		WSprintf(fh,"[\n%d=>%d\n", (*foo)->key, (*foo)->idx);  		if ((*foo)->next) {  #line 819 "engines/sci/engine/savegame.cfsml"  // Auto-generated CFSML data writer code -	write_int_hash_map_node_tp(fh, &((*foo)->next)); +	write_IntMapperNodePtr(fh, &((*foo)->next));  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 557 "engines/sci/engine/savegame.cfsml" +#line 531 "engines/sci/engine/savegame.cfsml"  		} else  			WSprintf(fh, "L");  		WSprintf(fh, "]");  	}  } -int read_int_hash_map_node_tp(Common::SeekableReadStream *fh, int_hash_map_t::node_t **foo, const char *lastval, int *line, int *hiteof) { +int read_IntMapperNodePtr(Common::SeekableReadStream *fh, IntMapper::Node **foo, const char *lastval, int *line, int *hiteof) {  	static char buffer[80];  	if (lastval[0] == '\\') {  		*foo = NULL; // No hash map node  	} else { -		*foo = (int_hash_map_t::node_t*)malloc(sizeof(int_hash_map_t::node_t)); +		*foo = (IntMapper::Node*)malloc(sizeof(IntMapper::Node));  		if (lastval[0] != '[') {  			sciprintf("Expected opening bracket in hash_map_node_t on line %d\n", *line);  			return 1; @@ -4241,12 +4215,10 @@ int read_int_hash_map_node_tp(Common::SeekableReadStream *fh, int_hash_map_t::no  			} // HACK: deliberately no else clause here  			if (buffer[0] == ']')  {  				break; -			} -			else if (buffer[0] == '[') { -				if (read_int_hash_map_node_tp(fh, &((*foo)->next), buffer, line, hiteof)) +			} else if (buffer[0] == '[') { +				if (read_IntMapperNodePtr(fh, &((*foo)->next), buffer, line, hiteof))  					return 1; -			} -			else if (sscanf(buffer, "%d=>%d", &((*foo)->name), &((*foo)->value))<2) { +			} else if (sscanf(buffer, "%d=>%d", &((*foo)->key), &((*foo)->idx))<2) {  				sciprintf("Error parsing hash_map_node_t on line %d\n", *line);  				return 1;  			} @@ -4263,7 +4235,7 @@ void write_menubar_tp(Common::WriteStream *fh, menubar_t **foo) {  	_cfsml_write_menubar_t(fh, (*foo));  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 602 "engines/sci/engine/savegame.cfsml" +#line 574 "engines/sci/engine/savegame.cfsml"  	} else { // Nothing to write  		WSprintf(fh, "\\null\\");  	} @@ -4299,11 +4271,37 @@ int read_menubar_tp(Common::SeekableReadStream *fh, menubar_t **foo, const char  		}  	}  // End of auto-generated CFSML data reader code -#line 614 "engines/sci/engine/savegame.cfsml" +#line 586 "engines/sci/engine/savegame.cfsml"  	}  	return *hiteof;  } +static struct { +	int type; +	const char *name; +} mem_obj_string_names[] = { +	{MEM_OBJ_INVALID, "INVALID"}, +	{MEM_OBJ_SCRIPT, "SCRIPT"}, +	{MEM_OBJ_CLONES, "CLONES"}, +	{MEM_OBJ_LOCALS, "LOCALS"}, +	{MEM_OBJ_STACK, "STACK"}, +	{MEM_OBJ_SYS_STRINGS,"SYS_STRINGS"}, +	{MEM_OBJ_LISTS,"LISTS"}, +	{MEM_OBJ_NODES,"NODES"}, +	{MEM_OBJ_HUNK,"HUNK"}, +	{MEM_OBJ_DYNMEM,"DYNMEM"}}; + +int mem_obj_string_to_enum(const char *str) { +	int i; + +	for (i = 0; i <= MEM_OBJ_MAX; i++) { +		if (!scumm_stricmp(mem_obj_string_names[i].name, str)) +			return i; +	} + +	return -1; +} +  void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	WSprintf(fh, "%s\n", mem_obj_string_names[foo->type].name);  #line 819 "engines/sci/engine/savegame.cfsml" @@ -4311,7 +4309,7 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	_cfsml_write_int(fh, &foo->segmgr_id);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 621 "engines/sci/engine/savegame.cfsml" +#line 619 "engines/sci/engine/savegame.cfsml"  	switch (foo->type) {  	case MEM_OBJ_SCRIPT:  #line 819 "engines/sci/engine/savegame.cfsml" @@ -4319,7 +4317,7 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	_cfsml_write_script_t(fh, &foo->data.script);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 624 "engines/sci/engine/savegame.cfsml" +#line 622 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_CLONES:  #line 819 "engines/sci/engine/savegame.cfsml" @@ -4327,7 +4325,7 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	_cfsml_write_clone_table_t(fh, &foo->data.clones);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 627 "engines/sci/engine/savegame.cfsml" +#line 625 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_LOCALS:  #line 819 "engines/sci/engine/savegame.cfsml" @@ -4335,7 +4333,7 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	_cfsml_write_local_variables_t(fh, &foo->data.locals);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 630 "engines/sci/engine/savegame.cfsml" +#line 628 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_SYS_STRINGS:  #line 819 "engines/sci/engine/savegame.cfsml" @@ -4343,7 +4341,7 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	_cfsml_write_sys_strings_t(fh, &foo->data.sys_strings);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 633 "engines/sci/engine/savegame.cfsml" +#line 631 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_STACK:  #line 819 "engines/sci/engine/savegame.cfsml" @@ -4351,7 +4349,7 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	_cfsml_write_int(fh, &foo->data.stack.nr);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 636 "engines/sci/engine/savegame.cfsml" +#line 634 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_HUNK:  		break; @@ -4361,7 +4359,7 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	_cfsml_write_list_table_t(fh, &foo->data.lists);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 641 "engines/sci/engine/savegame.cfsml" +#line 639 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_NODES:  #line 819 "engines/sci/engine/savegame.cfsml" @@ -4369,7 +4367,7 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	_cfsml_write_node_table_t(fh, &foo->data.nodes);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 644 "engines/sci/engine/savegame.cfsml" +#line 642 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_DYNMEM:  #line 819 "engines/sci/engine/savegame.cfsml" @@ -4377,7 +4375,7 @@ void write_mem_obj_t(Common::WriteStream *fh, mem_obj_t *foo) {  	_cfsml_write_dynmem_t(fh, &foo->data.dynmem);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 647 "engines/sci/engine/savegame.cfsml" +#line 645 "engines/sci/engine/savegame.cfsml"  	break;  	default:  	break; @@ -4417,7 +4415,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l  		}  	}  // End of auto-generated CFSML data reader code -#line 661 "engines/sci/engine/savegame.cfsml" +#line 659 "engines/sci/engine/savegame.cfsml"  	switch (foo->type) {  	case MEM_OBJ_SCRIPT:  // Auto-generated CFSML data reader code @@ -4446,7 +4444,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l  		}  	}  // End of auto-generated CFSML data reader code -#line 664 "engines/sci/engine/savegame.cfsml" +#line 662 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_CLONES:  // Auto-generated CFSML data reader code @@ -4475,7 +4473,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l  		}  	}  // End of auto-generated CFSML data reader code -#line 667 "engines/sci/engine/savegame.cfsml" +#line 665 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_LOCALS:  // Auto-generated CFSML data reader code @@ -4504,7 +4502,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l  		}  	}  // End of auto-generated CFSML data reader code -#line 670 "engines/sci/engine/savegame.cfsml" +#line 668 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_SYS_STRINGS:  // Auto-generated CFSML data reader code @@ -4533,7 +4531,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l  		}  	}  // End of auto-generated CFSML data reader code -#line 673 "engines/sci/engine/savegame.cfsml" +#line 671 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_LISTS:  // Auto-generated CFSML data reader code @@ -4562,7 +4560,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l  		}  	}  // End of auto-generated CFSML data reader code -#line 676 "engines/sci/engine/savegame.cfsml" +#line 674 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_NODES:  // Auto-generated CFSML data reader code @@ -4591,7 +4589,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l  		}  	}  // End of auto-generated CFSML data reader code -#line 679 "engines/sci/engine/savegame.cfsml" +#line 677 "engines/sci/engine/savegame.cfsml"  	break;  	case MEM_OBJ_STACK:  // Auto-generated CFSML data reader code @@ -4620,7 +4618,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l  		}  	}  // End of auto-generated CFSML data reader code -#line 682 "engines/sci/engine/savegame.cfsml" +#line 680 "engines/sci/engine/savegame.cfsml"  	foo->data.stack.entries = (reg_t *)sci_calloc(foo->data.stack.nr, sizeof(reg_t));  	break;  	case MEM_OBJ_HUNK: @@ -4653,7 +4651,7 @@ int read_mem_obj_t(Common::SeekableReadStream *fh, mem_obj_t *foo, const char *l  		}  	}  // End of auto-generated CFSML data reader code -#line 689 "engines/sci/engine/savegame.cfsml" +#line 687 "engines/sci/engine/savegame.cfsml"  	break;  	default:  		break; @@ -4669,7 +4667,7 @@ void write_mem_obj_tp(Common::WriteStream *fh, mem_obj_t **foo) {  	write_mem_obj_t(fh, (*foo));  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 700 "engines/sci/engine/savegame.cfsml" +#line 698 "engines/sci/engine/savegame.cfsml"  	} else { // Nothing to write  		WSprintf(fh, "\\null\\");  	} @@ -4704,7 +4702,7 @@ int read_mem_obj_tp(Common::SeekableReadStream *fh, mem_obj_t **foo, const char  		}  	}  // End of auto-generated CFSML data reader code -#line 711 "engines/sci/engine/savegame.cfsml" +#line 709 "engines/sci/engine/savegame.cfsml"  		return *hiteof;  	}  	return 0; @@ -4716,13 +4714,13 @@ void write_SegManagerPtr(Common::WriteStream *fh, SegManager **foo) {  	_cfsml_write_bool(fh, &((*foo)->isSci1_1));  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 718 "engines/sci/engine/savegame.cfsml" +#line 716 "engines/sci/engine/savegame.cfsml"  #line 819 "engines/sci/engine/savegame.cfsml"  // Auto-generated CFSML data writer code  	_cfsml_write_SegManager(fh, *foo);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 719 "engines/sci/engine/savegame.cfsml" +#line 717 "engines/sci/engine/savegame.cfsml"  }  int read_SegManagerPtr(Common::SeekableReadStream *fh, SegManager **foo, const char *lastval, int *line, int *hiteof) { @@ -4753,7 +4751,7 @@ int read_SegManagerPtr(Common::SeekableReadStream *fh, SegManager **foo, const c  		}  	}  // End of auto-generated CFSML data reader code -#line 726 "engines/sci/engine/savegame.cfsml" +#line 724 "engines/sci/engine/savegame.cfsml"  	*foo = new SegManager(sci11);  	token = _cfsml_get_identifier(fh, line, hiteof, &assignment);  // Auto-generated CFSML data reader code @@ -4780,7 +4778,7 @@ int read_SegManagerPtr(Common::SeekableReadStream *fh, SegManager **foo, const c  		}  	}  // End of auto-generated CFSML data reader code -#line 729 "engines/sci/engine/savegame.cfsml" +#line 727 "engines/sci/engine/savegame.cfsml"  	return 0;  } @@ -4832,13 +4830,13 @@ int gamestate_save(EngineState *s, Common::WriteStream *fh, const char* savename  	_cfsml_write_SavegameMetadata(fh, meta);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 776 "engines/sci/engine/savegame.cfsml" +#line 774 "engines/sci/engine/savegame.cfsml"  #line 819 "engines/sci/engine/savegame.cfsml"  // Auto-generated CFSML data writer code  	_cfsml_write_EngineState(fh, s);  	WSprintf(fh, "\n");  // End of auto-generated CFSML data writer code -#line 777 "engines/sci/engine/savegame.cfsml" +#line 775 "engines/sci/engine/savegame.cfsml"  	delete meta; @@ -5149,7 +5147,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {  		}  	}  // End of auto-generated CFSML data reader code -#line 1056 "engines/sci/engine/savegame.cfsml" +#line 1054 "engines/sci/engine/savegame.cfsml"  	if ((meta->savegame_version < FREESCI_MINIMUM_SAVEGAME_VERSION) ||  	    (meta->savegame_version > FREESCI_CURRENT_SAVEGAME_VERSION)) {  		if (meta->savegame_version < FREESCI_MINIMUM_SAVEGAME_VERSION) @@ -5204,7 +5202,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {  		}  	}  // End of auto-generated CFSML data reader code -#line 1079 "engines/sci/engine/savegame.cfsml" +#line 1077 "engines/sci/engine/savegame.cfsml"  	sfx_exit(&s->sound);  	_gamestate_unfrob(retval); @@ -5324,7 +5322,7 @@ bool get_savegame_metadata(Common::SeekableReadStream* stream, SavegameMetadata*  		}  	}  // End of auto-generated CFSML data reader code -#line 1167 "engines/sci/engine/savegame.cfsml" +#line 1165 "engines/sci/engine/savegame.cfsml"  	if (read_eof)  		return false; diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 7713ab6dd4..093542d8a1 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -54,11 +54,11 @@ namespace Sci {  #define INVALID_SCRIPT_ID -1  inline int SegManager::findFreeId(int *id) { -	char was_added = 0; +	bool was_added = false;  	int retval = 0;  	while (!was_added) { -		retval = id_seg_map->check_value(reserved_id, true, &was_added); +		retval = id_seg_map->checkKey(reserved_id, true, &was_added);  		*id = reserved_id--;  		if (reserved_id < -1000000)  			reserved_id = -10; @@ -82,9 +82,9 @@ SegManager::SegManager(bool sci1_1) {  	// Initialise memory count  	mem_allocated = 0; -	id_seg_map = new int_hash_map_t(); +	id_seg_map = new IntMapper();  	reserved_id = INVALID_SCRIPT_ID; -	id_seg_map->check_value(reserved_id, true);	// reserve 0 for seg_id +	id_seg_map->checkKey(reserved_id, true);	// reserve 0 for seg_id  	reserved_id--; // reserved_id runs in the reversed direction to make sure no one will use it.  	heap_size = DEFAULT_SCRIPTS; @@ -130,10 +130,10 @@ SegManager::~SegManager() {  //             seg_id - allocated segment id  mem_obj_t *SegManager::allocateScript(EngineState *s, int script_nr, int* seg_id) {  	int seg; -	char was_added; +	bool was_added;  	mem_obj_t* mem; -	seg = id_seg_map->check_value(script_nr, true, &was_added); +	seg = id_seg_map->checkKey(script_nr, true, &was_added);  	if (!was_added) {  		*seg_id = seg;  		return heap[*seg_id]; @@ -218,7 +218,7 @@ int SegManager::initialiseScript(mem_obj_t *mem, EngineState *s, int script_nr)  	scr->marked_as_deleted = 0;  	scr->relocated = 0; -	scr->obj_indices = new int_hash_map_t(); +	scr->obj_indices = new IntMapper();  	if (s->version >= SCI_VERSION(1, 001, 000))  		scr->heap_start = scr->buf + scr->script_size; @@ -233,7 +233,7 @@ int SegManager::deallocate(int seg, bool recursive) {  	VERIFY(check(seg), "invalid seg id");  	mobj = heap[seg]; -	id_seg_map->remove_value(mobj->segmgr_id); +	id_seg_map->removeKey(mobj->segmgr_id);  	switch (mobj->type) {  	case MEM_OBJ_SCRIPT: @@ -414,9 +414,7 @@ void SegManager::freeScript(mem_obj_t *mem) {  	}  	delete mem->data.script.obj_indices; -	if (NULL != mem->data.script.code) { -		free(mem->data.script.code); -	} +	free(mem->data.script.code);  }  // memory operations @@ -555,7 +553,7 @@ void SegManager::sm_put_heap(reg_t reg, int16 value) {  // return the seg if script_id is valid and in the map, else -1  int SegManager::segGet(int script_id) { -	return id_seg_map->check_value(script_id, false); +	return id_seg_map->checkKey(script_id, false);  }  // validate the seg @@ -883,7 +881,7 @@ object_t *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) {  	}  	temp = make_reg(obj_pos.segment, base); -	id = scr->obj_indices->check_value(base, true); +	id = scr->obj_indices->checkKey(base, true);  	scr->objects_nr++;  	obj = scr->objects + id; @@ -949,7 +947,7 @@ object_t *SegManager::scriptObjInit11(EngineState *s, reg_t obj_pos) {  		scr->objects = (object_t *)sci_realloc(scr->objects, sizeof(object_t) * scr->objects_allocated);  	} -	id = scr->obj_indices->check_value(obj_pos.offset, true); +	id = scr->obj_indices->checkKey(obj_pos.offset, true);  	scr->objects_nr++;  	obj = scr->objects + id; diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 31bad21398..a545fcd6f8 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -26,7 +26,7 @@  #ifndef _SCI_SEG_MANAGER_H  #define _SCI_SEG_MANAGER_H -#include "sci/engine/int_hashmap.h" +#include "sci/engine/intmap.h"  #include "sci/include/vm.h"  namespace Sci { @@ -397,7 +397,7 @@ public:  	int initialiseScript(mem_obj_t *mem, EngineState *s, int script_nr);  public: // TODO: make private -	int_hash_map_t *id_seg_map; // id - script id; seg - index of heap +	IntMapper *id_seg_map; // id - script id; seg - index of heap  	mem_obj_t **heap;  	int heap_size;		// size of the heap  	int reserved_id; diff --git a/engines/sci/include/vm.h b/engines/sci/include/vm.h index 1a720988de..d89b868e5a 100644 --- a/engines/sci/include/vm.h +++ b/engines/sci/include/vm.h @@ -33,7 +33,7 @@  #include "sci/include/sys_strings.h"  #include "sci/include/heapmgr.h" -#include "sci/engine/int_hashmap.h" +#include "sci/engine/intmap.h"  namespace Sci { @@ -111,7 +111,7 @@ struct class_t {  	reg_t reg; /* offset; script-relative offset, segment: 0 if not instantiated */  }; -#define RAW_GET_CLASS_INDEX(scr, reg) ((scr)->obj_indices->check_value(reg.offset, false)) +#define RAW_GET_CLASS_INDEX(scr, reg) ((scr)->obj_indices->checkKey(reg.offset, false))  #define RAW_IS_OBJECT(datablock) (getUInt16(((byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER)  #define IS_CLASS(obj) (obj->variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS) @@ -177,9 +177,6 @@ struct code_block_t { -//#define VM_OBJECT_SET_INDEX(ptr, index) { ((byte *) (ptr))[0] = (index) & 0xff; ((byte *) (ptr))[1] = ((index) >> 8) & 0xff; } -//#define VM_OBJECT_GET_INDEX(scr, reg) (int_hash_map_check_value(scr->obj_indices, reg.offset, 0, NULL)) -  struct script_t {  	int nr; /* Script number */  	byte* buf; /* Static data buffer, or NULL if not used */ @@ -191,7 +188,7 @@ struct script_t {  	byte *heap_start; /* Start of heap if SCI1.1, NULL otherwise */  	uint16 *export_table; /* Abs. offset of the export table or 0 if not present */ -	int_hash_map_t *obj_indices; +	IntMapper *obj_indices;  	int exports_nr; /* Number of entries in the exports table */  	int synonyms_nr; /* Number of entries in the synonyms block */ diff --git a/engines/sci/module.mk b/engines/sci/module.mk index 52813ffd05..876a36911c 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -10,7 +10,7 @@ MODULE_OBJS = \  	engine/game.o \  	engine/gc.o \  	engine/grammar.o \ -	engine/int_hashmap.o \ +	engine/intmap.o \  	engine/kernel.o \  	engine/kevent.o \  	engine/kfile.o \ | 
