GLK: COMPREHEND: Making comprehend game derive from game info

This commit is contained in:
Paul Gilbert 2020-05-29 12:00:47 -07:00
parent 14cf02cc1b
commit b0fe096225
15 changed files with 513 additions and 403 deletions

View File

@ -158,6 +158,7 @@ void Comprehend::runGame() {
comprehend_load_game(game);
comprehend_play_game(game);
delete game;
deinitialize();
}

View File

@ -39,7 +39,7 @@ namespace Comprehend {
#define PATH_MAX 256
struct game_info;
struct GameInfo;
struct game_state;
#define EXTRA_STRING_TABLE(x) (0x8200 | (x))

View File

@ -45,9 +45,9 @@ word *dict_find_word_by_string(ComprehendGame *game,
if (!string)
return NULL;
for (i = 0; i < game->info->_nr_words; i++)
if (word_match(&game->info->_words[i], string))
return &game->info->_words[i];
for (i = 0; i < game->_nr_words; i++)
if (word_match(&game->_words[i], string))
return &game->_words[i];
return NULL;
}
@ -57,10 +57,10 @@ struct word *dict_find_word_by_index_type(ComprehendGame *game,
{
uint i;
for (i = 0; i < game->info->_nr_words; i++) {
if (game->info->_words[i]._index == index &&
game->info->_words[i]._type == type)
return &game->info->_words[i];
for (i = 0; i < game->_nr_words; i++) {
if (game->_words[i]._index == index &&
game->_words[i]._type == type)
return &game->_words[i];
}
return NULL;
@ -71,10 +71,10 @@ struct word *find_dict_word_by_index(ComprehendGame *game,
{
uint i;
for (i = 0; i < game->info->_nr_words; i++) {
if (game->info->_words[i]._index == index &&
(game->info->_words[i]._type & type_mask) != 0)
return &game->info->_words[i];
for (i = 0; i < game->_nr_words; i++) {
if (game->_words[i]._index == index &&
(game->_words[i]._type & type_mask) != 0)
return &game->_words[i];
}
return NULL;
@ -85,10 +85,10 @@ bool dict_match_index_type(ComprehendGame *game, const char *word,
{
uint i;
for (i = 0; i < game->info->_nr_words; i++)
if (game->info->_words[i]._index == index &&
((game->info->_words[i]._type & type_mask) != 0) &&
word_match(&game->info->_words[i], word))
for (i = 0; i < game->_nr_words; i++)
if (game->_words[i]._index == index &&
((game->_words[i]._type & type_mask) != 0) &&
word_match(&game->_words[i], word))
return true;
return false;

View File

@ -160,7 +160,7 @@ void dump_instruction(ComprehendGame *game,
break;
case OPCODE_SET_STRING_REPLACEMENT:
debugN(" %s", game->info->_replaceWords[instr->operand[0] - 1]);
debugN(" %s", game->_replaceWords[instr->operand[0] - 1]);
break;
}
@ -172,9 +172,9 @@ static void dump_functions(ComprehendGame *game)
struct function *func;
uint i, j;
debugN("Functions (%zd entries)\n", game->info->_nr_functions);
for (i = 0; i < game->info->_nr_functions; i++) {
func = &game->info->_functions[i];
debugN("Functions (%zd entries)\n", game->_nr_functions);
for (i = 0; i < game->_nr_functions; i++) {
func = &game->_functions[i];
debugN("[%.4x] (%zd instructions)\n", i, func->nr_instructions);
for (j = 0; j < func->nr_instructions; j++)
@ -189,9 +189,9 @@ static void dump_action_table(ComprehendGame *game)
struct word *word;
uint i, j;
debugN("Action table (%zd entries)\n", game->info->_nr_actions);
for (i = 0; i < game->info->_nr_actions; i++) {
action = &game->info->_actions[i];
debugN("Action table (%zd entries)\n", game->_nr_actions);
for (i = 0; i < game->_nr_actions; i++) {
action = &game->_actions[i];
debugN("(");
for (j = 0; j < 4; j++) {
@ -247,14 +247,14 @@ static void dump_dictionary(ComprehendGame *game)
uint i;
/* Sort the dictionary by index */
dictionary = (word *)xmalloc(sizeof(*words) * game->info->_nr_words);
memcpy(dictionary, game->info->_words,
sizeof(*words) * game->info->_nr_words);
qsort(dictionary, game->info->_nr_words, sizeof(*words),
dictionary = (word *)xmalloc(sizeof(*words) * game->_nr_words);
memcpy(dictionary, game->_words,
sizeof(*words) * game->_nr_words);
qsort(dictionary, game->_nr_words, sizeof(*words),
word_index_compare);
debugN("Dictionary (%zd words)\n", game->info->_nr_words);
for (i = 0; i < game->info->_nr_words; i++) {
debugN("Dictionary (%zd words)\n", game->_nr_words);
for (i = 0; i < game->_nr_words; i++) {
words = &dictionary[i];
debugN(" [%.2x] %.2x %s\n", words->_index, words->_type,
words->_word);
@ -270,9 +270,9 @@ static void dump_word_map(ComprehendGame *game)
struct word_map *map;
uint i, j;
debugN("Word pairs (%zd entries)\n", game->info->_nr_word_maps);
for (i = 0; i < game->info->_nr_word_maps; i++) {
map = &game->info->_wordMaps[i];
debugN("Word pairs (%zd entries)\n", game->_nr_word_maps);
for (i = 0; i < game->_nr_word_maps; i++) {
map = &game->_wordMaps[i];
for (j = 0; j < 3; j++) {
word[j] = dict_find_word_by_index_type(
@ -296,9 +296,9 @@ static void dump_rooms(ComprehendGame *game)
uint i;
/* Room zero acts as the players inventory */
debugN("Rooms (%zd entries)\n", game->info->_nr_rooms);
for (i = 1; i <= game->info->_nr_rooms; i++) {
room = &game->info->_rooms[i];
debugN("Rooms (%zd entries)\n", game->_nr_rooms);
for (i = 1; i <= game->_nr_rooms; i++) {
room = &game->_rooms[i];
debugN(" [%.2x] flags=%.2x, graphic=%.2x\n",
i, room->flags, room->graphic);
@ -322,22 +322,22 @@ static void dump_items(ComprehendGame *game)
struct item *item;
uint i, j;
debugN("Items (%zd entries)\n", game->info->_header.nr_items);
for (i = 0; i < game->info->_header.nr_items; i++) {
item = &game->info->_item[i];
debugN("Items (%zd entries)\n", game->_header.nr_items);
for (i = 0; i < game->_header.nr_items; i++) {
item = &game->_items[i];
debugN(" [%.2x] %s\n", i + 1,
item->string_desc ?
string_lookup(game, item->string_desc) : "");
if (game->info->_comprehendVersion == 2)
if (game->_comprehendVersion == 2)
debugN(" long desc: %s\n",
string_lookup(game, item->long_string));
debugN(" words: ");
for (j = 0; j < game->info->_nr_words; j++)
if (game->info->_words[j]._index == item->word &&
(game->info->_words[j]._type & WORD_TYPE_NOUN_MASK))
debugN("%s ", game->info->_words[j]._word);
for (j = 0; j < game->_nr_words; j++)
if (game->_words[j]._index == item->word &&
(game->_words[j]._type & WORD_TYPE_NOUN_MASK))
debugN("%s ", game->_words[j]._word);
debugN("\n");
debugN(" flags=%.2x (takeable=%d, weight=%d)\n",
item->flags, !!(item->flags & ITEMF_CAN_TAKE),
@ -359,15 +359,15 @@ static void dump_string_table(struct string_table *table)
static void dump_game_data_strings(ComprehendGame *game)
{
debugN("Main string table (%zd entries)\n",
game->info->_strings.nr_strings);
dump_string_table(&game->info->_strings);
game->_strings.nr_strings);
dump_string_table(&game->_strings);
}
static void dump_extra_strings(ComprehendGame *game)
{
debugN("Extra strings (%zd entries)\n",
game->info->_strings2.nr_strings);
dump_string_table(&game->info->_strings2);
game->_strings2.nr_strings);
dump_string_table(&game->_strings2);
}
static void dump_replace_words(ComprehendGame *game)
@ -375,14 +375,14 @@ static void dump_replace_words(ComprehendGame *game)
uint i;
debugN("Replacement words (%zd entries)\n",
game->info->_nr_replace_words);
for (i = 0; i < game->info->_nr_replace_words; i++)
debugN(" [%.2x] %s\n", i + 1, game->info->_replaceWords[i]);
game->_nr_replace_words);
for (i = 0; i < game->_nr_replace_words; i++)
debugN(" [%.2x] %s\n", i + 1, game->_replaceWords[i]);
}
static void dump_header(ComprehendGame *game)
{
struct game_header *header = &game->info->_header;
struct game_header *header = &game->_header;
uint16 *dir_table = header->room_direction_table;
debugN("Game header:\n");

View File

@ -49,11 +49,9 @@ ComprehendGame::ComprehendGame() : _gameName(nullptr),
_savegameFileFormat(nullptr),
_colorTable(0),
_gameStrings(nullptr) {
info = (game_info *)malloc(sizeof(*info));
}
ComprehendGame::~ComprehendGame() {
free(info);
}
static void console_init(void) {
@ -95,13 +93,13 @@ void console_println(ComprehendGame *game, const char *text) {
case '@':
/* Replace word */
if (game->info->_currentReplaceWord >= game->info->_nr_replace_words) {
if (game->_currentReplaceWord >= game->_nr_replace_words) {
snprintf(bad_word, sizeof(bad_word),
"[BAD_REPLACE_WORD(%.2x)]",
game->info->_currentReplaceWord);
game->_currentReplaceWord);
word = bad_word;
} else {
word = game->info->_replaceWords[game->info->_currentReplaceWord];
word = game->_replaceWords[game->_currentReplaceWord];
}
word_len = strlen(word);
p++;
@ -164,24 +162,24 @@ static struct room *get_room(ComprehendGame *game, uint16 index) {
if (index == 0)
fatal_error("Room index 0 (player inventory) is invalid");
if (index - 1 >= (int)game->info->_nr_rooms)
if (index - 1 >= (int)game->_nr_rooms)
fatal_error("Room index %d is invalid", index);
return &game->info->_rooms[index];
return &game->_rooms[index];
}
struct item *get_item(ComprehendGame *game, uint16 index) {
if (index >= game->info->_header.nr_items)
if (index >= game->_header.nr_items)
fatal_error("Bad item %d\n", index);
return &game->info->_item[index];
return &game->_items[index];
}
void game_save(ComprehendGame *game) {
char filename[32];
int c;
console_println(game, game->info->_strings.strings[STRING_SAVE_GAME]);
console_println(game, game->_strings.strings[STRING_SAVE_GAME]);
c = console_get_key();
if (c < '1' || c > '3') {
@ -201,7 +199,7 @@ void game_restore(ComprehendGame *game) {
char filename[32];
int c;
console_println(game, game->info->_strings.strings[STRING_RESTORE_GAME]);
console_println(game, game->_strings.strings[STRING_RESTORE_GAME]);
c = console_get_key();
if (c < '1' || c > '3') {
@ -216,7 +214,7 @@ void game_restore(ComprehendGame *game) {
snprintf(filename, sizeof(filename), game->_savegameFileFormat, c - '0');
comprehend_restore_game(game, filename);
game->info->_updateFlags = UPDATE_ALL;
game->_updateFlags = UPDATE_ALL;
}
void game_restart(ComprehendGame *game) {
@ -224,7 +222,7 @@ void game_restart(ComprehendGame *game) {
console_get_key();
comprehend_load_game(game);
game->info->_updateFlags = UPDATE_ALL;
game->_updateFlags = UPDATE_ALL;
}
static struct word_index *is_word_pair(ComprehendGame *game,
@ -233,8 +231,8 @@ static struct word_index *is_word_pair(ComprehendGame *game,
uint i;
/* Check if this is a word pair */
for (i = 0; i < game->info->_nr_word_maps; i++) {
map = &game->info->_wordMaps[i];
for (i = 0; i < game->_nr_word_maps; i++) {
map = &game->_wordMaps[i];
if (map->word[0].index == word1->_index &&
map->word[0].type == word1->_type &&
@ -258,9 +256,9 @@ static struct item *get_item_by_noun(ComprehendGame *game,
* (the box and the snarl-in-a-box). The player is unable
* to drop the latter because this will match the former.
*/
for (i = 0; i < game->info->_header.nr_items; i++)
if (game->info->_item[i].word == noun->_index)
return &game->info->_item[i];
for (i = 0; i < game->_header.nr_items; i++)
if (game->_items[i].word == noun->_index)
return &game->_items[i];
return NULL;
}
@ -274,34 +272,34 @@ static void update_graphics(ComprehendGame *game) {
if (!g_enabled())
return;
type = game->room_is_special(game->info->_currentRoom, NULL);
type = game->room_is_special(game->_currentRoom, NULL);
switch (type) {
case ROOM_IS_DARK:
if (game->info->_updateFlags & UPDATE_GRAPHICS)
if (game->_updateFlags & UPDATE_GRAPHICS)
draw_dark_room();
break;
case ROOM_IS_TOO_BRIGHT:
if (game->info->_updateFlags & UPDATE_GRAPHICS)
if (game->_updateFlags & UPDATE_GRAPHICS)
draw_bright_room();
break;
default:
if (game->info->_updateFlags & UPDATE_GRAPHICS) {
room = get_room(game, game->info->_currentRoom);
draw_location_image(&game->info->_roomImages,
if (game->_updateFlags & UPDATE_GRAPHICS) {
room = get_room(game, game->_currentRoom);
draw_location_image(&game->_roomImages,
room->graphic - 1);
}
if ((game->info->_updateFlags & UPDATE_GRAPHICS) ||
(game->info->_updateFlags & UPDATE_GRAPHICS_ITEMS)) {
for (i = 0; i < game->info->_header.nr_items; i++) {
item = &game->info->_item[i];
if ((game->_updateFlags & UPDATE_GRAPHICS) ||
(game->_updateFlags & UPDATE_GRAPHICS_ITEMS)) {
for (i = 0; i < game->_header.nr_items; i++) {
item = &game->_items[i];
if (item->room == game->info->_currentRoom &&
if (item->room == game->_currentRoom &&
item->graphic != 0)
draw_image(&game->info->_itemImages,
draw_image(&game->_itemImages,
item->graphic - 1);
}
}
@ -314,10 +312,10 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
size_t count = 0;
uint i;
for (i = 0; i < game->info->_header.nr_items; i++) {
item = &game->info->_item[i];
for (i = 0; i < game->_header.nr_items; i++) {
item = &game->_items[i];
if (item->room == game->info->_currentRoom &&
if (item->room == game->_currentRoom &&
item->string_desc != 0)
count++;
}
@ -325,10 +323,10 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
if (count > 0) {
console_println(game, string_lookup(game, STRING_YOU_SEE));
for (i = 0; i < game->info->_header.nr_items; i++) {
item = &game->info->_item[i];
for (i = 0; i < game->_header.nr_items; i++) {
item = &game->_items[i];
if (item->room == game->info->_currentRoom &&
if (item->room == game->_currentRoom &&
item->string_desc != 0)
console_println(game, string_lookup(game, item->string_desc));
}
@ -336,32 +334,32 @@ static void describe_objects_in_current_room(ComprehendGame *game) {
}
static void update(ComprehendGame *game) {
struct room *room = get_room(game, game->info->_currentRoom);
struct room *room = get_room(game, game->_currentRoom);
unsigned room_type, room_desc_string;
update_graphics(game);
/* Check if the room is special (dark, too bright, etc) */
room_desc_string = room->string_desc;
room_type = game->room_is_special(game->info->_currentRoom,
room_type = game->room_is_special(game->_currentRoom,
&room_desc_string);
if (game->info->_updateFlags & UPDATE_ROOM_DESC)
if (game->_updateFlags & UPDATE_ROOM_DESC)
console_println(game, string_lookup(game, room_desc_string));
if ((game->info->_updateFlags & UPDATE_ITEM_LIST) &&
if ((game->_updateFlags & UPDATE_ITEM_LIST) &&
room_type == ROOM_IS_NORMAL)
describe_objects_in_current_room(game);
game->info->_updateFlags = 0;
game->_updateFlags = 0;
}
static void move_to(ComprehendGame *game, uint8 room) {
if (room - 1 >= (int)game->info->_nr_rooms)
if (room - 1 >= (int)game->_nr_rooms)
fatal_error("Attempted to move to invalid room %.2x\n", room);
game->info->_currentRoom = room;
game->info->_updateFlags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
game->_currentRoom = room;
game->_updateFlags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
UPDATE_ITEM_LIST);
}
@ -386,8 +384,8 @@ static void func_set_test_result(struct function_state *func_state, bool value)
static size_t num_objects_in_room(ComprehendGame *game, int room) {
size_t count = 0, i;
for (i = 0; i < game->info->_header.nr_items; i++)
if (game->info->_item[i].room == room)
for (i = 0; i < game->_header.nr_items; i++)
if (game->_items[i].room == room)
count++;
return count;
@ -401,23 +399,23 @@ void move_object(ComprehendGame *game, struct item *item, int new_room) {
if (item->room == ROOM_INVENTORY) {
/* Removed from player's inventory */
game->info->_variables[VAR_INVENTORY_WEIGHT] -= obj_weight;
game->_variables[VAR_INVENTORY_WEIGHT] -= obj_weight;
}
if (new_room == ROOM_INVENTORY) {
/* Moving to the player's inventory */
game->info->_variables[VAR_INVENTORY_WEIGHT] += obj_weight;
game->_variables[VAR_INVENTORY_WEIGHT] += obj_weight;
}
if (item->room == game->info->_currentRoom) {
if (item->room == game->_currentRoom) {
/* Item moved away from the current room */
game->info->_updateFlags |= UPDATE_GRAPHICS;
game->_updateFlags |= UPDATE_GRAPHICS;
} else if (new_room == game->info->_currentRoom) {
} else if (new_room == game->_currentRoom) {
/*
* Item moved into the current room. Only the item needs a
* redraw, not the whole room.
*/
game->info->_updateFlags |= (UPDATE_GRAPHICS_ITEMS |
game->_updateFlags |= (UPDATE_GRAPHICS_ITEMS |
UPDATE_ITEM_LIST);
}
@ -435,7 +433,7 @@ static void eval_instruction(ComprehendGame *game,
bool test;
uint i, count;
room = get_room(game, game->info->_currentRoom);
room = get_room(game, game->_currentRoom);
if (debugging_enabled()) {
if (!instr->is_command) {
@ -482,31 +480,31 @@ static void eval_instruction(ComprehendGame *game,
opcode_map = get_opcode_map(game);
switch (opcode_map[instr->opcode]) {
case OPCODE_VAR_ADD:
game->info->_variables[instr->operand[0]] +=
game->info->_variables[instr->operand[1]];
game->_variables[instr->operand[0]] +=
game->_variables[instr->operand[1]];
break;
case OPCODE_VAR_SUB:
game->info->_variables[instr->operand[0]] -=
game->info->_variables[instr->operand[1]];
game->_variables[instr->operand[0]] -=
game->_variables[instr->operand[1]];
break;
case OPCODE_VAR_INC:
game->info->_variables[instr->operand[0]]++;
game->_variables[instr->operand[0]]++;
break;
case OPCODE_VAR_DEC:
game->info->_variables[instr->operand[0]]--;
game->_variables[instr->operand[0]]--;
break;
case OPCODE_VAR_EQ:
func_set_test_result(func_state,
game->info->_variables[instr->operand[0]] ==
game->info->_variables[instr->operand[1]]);
game->_variables[instr->operand[0]] ==
game->_variables[instr->operand[1]]);
break;
case OPCODE_TURN_TICK:
game->info->_variables[VAR_TURN_COUNT]++;
game->_variables[VAR_TURN_COUNT]++;
break;
case OPCODE_PRINT:
@ -527,12 +525,12 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_NOT_IN_ROOM:
func_set_test_result(func_state,
game->info->_currentRoom != instr->operand[0]);
game->_currentRoom != instr->operand[0]);
break;
case OPCODE_IN_ROOM:
func_set_test_result(func_state,
game->info->_currentRoom == instr->operand[0]);
game->_currentRoom == instr->operand[0]);
break;
case OPCODE_MOVE_TO_ROOM:
@ -574,7 +572,7 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM:
item = get_item(game, instr->operand[0] - 1);
move_object(game, item, game->info->_currentRoom);
move_object(game, item, game->_currentRoom);
break;
case OPCODE_OBJECT_IN_ROOM:
@ -597,9 +595,9 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_INVENTORY_FULL:
item = get_item_by_noun(game, noun);
func_set_test_result(func_state,
game->info->_variables[VAR_INVENTORY_WEIGHT] +
game->_variables[VAR_INVENTORY_WEIGHT] +
(item->flags & ITEMF_WEIGHT_MASK) >
game->info->_variables[VAR_INVENTORY_LIMIT]);
game->_variables[VAR_INVENTORY_LIMIT]);
break;
case OPCODE_DESCRIBE_CURRENT_OBJECT:
@ -616,8 +614,8 @@ static void eval_instruction(ComprehendGame *game,
test = false;
if (noun) {
for (i = 0; i < game->info->_header.nr_items; i++) {
struct item *itemP = &game->info->_item[i];
for (i = 0; i < game->_header.nr_items; i++) {
struct item *itemP = &game->_items[i];
if (itemP->word == noun->_index &&
itemP->room == instr->operand[0]) {
@ -635,7 +633,7 @@ static void eval_instruction(ComprehendGame *game,
item = get_item_by_noun(game, noun);
if (item)
func_set_test_result(func_state,
item->room != game->info->_currentRoom);
item->room != game->_currentRoom);
else
func_set_test_result(func_state, true);
break;
@ -644,7 +642,7 @@ static void eval_instruction(ComprehendGame *game,
item = get_item_by_noun(game, noun);
if (item)
func_set_test_result(func_state,
item->room == game->info->_currentRoom);
item->room == game->_currentRoom);
else
func_set_test_result(func_state, false);
break;
@ -715,13 +713,13 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_OBJECT_NOT_PRESENT:
item = get_item(game, instr->operand[0] - 1);
func_set_test_result(func_state,
item->room != game->info->_currentRoom);
item->room != game->_currentRoom);
break;
case OPCODE_OBJECT_PRESENT:
item = get_item(game, instr->operand[0] - 1);
func_set_test_result(func_state,
item->room == game->info->_currentRoom);
item->room == game->_currentRoom);
break;
case OPCODE_OBJECT_NOT_VALID:
@ -758,8 +756,8 @@ static void eval_instruction(ComprehendGame *game,
}
console_println(game, string_lookup(game, STRING_INVENTORY));
for (i = 0; i < game->info->_header.nr_items; i++) {
item = &game->info->_item[i];
for (i = 0; i < game->_header.nr_items; i++) {
item = &game->_items[i];
if (item->room == ROOM_INVENTORY)
printf("%s\n",
string_lookup(game, item->string_desc));
@ -774,8 +772,8 @@ static void eval_instruction(ComprehendGame *game,
}
console_println(game, string_lookup(game, instr->operand[1]));
for (i = 0; i < game->info->_header.nr_items; i++) {
item = &game->info->_item[i];
for (i = 0; i < game->_header.nr_items; i++) {
item = &game->_items[i];
if (item->room == instr->operand[0])
printf("%s\n",
string_lookup(game, item->string_desc));
@ -792,7 +790,7 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_DROP_OBJECT:
item = get_item(game, instr->operand[0] - 1);
move_object(game, item, game->info->_currentRoom);
move_object(game, item, game->_currentRoom);
break;
case OPCODE_DROP_CURRENT_OBJECT:
@ -800,7 +798,7 @@ static void eval_instruction(ComprehendGame *game,
if (!item)
fatal_error("Attempt to take object failed\n");
move_object(game, item, game->info->_currentRoom);
move_object(game, item, game->_currentRoom);
break;
case OPCODE_TAKE_CURRENT_OBJECT:
@ -818,20 +816,20 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_TEST_FLAG:
func_set_test_result(func_state,
game->info->_flags[instr->operand[0]]);
game->_flags[instr->operand[0]]);
break;
case OPCODE_TEST_NOT_FLAG:
func_set_test_result(func_state,
!game->info->_flags[instr->operand[0]]);
!game->_flags[instr->operand[0]]);
break;
case OPCODE_CLEAR_FLAG:
game->info->_flags[instr->operand[0]] = false;
game->_flags[instr->operand[0]] = false;
break;
case OPCODE_SET_FLAG:
game->info->_flags[instr->operand[0]] = true;
game->_flags[instr->operand[0]] = true;
break;
case OPCODE_OR:
@ -875,28 +873,28 @@ static void eval_instruction(ComprehendGame *game,
case OPCODE_SET_OBJECT_GRAPHIC:
item = get_item(game, instr->operand[0] - 1);
item->graphic = instr->operand[1];
if (item->room == game->info->_currentRoom)
game->info->_updateFlags |= UPDATE_GRAPHICS;
if (item->room == game->_currentRoom)
game->_updateFlags |= UPDATE_GRAPHICS;
break;
case OPCODE_SET_ROOM_GRAPHIC:
room = get_room(game, instr->operand[0]);
room->graphic = instr->operand[1];
if (instr->operand[0] == game->info->_currentRoom)
game->info->_updateFlags |= UPDATE_GRAPHICS;
if (instr->operand[0] == game->_currentRoom)
game->_updateFlags |= UPDATE_GRAPHICS;
break;
case OPCODE_CALL_FUNC:
index = instr->operand[0];
if (instr->operand[1] == 0x81)
index += 256;
if (index >= game->info->_nr_functions)
if (index >= game->_nr_functions)
fatal_error("Bad function %.4x >= %.4x\n",
index, game->info->_nr_functions);
index, game->_nr_functions);
debug_printf(DEBUG_FUNCTIONS,
"Calling subfunction %.4x\n", index);
eval_function(game, &game->info->_functions[index], verb, noun);
eval_function(game, &game->_functions[index], verb, noun);
break;
case OPCODE_TEST_FALSE:
@ -923,7 +921,7 @@ static void eval_instruction(ComprehendGame *game,
break;
case OPCODE_SET_STRING_REPLACEMENT:
game->info->_currentReplaceWord = instr->operand[0] - 1;
game->_currentReplaceWord = instr->operand[0] - 1;
break;
case OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT:
@ -932,22 +930,22 @@ static void eval_instruction(ComprehendGame *game,
* maybe capitalisation?
*/
if (noun && (noun->_type & WORD_TYPE_NOUN_PLURAL))
game->info->_currentReplaceWord = 3;
game->_currentReplaceWord = 3;
else if (noun && (noun->_type & WORD_TYPE_FEMALE))
game->info->_currentReplaceWord = 0;
game->_currentReplaceWord = 0;
else if (noun && (noun->_type & WORD_TYPE_MALE))
game->info->_currentReplaceWord = 1;
game->_currentReplaceWord = 1;
else
game->info->_currentReplaceWord = 2;
game->_currentReplaceWord = 2;
break;
case OPCODE_DRAW_ROOM:
draw_location_image(&game->info->_roomImages,
draw_location_image(&game->_roomImages,
instr->operand[0] - 1);
break;
case OPCODE_DRAW_OBJECT:
draw_image(&game->info->_itemImages, instr->operand[0] - 1);
draw_image(&game->_itemImages, instr->operand[0] - 1);
break;
case OPCODE_WAIT_KEY:
@ -1037,21 +1035,21 @@ static void handle_debug_command(ComprehendGame *game,
dump_game_data(game, DUMP_ROOMS);
} else if (strncmp(line, "dump state", 10) == 0) {
printf("Current room: %.2x\n", game->info->current_room);
printf("Current room: %.2x\n", game->current_room);
printf("Carry weight %d/%d\n\n",
game->info->variable[VAR_INVENTORY_WEIGHT],
game->info->variable[VAR_INVENTORY_LIMIT]);
game->variable[VAR_INVENTORY_WEIGHT],
game->variable[VAR_INVENTORY_LIMIT]);
printf("Flags:\n");
for (i = 0; i < ARRAY_SIZE(game->info->flags); i++)
printf(" [%.2x]: %d\n", i, game->info->flags[i]);
for (i = 0; i < ARRAY_SIZE(game->flags); i++)
printf(" [%.2x]: %d\n", i, game->flags[i]);
printf("\n");
printf("Variables:\n");
for (i = 0; i < ARRAY_SIZE(game->info->variable); i++)
for (i = 0; i < ARRAY_SIZE(game->variable); i++)
printf(" [%.2x]: %5d (0x%.4x)\n",
i, game->info->variable[i],
game->info->variable[i]);
i, game->variable[i],
game->variable[i]);
printf("\n");
}
}
@ -1067,8 +1065,8 @@ static bool handle_sentence(ComprehendGame *game,
return false;
/* Find a matching action */
for (i = 0; i < game->info->_nr_actions; i++) {
action = &game->info->_actions[i];
for (i = 0; i < game->_nr_actions; i++) {
action = &game->_actions[i];
if (action->type == ACTION_VERB_OPT_NOUN &&
sentence->nr_words > action->nr_words + 1)
@ -1091,7 +1089,7 @@ static bool handle_sentence(ComprehendGame *game,
}
if (j == action->nr_words) {
/* Match */
func = &game->info->_functions[action->function];
func = &game->_functions[action->function];
eval_function(game, func,
&sentence->words[0], &sentence->words[1]);
return true;
@ -1168,7 +1166,7 @@ static void before_turn(ComprehendGame *game) {
game->before_turn();
// Run the each turn functions
eval_function(game, &game->info->_functions[0], NULL, NULL);
eval_function(game, &game->_functions[0], NULL, NULL);
update(game);
}
@ -1223,7 +1221,7 @@ void comprehend_play_game(ComprehendGame *game) {
game->before_game();
game->info->_updateFlags = (uint)UPDATE_ALL;
game->_updateFlags = (uint)UPDATE_ALL;
while (!g_comprehend->shouldQuit())
read_input(game);
}

View File

@ -33,7 +33,7 @@ namespace Comprehend {
#define ROOM_IS_DARK 1
#define ROOM_IS_TOO_BRIGHT 2
class ComprehendGame {
class ComprehendGame : public GameInfo {
public:
const char *_gameName;
const char *_shortName;
@ -46,7 +46,6 @@ public:
unsigned _colorTable;
struct game_strings *_gameStrings;
struct game_info *info;
public:
ComprehendGame();

View File

@ -71,8 +71,8 @@ ComprehendGame game_crimson_crown_2 = {
static void cc_clear_companion_flags(ComprehendGame *game) {
/* Clear the Sabrina/Erik action flags */
game->info->_flags[0xa] = 0;
game->info->_flags[0xb] = 0;
game->_flags[0xa] = 0;
game->_flags[0xb] = 0;
}
static bool cc_common_handle_special_opcode(ComprehendGame *game,
@ -128,7 +128,7 @@ static void cc2_handle_special_opcode(ComprehendGame *game,
switch (operand) {
case 0x01:
/* Enter the Vampire's throne room */
eval_function(game, &game->info->_functions[0xe], NULL, NULL);
eval_function(game, &game->_functions[0xe], NULL, NULL);
break;
case 0x05:

View File

@ -38,99 +38,149 @@ static char special_charset[] = "[]\n!\"#$%&'(),-/0123456789:;?<>";
static uint16 magic_offset;
function_state::function_state() : test_result(true),
else_result(false),
or_count(0),
_and(false),
in_command(false),
executed(false) {
void function_state::clear() {
test_result = true;
else_result = false;
or_count = 0;
_and = false;
in_command = false;
executed = false;
}
/*-------------------------------------------------------*/
room::room() : flags(0),
graphic(0),
string_desc(0) {
void room::clear() {
flags = 0;
graphic = 0;
string_desc = 0;
Common::fill(&direction[0], &direction[NR_DIRECTIONS], 0);
}
/*-------------------------------------------------------*/
item::item() : string_desc(0),
long_string(0),
room(0),
flags(0),
word(0),
graphic(0) {
void item::clear() {
string_desc = 0;
long_string = 0;
room = 0;
flags = 0;
word = 0;
graphic = 0;
}
/*-------------------------------------------------------*/
word::word() : _index(0), _type(0) {
void word::clear() {
_index = 0;
_type = 0;
Common::fill(&_word[0], &_word[7], '\0');
}
/*-------------------------------------------------------*/
action::action() : type(0), nr_words(0), function(0) {
void word_map::clear() {
flags = 0;
for (int idx = 0; idx < 3; ++idx)
word[idx].clear();
}
/*-------------------------------------------------------*/
void action::clear() {
type = 0;
nr_words = 0;
function = 0;
Common::fill(&word[0], &word[4], 0);
Common::fill(&word_type[0], &word_type[4], 0);
}
instruction::instruction() : opcode(0), nr_operands(0),
is_command(false) {
/*-------------------------------------------------------*/
void instruction::clear() {
opcode = 0;
nr_operands = 0;
is_command= false;
Common::fill(&operand[0], &operand[3], 0);
}
/*-------------------------------------------------------*/
string_table::string_table() : nr_strings(0) {
void function::clear() {
nr_instructions = 0;
for (int idx = 0; idx < 0x100; ++idx)
instructions[idx].clear();
}
/*-------------------------------------------------------*/
void string_table::clear() {
nr_strings = 0;
Common::fill(&strings[0], &strings[0xffff], nullptr);
}
/*-------------------------------------------------------*/
game_header::game_header() : magic(0),
room_desc_table(0),
room_flags_table(0),
room_graphics_table(0),
nr_items(0),
addr_item_locations(0),
addr_item_flags(0),
addr_item_word(0),
addr_item_strings(0),
addr_item_graphics(0),
addr_dictionary(0),
addr_word_map(0),
addr_strings(0),
addr_strings_end(0),
addr_actions_vvnn(0),
addr_actions_unknown(0),
addr_actions_vnjn(0),
addr_actions_vjn(0),
addr_actions_vdn(0),
addr_actions_vnn(0),
addr_actions_vn(0),
addr_actions_v(0),
addr_vm(0) // FIXME - functions
{
void game_header::clear() {
magic = 0;
room_desc_table = 0;
room_flags_table = 0;
room_graphics_table = 0;
nr_items = 0;
addr_item_locations = 0;
addr_item_flags = 0;
addr_item_word = 0;
addr_item_strings = 0;
addr_item_graphics = 0;
addr_dictionary = 0;
addr_word_map = 0;
addr_strings = 0;
addr_strings_end = 0;
addr_actions_vvnn = 0;
addr_actions_unknown = 0;
addr_actions_vnjn = 0;
addr_actions_vjn = 0;
addr_actions_vdn = 0;
addr_actions_vnn = 0;
addr_actions_vn = 0;
addr_actions_v = 0;
addr_vm = 0; // FIXME - functions
Common::fill(&room_direction_table[0], &room_direction_table[NR_DIRECTIONS], 0);
}
/*-------------------------------------------------------*/
game_info::game_info() : _comprehendVersion(0),
_startRoom(0),
_nr_rooms(0),
_currentRoom(0),
_words(nullptr),
_nr_words(0),
_nr_word_maps(0),
_nr_actions(0),
_nr_functions(0),
_nr_replace_words(0),
_currentReplaceWord(0),
_updateFlags(0) {
void GameInfo::clearInfo() {
_header.clear();
_comprehendVersion = 0;
_startRoom = 0;
_nr_rooms = 0;
_currentRoom = 0;
_words = nullptr;
_nr_words = 0;
_nr_word_maps = 0;
_nr_actions = 0;
_nr_functions = 0;
_nr_replace_words = 0;
_currentReplaceWord = 0;
_updateFlags = 0;
_strings.clear();
_strings2.clear();
_roomImages.clear();
_itemImages.clear();
for (uint idx = 0; idx < 0x100; ++idx)
_rooms[idx].clear();
for (uint idx = 0; idx < 0xff; ++idx)
_items[idx].clear();
for (uint idx = 0; idx < 0xff; ++idx)
_wordMaps[idx].clear();
for (uint idx = 0; idx < 0xffff; ++idx)
_actions[idx].clear();
for (uint idx = 0; idx < 0xffff; ++idx)
_functions[idx].clear();
Common::fill(&_flags[0], &_flags[MAX_FLAGS], false);
Common::fill(&_variables[0], &_variables[MAX_VARIABLES], 0);
Common::fill(&_replaceWords[0], &_replaceWords[256], (char *)nullptr);
}
static void parse_header_le16(struct file_buf * fb, uint16 * val) {
@ -190,15 +240,15 @@ static void parse_function(struct file_buf * fb, struct function * func) {
static void parse_vm(ComprehendGame * game, struct file_buf * fb) {
struct function *func;
file_buf_set_pos(fb, game->info->_header.addr_vm);
file_buf_set_pos(fb, game->_header.addr_vm);
while (1) {
func = &game->info->_functions[game->info->_nr_functions];
func = &game->_functions[game->_nr_functions];
parse_function(fb, func);
if (func->nr_instructions == 0)
break;
game->info->_nr_functions++;
game->_nr_functions++;
}
}
@ -218,7 +268,7 @@ static void parse_action_table_vvnn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
file_buf_set_pos(fb, game->info->_header.addr_actions_vvnn);
file_buf_set_pos(fb, game->_header.addr_actions_vvnn);
while (1) {
file_buf_get_u8(fb, &verb);
if (verb == 0)
@ -226,7 +276,7 @@ static void parse_action_table_vvnn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
action = &game->info->_actions[*index];
action = &game->_actions[*index];
action->type = ACTION_VERB_VERB_NOUN_NOUN;
action->nr_words = 4;
@ -262,7 +312,7 @@ static void parse_action_table_vnjn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
file_buf_set_pos(fb, game->info->_header.addr_actions_vnjn);
file_buf_set_pos(fb, game->_header.addr_actions_vnjn);
while (1) {
file_buf_get_u8(fb, &join);
if (join == 0)
@ -270,7 +320,7 @@ static void parse_action_table_vnjn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
action = &game->info->_actions[*index];
action = &game->_actions[*index];
action->type = ACTION_VERB_NOUN_JOIN_NOUN;
action->nr_words = 4;
@ -306,7 +356,7 @@ static void parse_action_table_vjn(ComprehendGame * game,
* u8: noun
* le16: action
*/
file_buf_set_pos(fb, game->info->_header.addr_actions_vjn);
file_buf_set_pos(fb, game->_header.addr_actions_vjn);
while (1) {
file_buf_get_u8(fb, &join);
if (join == 0)
@ -314,7 +364,7 @@ static void parse_action_table_vjn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
action = &game->info->_actions[*index];
action = &game->_actions[*index];
action->type = ACTION_VERB_JOIN_NOUN;
action->word[1] = join;
@ -347,7 +397,7 @@ static void parse_action_table_vdn(ComprehendGame * game,
* u8: noun
* le16: action
*/
file_buf_set_pos(fb, game->info->_header.addr_actions_vdn);
file_buf_set_pos(fb, game->_header.addr_actions_vdn);
while (1) {
file_buf_get_u8(fb, &verb);
if (verb == 0)
@ -355,7 +405,7 @@ static void parse_action_table_vdn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
action = &game->info->_actions[*index];
action = &game->_actions[*index];
action->type = ACTION_VERB_JOIN_NOUN;
action->word[0] = verb;
@ -388,7 +438,7 @@ static void parse_action_table_vnn(ComprehendGame * game,
* u8: noun2
* le16: action
*/
file_buf_set_pos(fb, game->info->_header.addr_actions_vnn);
file_buf_set_pos(fb, game->_header.addr_actions_vnn);
while (1) {
/* 2-byte header */
file_buf_get_u8(fb, &verb);
@ -397,7 +447,7 @@ static void parse_action_table_vnn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
action = &game->info->_actions[*index];
action = &game->_actions[*index];
action->type = ACTION_VERB_NOUN_NOUN;
action->word[0] = verb;
@ -429,7 +479,7 @@ static void parse_action_table_vn(ComprehendGame * game,
* u8: noun
* le16: action
*/
file_buf_set_pos(fb, game->info->_header.addr_actions_vn);
file_buf_set_pos(fb, game->_header.addr_actions_vn);
while (1) {
/* 2-byte header */
file_buf_get_u8(fb, &verb);
@ -438,7 +488,7 @@ static void parse_action_table_vn(ComprehendGame * game,
file_buf_get_u8(fb, &count);
for (i = 0; i < count; i++) {
action = &game->info->_actions[*index];
action = &game->_actions[*index];
action->type = ACTION_VERB_NOUN;
action->word[0] = verb;
@ -468,13 +518,13 @@ static void parse_action_table_v(ComprehendGame * game,
* u8: count (num actions)
* le16: action
*/
file_buf_set_pos(fb, game->info->_header.addr_actions_v);
file_buf_set_pos(fb, game->_header.addr_actions_v);
while (1) {
file_buf_get_u8(fb, &verb);
if (verb == 0)
break;
action = &game->info->_actions[*index];
action = &game->_actions[*index];
action->type = ACTION_VERB_OPT_NOUN;
action->word[0] = verb;
@ -499,20 +549,20 @@ static void parse_action_table_v(ComprehendGame * game,
static void parse_action_table(ComprehendGame * game,
struct file_buf * fb) {
game->info->_nr_actions = 0;
game->_nr_actions = 0;
if (game->info->_comprehendVersion == 1) {
parse_action_table_vvnn(game, fb, &game->info->_nr_actions);
parse_action_table_vdn(game, fb, &game->info->_nr_actions);
if (game->_comprehendVersion == 1) {
parse_action_table_vvnn(game, fb, &game->_nr_actions);
parse_action_table_vdn(game, fb, &game->_nr_actions);
}
if (game->info->_comprehendVersion >= 2) {
parse_action_table_vnn(game, fb, &game->info->_nr_actions);
if (game->_comprehendVersion >= 2) {
parse_action_table_vnn(game, fb, &game->_nr_actions);
}
parse_action_table_vnjn(game, fb, &game->info->_nr_actions);
parse_action_table_vjn(game, fb, &game->info->_nr_actions);
parse_action_table_vn(game, fb, &game->info->_nr_actions);
parse_action_table_v(game, fb, &game->info->_nr_actions);
parse_action_table_vnjn(game, fb, &game->_nr_actions);
parse_action_table_vjn(game, fb, &game->_nr_actions);
parse_action_table_vn(game, fb, &game->_nr_actions);
parse_action_table_v(game, fb, &game->_nr_actions);
}
static void parse_dictionary(ComprehendGame * game, struct file_buf * fb) {
@ -520,11 +570,11 @@ static void parse_dictionary(ComprehendGame * game, struct file_buf * fb) {
uint i, j;
// FIXME - fixed size 0xff array?
game->info->_words = (word *)xmalloc(game->info->_nr_words * sizeof(words));
game->_words = (word *)xmalloc(game->_nr_words * sizeof(words));
file_buf_set_pos(fb, game->info->_header.addr_dictionary);
for (i = 0; i < game->info->_nr_words; i++) {
words = &game->info->_words[i];
file_buf_set_pos(fb, game->_header.addr_dictionary);
for (i = 0; i < game->_nr_words; i++) {
words = &game->_words[i];
file_buf_get_data(fb, words->_word, 6);
@ -543,15 +593,15 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
uint8 index, type, dummy;
uint i;
game->info->_nr_word_maps = 0;
file_buf_set_pos(fb, game->info->_header.addr_word_map);
game->_nr_word_maps = 0;
file_buf_set_pos(fb, game->_header.addr_word_map);
/*
* Parse the word pair table. Each entry has a pair of dictionary
* index/type values for a first and second word.
*/
while (1) {
map = &game->info->_wordMaps[game->info->_nr_word_maps];
map = &game->_wordMaps[game->_nr_word_maps];
file_buf_get_u8(fb, &index);
file_buf_get_u8(fb, &type);
@ -566,7 +616,7 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
file_buf_get_u8(fb, &map->word[1].index);
file_buf_get_u8(fb, &map->word[1].type);
game->info->_nr_word_maps++;
game->_nr_word_maps++;
}
/* Consume two more null bytes (type and index were also null) */
@ -578,8 +628,8 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
* index/type. The first and second words from above map to the
* target word here. E.g. 'go north' -> 'north'.
*/
for (i = 0; i < game->info->_nr_word_maps; i++) {
map = &game->info->_wordMaps[i];
for (i = 0; i < game->_nr_word_maps; i++) {
map = &game->_wordMaps[i];
file_buf_get_u8(fb, &map->word[2].index);
file_buf_get_u8(fb, &map->word[2].type);
@ -587,58 +637,58 @@ static void parse_word_map(ComprehendGame * game, struct file_buf * fb) {
}
static void parse_items(ComprehendGame * game, struct file_buf * fb) {
size_t nr_items = game->info->_header.nr_items;
size_t nr_items = game->_header.nr_items;
/* Item descriptions */
file_buf_set_pos(fb, game->info->_header.addr_item_strings);
file_buf_get_array_le16(fb, 0, game->info->_item, string_desc, nr_items);
file_buf_set_pos(fb, game->_header.addr_item_strings);
file_buf_get_array_le16(fb, 0, game->_items, string_desc, nr_items);
if (game->info->_comprehendVersion == 2) {
if (game->_comprehendVersion == 2) {
/* Comprehend version 2 adds long string descriptions */
file_buf_set_pos(fb, game->info->_header.addr_item_strings +
(game->info->_header.nr_items * sizeof(uint16)));
file_buf_get_array_le16(fb, 0, game->info->_item, long_string, nr_items);
file_buf_set_pos(fb, game->_header.addr_item_strings +
(game->_header.nr_items * sizeof(uint16)));
file_buf_get_array_le16(fb, 0, game->_items, long_string, nr_items);
}
/* Item flags */
file_buf_set_pos(fb, game->info->_header.addr_item_flags);
file_buf_get_array_u8(fb, 0, game->info->_item, flags, nr_items);
file_buf_set_pos(fb, game->_header.addr_item_flags);
file_buf_get_array_u8(fb, 0, game->_items, flags, nr_items);
/* Item word */
file_buf_set_pos(fb, game->info->_header.addr_item_word);
file_buf_get_array_u8(fb, 0, game->info->_item, word, nr_items);
file_buf_set_pos(fb, game->_header.addr_item_word);
file_buf_get_array_u8(fb, 0, game->_items, word, nr_items);
/* Item locations */
file_buf_set_pos(fb, game->info->_header.addr_item_locations);
file_buf_get_array_u8(fb, 0, game->info->_item, room, nr_items);
file_buf_set_pos(fb, game->_header.addr_item_locations);
file_buf_get_array_u8(fb, 0, game->_items, room, nr_items);
/* Item graphic */
file_buf_set_pos(fb, game->info->_header.addr_item_graphics);
file_buf_get_array_u8(fb, 0, game->info->_item, graphic, nr_items);
file_buf_set_pos(fb, game->_header.addr_item_graphics);
file_buf_get_array_u8(fb, 0, game->_items, graphic, nr_items);
}
static void parse_rooms(ComprehendGame * game, struct file_buf * fb) {
size_t nr_rooms = game->info->_nr_rooms;
size_t nr_rooms = game->_nr_rooms;
int i;
/* Room exit directions */
for (i = 0; i < NR_DIRECTIONS; i++) {
file_buf_set_pos(fb, game->info->_header.room_direction_table[i]);
file_buf_get_array_u8(fb, 1, game->info->_rooms,
file_buf_set_pos(fb, game->_header.room_direction_table[i]);
file_buf_get_array_u8(fb, 1, game->_rooms,
direction[i], nr_rooms);
}
/* Room string descriptions */
file_buf_set_pos(fb, game->info->_header.room_desc_table);
file_buf_get_array_le16(fb, 1, game->info->_rooms, string_desc, nr_rooms);
file_buf_set_pos(fb, game->_header.room_desc_table);
file_buf_get_array_le16(fb, 1, game->_rooms, string_desc, nr_rooms);
/* Room flags */
file_buf_set_pos(fb, game->info->_header.room_flags_table);
file_buf_get_array_u8(fb, 1, game->info->_rooms, flags, nr_rooms);
file_buf_set_pos(fb, game->_header.room_flags_table);
file_buf_get_array_u8(fb, 1, game->_rooms, flags, nr_rooms);
/* Room graphic */
file_buf_set_pos(fb, game->info->_header.room_graphics_table);
file_buf_get_array_u8(fb, 1, game->info->_rooms, graphic, nr_rooms);
file_buf_set_pos(fb, game->_header.room_graphics_table);
file_buf_get_array_u8(fb, 1, game->_rooms, graphic, nr_rooms);
}
static uint64 string_get_chunk(uint8 * string) {
@ -751,18 +801,18 @@ static void parse_string_table(struct file_buf * fb, unsigned start_addr,
static void parse_variables(ComprehendGame * game, struct file_buf * fb) {
int i;
for (i = 0; i < ARRAY_SIZE(game->info->_variables); i++)
file_buf_get_le16(fb, &game->info->_variables[i]);
for (i = 0; i < ARRAY_SIZE(game->_variables); i++)
file_buf_get_le16(fb, &game->_variables[i]);
}
static void parse_flags(ComprehendGame * game, struct file_buf * fb) {
int i, bit, flag_index = 0;
uint8 bitmask;
for (i = 0; i < ARRAY_SIZE(game->info->_flags) / 8; i++) {
for (i = 0; i < ARRAY_SIZE(game->_flags) / 8; i++) {
file_buf_get_u8(fb, &bitmask);
for (bit = 7; bit >= 0; bit--) {
game->info->_flags[flag_index] = !!(bitmask & (1 << bit));
game->_flags[flag_index] = !!(bitmask & (1 << bit));
flag_index++;
}
}
@ -776,7 +826,7 @@ static void parse_replace_words(ComprehendGame * game,
int i;
/* FIXME - Rename addr_strings_end */
file_buf_set_pos(fb, game->info->_header.addr_strings_end);
file_buf_set_pos(fb, game->_header.addr_strings_end);
/* FIXME - what is this for */
file_buf_get_le16(fb, &dummy);
@ -786,12 +836,12 @@ static void parse_replace_words(ComprehendGame * game,
if (len == 0)
break;
game->info->_replaceWords[i] = xstrndup((char *)fb->p, len);
game->_replaceWords[i] = xstrndup((char *)fb->p, len);
file_buf_get_data(fb, NULL, len + (eof ? 0 : 1));
if (eof)
break;
}
game->info->_nr_replace_words = i;
game->_nr_replace_words = i;
}
/*
@ -799,7 +849,7 @@ static void parse_replace_words(ComprehendGame * game,
* game data is. The offsets have a magic constant value added to them.
*/
static void parse_header(ComprehendGame * game, struct file_buf * fb) {
struct game_header *header = &game->info->_header;
struct game_header *header = &game->_header;
uint16 dummy, addr_dictionary_end;
uint8 dummy8;
@ -808,17 +858,17 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
switch (header->magic) {
case 0x2000: /* Transylvania, Crimson Crown disk one */
case 0x4800: /* Crimson Crown disk two */
game->info->_comprehendVersion = 1;
game->_comprehendVersion = 1;
magic_offset = (uint16)(-0x5a00 + 0x4);
break;
case 0x93f0: /* OO-Topos */
game->info->_comprehendVersion = 2;
game->_comprehendVersion = 2;
magic_offset = (uint16)-0x5a00;
break;
case 0xa429: /* Talisman */
game->info->_comprehendVersion = 2;
game->_comprehendVersion = 2;
magic_offset = (uint16)-0x5a00;
break;
@ -835,14 +885,14 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
*
* Layout depends on the comprehend version.
*/
if (game->info->_comprehendVersion == 1) {
if (game->_comprehendVersion == 1) {
parse_header_le16(fb, &header->addr_actions_vvnn);
parse_header_le16(fb, &header->addr_actions_unknown);
parse_header_le16(fb, &header->addr_actions_vnjn);
parse_header_le16(fb, &header->addr_actions_vjn);
parse_header_le16(fb, &header->addr_actions_vdn);
}
if (game->info->_comprehendVersion >= 2) {
if (game->_comprehendVersion >= 2) {
parse_header_le16(fb, &header->addr_actions_vnjn);
parse_header_le16(fb, &header->addr_actions_vjn);
parse_header_le16(fb, &header->addr_actions_vnn);
@ -876,7 +926,7 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
*
* Layout is dependent on comprehend version.
*/
if (game->info->_comprehendVersion == 1) {
if (game->_comprehendVersion == 1) {
parse_header_le16(fb, &header->addr_item_locations);
parse_header_le16(fb, &header->addr_item_flags);
parse_header_le16(fb, &header->addr_item_word);
@ -902,16 +952,16 @@ static void parse_header(ComprehendGame * game, struct file_buf * fb) {
parse_header_le16(fb, &header->addr_strings_end);
file_buf_get_u8(fb, &dummy8);
file_buf_get_u8(fb, &game->info->_startRoom);
file_buf_get_u8(fb, &game->_startRoom);
file_buf_get_u8(fb, &dummy8);
parse_variables(game, fb);
parse_flags(game, fb);
game->info->_nr_rooms = header->room_direction_table[DIRECTION_SOUTH] -
game->_nr_rooms = header->room_direction_table[DIRECTION_SOUTH] -
header->room_direction_table[DIRECTION_NORTH];
game->info->_nr_words = (addr_dictionary_end -
game->_nr_words = (addr_dictionary_end -
header->addr_dictionary) /
8;
}
@ -929,7 +979,7 @@ static void load_extra_string_file(ComprehendGame * game,
end = fb.size;
parse_string_table(&fb, string_file->base_offset,
end, &game->info->_strings2);
end, &game->_strings2);
file_buf_unmap(&fb);
}
@ -937,16 +987,16 @@ static void load_extra_string_file(ComprehendGame * game,
static void load_extra_string_files(ComprehendGame * game) {
int i;
memset(&game->info->_strings2, 0, sizeof(game->info->_strings2));
memset(&game->_strings2, 0, sizeof(game->_strings2));
for (i = 0; i < ARRAY_SIZE(game->_stringFiles); i++) {
if (!game->_stringFiles[i].filename)
break;
// HACK - get string offsets correct
game->info->_strings2.nr_strings = 0x40 * i;
if (game->info->_strings2.nr_strings == 0)
game->info->_strings2.nr_strings++;
game->_strings2.nr_strings = 0x40 * i;
if (game->_strings2.nr_strings == 0)
game->_strings2.nr_strings++;
load_extra_string_file(game, &game->_stringFiles[i]);
}
@ -955,7 +1005,7 @@ static void load_extra_string_files(ComprehendGame * game) {
static void load_game_data(ComprehendGame * game) {
struct file_buf fb;
memset(game->info, 0, sizeof(*game->info));
game->clearInfo();
file_buf_map(game->_gameDataFile, &fb);
parse_header(game, &fb);
@ -963,10 +1013,10 @@ static void load_game_data(ComprehendGame * game) {
parse_items(game, &fb);
parse_dictionary(game, &fb);
parse_word_map(game, &fb);
memset(&game->info->_strings, 0, sizeof(game->info->_strings));
parse_string_table(&fb, game->info->_header.addr_strings,
game->info->_header.addr_strings_end,
&game->info->_strings);
memset(&game->_strings, 0, sizeof(game->_strings));
parse_string_table(&fb, game->_header.addr_strings,
game->_header.addr_strings_end,
&game->_strings);
load_extra_string_files(game);
parse_vm(game, &fb);
parse_action_table(game, &fb);
@ -986,7 +1036,7 @@ void comprehend_load_game(ComprehendGame * game) {
}
/* FIXME - This can be merged, don't need to keep start room around */
game->info->_currentRoom = game->info->_startRoom;
game->_currentRoom = game->_startRoom;
}
#ifdef TODO
@ -1018,22 +1068,22 @@ void comprehend_save_game(ComprehendGame * game, const char *filename) {
return;
}
nr_rooms = game->info->nr_rooms;
nr_items = game->info->header.nr_items;
nr_rooms = game->nr_rooms;
nr_items = game->header.nr_items;
file_buf_put_u8(fd, 0);
file_buf_put_u8(fd, game->info->current_room);
file_buf_put_u8(fd, game->current_room);
file_buf_put_u8(fd, 0);
/* Variables */
for (i = 0; i < ARRAY_SIZE(game->info->variable); i++)
file_buf_put_le16(fd, game->info->variable[i]);
for (i = 0; i < ARRAY_SIZE(game->variable); i++)
file_buf_put_le16(fd, game->variable[i]);
/* Flags */
for (flag_index = 0, i = 0; i < ARRAY_SIZE(game->info->flags) / 8; i++) {
for (flag_index = 0, i = 0; i < ARRAY_SIZE(game->flags) / 8; i++) {
bitmask = 0;
for (bit = 7; bit >= 0; bit--) {
bitmask |= (!!game->info->flags[flag_index]) << bit;
bitmask |= (!!game->flags[flag_index]) << bit;
flag_index++;
}
@ -1048,19 +1098,19 @@ void comprehend_save_game(ComprehendGame * game, const char *filename) {
file_buf_put_skip(fd, 0x12c - ftell(fd));
file_buf_put_u8(fd, nr_items);
if (game->info->comprehend_version == 1)
if (game->comprehend_version == 1)
file_buf_put_skip(fd, 0x230 - ftell(fd));
else
file_buf_put_skip(fd, 0x130 - ftell(fd));
/* Rooms */
file_buf_put_array_le16(fd, 1, game->info->rooms,
file_buf_put_array_le16(fd, 1, game->rooms,
string_desc, nr_rooms);
for (dir = 0; dir < NR_DIRECTIONS; dir++)
file_buf_put_array_u8(fd, 1, game->info->rooms,
file_buf_put_array_u8(fd, 1, game->rooms,
direction[dir], nr_rooms);
file_buf_put_array_u8(fd, 1, game->info->rooms, flags, nr_rooms);
file_buf_put_array_u8(fd, 1, game->info->rooms, graphic, nr_rooms);
file_buf_put_array_u8(fd, 1, game->rooms, flags, nr_rooms);
file_buf_put_array_u8(fd, 1, game->rooms, graphic, nr_rooms);
/*
* Objects
@ -1068,18 +1118,18 @@ void comprehend_save_game(ComprehendGame * game, const char *filename) {
* Layout differs depending on Comprehend version. Version 2 also
* has long string descriptions for each object.
*/
file_buf_put_array_le16(fd, 0, game->info->item, string_desc, nr_items);
if (game->info->comprehend_version == 1) {
file_buf_put_array_u8(fd, 0, game->info->item, room, nr_items);
file_buf_put_array_u8(fd, 0, game->info->item, flags, nr_items);
file_buf_put_array_u8(fd, 0, game->info->item, word, nr_items);
file_buf_put_array_u8(fd, 0, game->info->item, graphic, nr_items);
file_buf_put_array_le16(fd, 0, game->item, string_desc, nr_items);
if (game->comprehend_version == 1) {
file_buf_put_array_u8(fd, 0, game->item, room, nr_items);
file_buf_put_array_u8(fd, 0, game->item, flags, nr_items);
file_buf_put_array_u8(fd, 0, game->item, word, nr_items);
file_buf_put_array_u8(fd, 0, game->item, graphic, nr_items);
} else {
file_buf_put_array_le16(fd, 0, game->info->item, long_string, nr_items);
file_buf_put_array_u8(fd, 0, game->info->item, word, nr_items);
file_buf_put_array_u8(fd, 0, game->info->item, room, nr_items);
file_buf_put_array_u8(fd, 0, game->info->item, flags, nr_items);
file_buf_put_array_u8(fd, 0, game->info->item, graphic, nr_items);
file_buf_put_array_le16(fd, 0, game->item, long_string, nr_items);
file_buf_put_array_u8(fd, 0, game->item, word, nr_items);
file_buf_put_array_u8(fd, 0, game->item, room, nr_items);
file_buf_put_array_u8(fd, 0, game->item, flags, nr_items);
file_buf_put_array_u8(fd, 0, game->item, graphic, nr_items);
}
fclose(fd);
@ -1101,12 +1151,12 @@ void comprehend_restore_game(ComprehendGame * game, const char *filename) {
return;
}
nr_rooms = game->info->nr_rooms;
nr_items = game->info->header.nr_items;
nr_rooms = game->nr_rooms;
nr_items = game->header.nr_items;
/* Restore starting room */
file_buf_set_pos(&fb, 1);
file_buf_get_u8(&fb, &game->info->current_room);
file_buf_get_u8(&fb, &game->current_room);
/* Restore flags and variables */
file_buf_set_pos(&fb, 3);
@ -1114,19 +1164,19 @@ void comprehend_restore_game(ComprehendGame * game, const char *filename) {
parse_flags(game, &fb);
/* FIXME - unknown restore data, skip over it */
if (game->info->comprehend_version == 1)
if (game->comprehend_version == 1)
file_buf_set_pos(&fb, 0x230);
else
file_buf_set_pos(&fb, 0x130);
/* Restore rooms */
file_buf_get_array_le16(&fb, 1, game->info->rooms,
file_buf_get_array_le16(&fb, 1, game->rooms,
string_desc, nr_rooms);
for (dir = 0; dir < NR_DIRECTIONS; dir++)
file_buf_get_array_u8(&fb, 1, game->info->rooms,
file_buf_get_array_u8(&fb, 1, game->rooms,
direction[dir], nr_rooms);
file_buf_get_array_u8(&fb, 1, game->info->rooms, flags, nr_rooms);
file_buf_get_array_u8(&fb, 1, game->info->rooms, graphic, nr_rooms);
file_buf_get_array_u8(&fb, 1, game->rooms, flags, nr_rooms);
file_buf_get_array_u8(&fb, 1, game->rooms, graphic, nr_rooms);
/*
* Restore objects
@ -1134,18 +1184,18 @@ void comprehend_restore_game(ComprehendGame * game, const char *filename) {
* Layout differs depending on Comprehend version. Version 2 also
* has long string descriptions for each object.
*/
file_buf_get_array_le16(&fb, 0, game->info->item, string_desc, nr_items);
if (game->info->comprehend_version == 1) {
file_buf_get_array_u8(&fb, 0, game->info->item, room, nr_items);
file_buf_get_array_u8(&fb, 0, game->info->item, flags, nr_items);
file_buf_get_array_u8(&fb, 0, game->info->item, word, nr_items);
file_buf_get_array_u8(&fb, 0, game->info->item, graphic, nr_items);
file_buf_get_array_le16(&fb, 0, game->item, string_desc, nr_items);
if (game->comprehend_version == 1) {
file_buf_get_array_u8(&fb, 0, game->item, room, nr_items);
file_buf_get_array_u8(&fb, 0, game->item, flags, nr_items);
file_buf_get_array_u8(&fb, 0, game->item, word, nr_items);
file_buf_get_array_u8(&fb, 0, game->item, graphic, nr_items);
} else {
file_buf_get_array_le16(&fb, 0, game->info->item, long_string, nr_items);
file_buf_get_array_u8(&fb, 0, game->info->item, word, nr_items);
file_buf_get_array_u8(&fb, 0, game->info->item, room, nr_items);
file_buf_get_array_u8(&fb, 0, game->info->item, flags, nr_items);
file_buf_get_array_u8(&fb, 0, game->info->item, graphic, nr_items);
file_buf_get_array_le16(&fb, 0, game->item, long_string, nr_items);
file_buf_get_array_u8(&fb, 0, game->item, word, nr_items);
file_buf_get_array_u8(&fb, 0, game->item, room, nr_items);
file_buf_get_array_u8(&fb, 0, game->item, flags, nr_items);
file_buf_get_array_u8(&fb, 0, game->item, graphic, nr_items);
}
/*
@ -1153,9 +1203,9 @@ void comprehend_restore_game(ComprehendGame * game, const char *filename) {
* Not sure what this means, so just mask it out for now.
*/
for (i = 1; i <= nr_rooms; i++)
patch_string_desc(&game->info->rooms[i].string_desc);
patch_string_desc(&game->rooms[i].string_desc);
for (i = 0; i < nr_items; i++)
patch_string_desc(&game->info->item[i].string_desc);
patch_string_desc(&game->item[i].string_desc);
file_buf_unmap(&fb);
#else

View File

@ -51,7 +51,11 @@ struct function_state {
bool in_command;
bool executed;
function_state();
function_state() {
clear();
}
void clear();
};
struct room {
@ -60,7 +64,11 @@ struct room {
uint8 graphic;
uint16 string_desc;
room();
room() {
clear();
}
void clear();
};
struct item {
@ -71,7 +79,11 @@ struct item {
uint8 word;
uint8 graphic;
item();
item() {
clear();
}
void clear();
};
struct word {
@ -79,14 +91,24 @@ struct word {
uint8 _index;
uint8 _type;
word();
word() {
clear();
}
void clear();
};
struct word_index {
uint8 index;
uint8 type;
word_index() : index(0), type(0) {}
word_index() {
clear();
}
void clear() {
index = type = 0;
}
};
struct word_map {
@ -94,7 +116,11 @@ struct word_map {
word_index word[3];
uint8 flags;
word_map() : flags(0) {}
word_map() {
clear();
}
void clear();
};
struct action {
@ -105,7 +131,11 @@ struct action {
uint8 word_type[4];
uint16 function;
action();
action() {
clear();
}
void clear();
};
struct instruction {
@ -114,21 +144,33 @@ struct instruction {
uint8 operand[3];
bool is_command;
instruction();
instruction() {
clear();
}
void clear();
};
struct function {
instruction instructions[0x100];
size_t nr_instructions;
function() : nr_instructions(0) {}
function() {
clear();
}
void clear();
};
struct string_table {
char *strings[0xffff];
size_t nr_strings;
string_table();
string_table() {
clear();
}
void clear();
};
struct game_header {
@ -163,10 +205,14 @@ struct game_header {
uint16 addr_vm; // FIXME - functions
game_header();
game_header() {
clear();
}
void clear();
};
struct game_info {
struct GameInfo {
game_header _header;
unsigned _comprehendVersion;
@ -177,7 +223,7 @@ struct game_info {
size_t _nr_rooms;
uint8 _currentRoom;
struct item _item[0xff];
struct item _items[0xff];
struct word *_words;
size_t _nr_words;
@ -206,7 +252,11 @@ struct game_info {
uint8 _currentReplaceWord;
unsigned _updateFlags;
game_info();
GameInfo() {
clearInfo();
}
void clearInfo();
};
struct string_file {

View File

@ -61,11 +61,11 @@ OOToposGame::OOToposGame() : ComprehendGame() {
int OOToposGame::room_is_special(unsigned room_index,
unsigned *room_desc_string) {
room *room = &info->_rooms[room_index];
room *room = &_rooms[room_index];
/* Is the room dark */
if ((room->flags & OO_ROOM_FLAG_DARK) &&
!(info->_flags[OO_FLAG_FLASHLIGHT_ON])) {
!(_flags[OO_FLAG_FLASHLIGHT_ON])) {
if (room_desc_string)
*room_desc_string = 0xb3;
return ROOM_IS_DARK;
@ -73,7 +73,7 @@ int OOToposGame::room_is_special(unsigned room_index,
/* Is the room too bright */
if (room_index == OO_BRIGHT_ROOM &&
!info->_flags[OO_FLAG_WEARING_GOGGLES]) {
!_flags[OO_FLAG_WEARING_GOGGLES]) {
if (room_desc_string)
*room_desc_string = 0x1c;
return ROOM_IS_TOO_BRIGHT;
@ -85,26 +85,26 @@ int OOToposGame::room_is_special(unsigned room_index,
bool OOToposGame::before_turn() {
/* FIXME - probably doesn't work correctly with restored games */
static bool flashlight_was_on = false, googles_were_worn = false;
struct room *room = &info->_rooms[info->_currentRoom];
struct room *room = &_rooms[_currentRoom];
/*
* Check if the room needs to be redrawn because the flashlight
* was switch off or on.
*/
if (info->_flags[OO_FLAG_FLASHLIGHT_ON] != flashlight_was_on &&
if (_flags[OO_FLAG_FLASHLIGHT_ON] != flashlight_was_on &&
(room->flags & OO_ROOM_FLAG_DARK)) {
flashlight_was_on = info->_flags[OO_FLAG_FLASHLIGHT_ON];
info->_updateFlags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
flashlight_was_on = _flags[OO_FLAG_FLASHLIGHT_ON];
_updateFlags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
}
/*
* Check if the room needs to be redrawn because the goggles were
* put on or removed.
*/
if (info->_flags[OO_FLAG_WEARING_GOGGLES] != googles_were_worn &&
info->_currentRoom == OO_BRIGHT_ROOM) {
googles_were_worn = info->_flags[OO_FLAG_WEARING_GOGGLES];
info->_updateFlags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
if (_flags[OO_FLAG_WEARING_GOGGLES] != googles_were_worn &&
_currentRoom == OO_BRIGHT_ROOM) {
googles_were_worn = _flags[OO_FLAG_WEARING_GOGGLES];
_updateFlags |= UPDATE_GRAPHICS | UPDATE_ROOM_DESC;
}
return false;

View File

@ -69,17 +69,17 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
struct room *room;
uint16 turn_count;
room = &info->_rooms[info->_currentRoom];
turn_count = info->_variables[VAR_TURN_COUNT];
room = &_rooms[_currentRoom];
turn_count = _variables[VAR_TURN_COUNT];
monster = get_item(this, monster_info->object);
if (monster->room == info->_currentRoom) {
if (monster->room == _currentRoom) {
/* The monster is in the current room - leave it there */
return;
}
if ((room->flags & monster_info->room_allow_flag) &&
!info->_flags[monster_info->dead_flag] &&
!_flags[monster_info->dead_flag] &&
turn_count > monster_info->min_turns_before) {
/*
* The monster is alive and allowed to move to the current
@ -87,8 +87,8 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
* it back to limbo.
*/
if ((g_comprehend->getRandomNumber(0x7fffffff) % monster_info->randomness) == 0) {
move_object(this, monster, info->_currentRoom);
info->_variables[0xf] = turn_count + 1;
move_object(this, monster, _currentRoom);
_variables[0xf] = turn_count + 1;
} else {
move_object(this, monster, ROOM_NOWHERE);
}
@ -98,7 +98,7 @@ void TransylvaniaGame::update_monster(const tr_monster *monster_info) {
int TransylvaniaGame::room_is_special(unsigned room_index,
unsigned *room_desc_string)
{
struct room *room = &info->_rooms[room_index];
struct room *room = &_rooms[room_index];
if (room_index == 0x28) {
if (room_desc_string)
@ -151,9 +151,9 @@ void TransylvaniaGame::handle_special_opcode(uint8 operand)
* Show the Zin screen in reponse to doing 'sing some enchanted
* evening' in his cabin.
*/
draw_location_image(&info->_roomImages, 41);
draw_location_image(&_roomImages, 41);
console_get_key();
info->_updateFlags |= UPDATE_GRAPHICS;
_updateFlags |= UPDATE_GRAPHICS;
break;
}
}
@ -179,7 +179,7 @@ void TransylvaniaGame::before_game() {
char buffer[128];
/* Welcome to Transylvania - sign your name */
console_println(this, info->_strings.strings[0x20]);
console_println(this, _strings.strings[0x20]);
read_string(buffer, sizeof(buffer));
/*
@ -188,15 +188,15 @@ void TransylvaniaGame::before_game() {
* limited (the original game will break if you put a name in that
* is too long).
*/
if (!info->_replaceWords[0])
info->_replaceWords[0] = xstrndup(buffer, strlen(buffer));
if (!_replaceWords[0])
_replaceWords[0] = xstrndup(buffer, strlen(buffer));
else
snprintf(info->_replaceWords[0],
strlen(info->_replaceWords[0]),
snprintf(_replaceWords[0],
strlen(_replaceWords[0]),
"%s", buffer);
/* And your next of kin - This isn't store by the game */
console_println(this, info->_strings.strings[0x21]);
console_println(this, _strings.strings[0x21]);
read_string(buffer, sizeof(buffer));
}

View File

@ -46,6 +46,12 @@ struct image_context {
static unsigned draw_flags;
void image_data::clear() {
fb = nullptr;
image_offsets = nullptr;
nr_images = 0;
}
void image_set_draw_flags(unsigned flags)
{
draw_flags |= flags;
@ -349,10 +355,10 @@ void comprehend_load_image_file(const char *filename, struct image_data *info)
}
void comprehend_load_images(ComprehendGame *game) {
load_image_files(&game->info->_roomImages,
load_image_files(&game->_roomImages,
game->_locationGraphicFiles);
load_image_files(&game->info->_itemImages,
load_image_files(&game->_itemImages,
game->_itemGraphicFiles);
}

View File

@ -35,6 +35,12 @@ struct image_data {
file_buf *fb;
uint16 *image_offsets;
size_t nr_images;
image_data() {
clear();
}
void clear();
};
#define IMAGEF_OP_WAIT_KEYPRESS (1 << 0)

View File

@ -175,7 +175,7 @@ static uint8 opcode_map_v2[0x100] = {
uint8 *get_opcode_map(ComprehendGame *game)
{
switch (game->info->_comprehendVersion) {
switch (game->_comprehendVersion) {
case 1:
return opcode_map_v1;
break;
@ -183,7 +183,7 @@ uint8 *get_opcode_map(ComprehendGame *game)
return opcode_map_v2;
default:
fatal_error("Unsupported Comprehend version %d\n",
game->info->_comprehendVersion);
game->_comprehendVersion);
/* Not reached */
return NULL;

View File

@ -55,8 +55,8 @@ const char *string_lookup(ComprehendGame *game, uint16 index)
/* Fall-through */
case 0x00:
case 0x80:
if (string < game->info->_strings.nr_strings)
return game->info->_strings.strings[string];
if (string < game->_strings.nr_strings)
return game->_strings.strings[string];
break;
case 0x83:
@ -64,8 +64,8 @@ const char *string_lookup(ComprehendGame *game, uint16 index)
/* Fall-through */
case 0x02:
case 0x82:
if (string < game->info->_strings2.nr_strings)
return game->info->_strings2.strings[string];
if (string < game->_strings2.nr_strings)
return game->_strings2.strings[string];
break;
}