Added experimental (i.e. not tested) resource dumping code.

Added tentative workaround for the bug (a script bug, I think) that causes
the game to hang when examining the lift at the top of the pyramid.

And, of course, some misc. cleanup.

svn-id: r11359
This commit is contained in:
Torbjörn Andersson 2003-11-23 13:40:24 +00:00
parent cc0da57553
commit 509235e176
8 changed files with 230 additions and 227 deletions

View File

@ -50,46 +50,47 @@ struct _standardHeader {
uint8 name[NAME_LEN]; // Name of object
} GCC_PACK;
//----------------------------------------------------------
// fileType
// 0 something's wrong!
#define ANIMATION_FILE 1 // All normal animations & sprites
enum {
// 0 something's wrong!
ANIMATION_FILE = 1, // All normal animations & sprites
// including mega-sets & font files
// which are the same format (but all
// frames always uncompressed)
#define SCREEN_FILE 2 // Each contains background, palette,
SCREEN_FILE = 2, // Each contains background, palette,
// layer sprites, parallax layers &
// shading mask
#define GAME_OBJECT 3 // Each contains object hub +
GAME_OBJECT = 3, // Each contains object hub +
// structures + script data
#define WALK_GRID_FILE 4 // Walk-grid data
#define GLOBAL_VAR_FILE 5 // All the global script variables in
WALK_GRID_FILE = 4, // Walk-grid data
GLOBAL_VAR_FILE = 5, // All the global script variables in
// one file; "there can be only one"
#define PARALLAX_FILE_null 6 // NOT USED
#define RUN_LIST 7 // Each contains a list of object
PARALLAX_FILE_null = 6, // NOT USED
RUN_LIST = 7, // Each contains a list of object
// resource id's
#define TEXT_FILE 8 // Each contains all the lines of text
TEXT_FILE = 8, // Each contains all the lines of text
// for a location or a character's
// conversation script
#define SCREEN_MANAGER 9 // One for each location; this contains
SCREEN_MANAGER = 9, // One for each location; this contains
// special startup scripts
#define MOUSE_FILE 10 // Mouse pointers and luggage icons
MOUSE_FILE = 10, // Mouse pointers and luggage icons
// (sprites in General / Mouse pointers
// & Luggage icons)
#define WAV_FILE 11 // WAV file
#define ICON_FILE 12 // Menu icon (sprites in General \ Menu
// icons
#define PALETTE_FILE 13 // separate palette file (see also
WAV_FILE = 11, // WAV file
ICON_FILE = 12, // Menu icon (sprites in General / Menu
// icons)
PALETTE_FILE = 13 // separate palette file (see also
// _paletteHeader)
};
//----------------------------------------------------------
// compType
#define NO_COMPRESSION 0
#define FILE_COMPRESSION 1 // standard whole-file compression
enum {
NO_COMPRESSION = 0,
FILE_COMPRESSION = 1 // standard whole-file compression
// (not yet devised!)
};
//----------------------------------------------------------
// (1) ANIMATION FILES
@ -103,7 +104,6 @@ struct _standardHeader {
// a 16-byte colour table ONLY if (runTimeComp==RLE16)
// a string of groups of (frame header + frame data)
//----------------------------------------------------------
// Animation Header
struct _animHeader {
@ -122,17 +122,17 @@ struct _animHeader {
uint16 blend;
} GCC_PACK;
//----------------------------------------------------------
// runtimeComp - compression used on each frame of the anim
#define NONE 0 // No frame compression
#define RLE256 1 // James's RLE for 256-colour sprites
#define RLE16 2 // James's RLE for 16- or 17-colour sprites
enum {
NONE = 0, // No frame compression
RLE256 = 1, // James's RLE for 256-colour sprites
RLE16 = 2 // James's RLE for 16- or 17-colour sprites
// (raw blocks have max 16 colours for 2 pixels
// per byte, so '0's are encoded only as FLAT
// for 17-colour sprites eg. George's mega-set)
};
//----------------------------------------------------------
// CDT Entry
struct _cdtEntry {
@ -147,14 +147,16 @@ struct _cdtEntry {
} GCC_PACK;
// 'frameType' bit values
#define FRAME_OFFSET 1 // Print at (feetX + x, feetY + y), with
// scaling according to feetY
#define FRAME_FLIPPED 2 // Print the frame flipped Left->Right
#define FRAME_256_FAST 4 // Frame has been compressed using Pauls fast
// RLE 256 compression.
//----------------------------------------------------------
//Frame Header
enum {
FRAME_OFFSET = 1, // Print at (feetX + x, feetY + y), with
// scaling according to feetY
FRAME_FLIPPED = 2, // Print the frame flipped Left->Right
FRAME_256_FAST = 4 // Frame has been compressed using Pauls fast
// RLE 256 compression.
};
// Frame Header
struct _frameHeader {
uint32 compSize; // Compressed size of frame - NB. compression
@ -178,7 +180,6 @@ struct _frameHeader {
// a string of layer headers
// a string of layer masks
//----------------------------------------------------------
// Multi screen header
// Goes at the beginning of a screen file after the standard header.
// Gives offsets from start of table of each of the components
@ -193,7 +194,6 @@ struct _multiScreenHeader {
uint32 maskOffset;
} GCC_PACK;
//------------------------------------------------------------
// Palette Data
struct _palEntry {
@ -203,7 +203,6 @@ struct _palEntry {
uint8 alpha;
} GCC_PACK;
//------------------------------------------------------------
// Screen Header
struct _screenHeader {
@ -212,12 +211,10 @@ struct _screenHeader {
uint16 noLayers; // number of layer areas
} GCC_PACK;
//------------------------------------------------------------
// Layer Header
// Note that all the layer headers are kept together,
// rather than being placed before each layer mask,
// in order to simplify the sort routine.
// Note that all the layer headers are kept together, rather than being placed
// before each layer mask, in order to simplify the sort routine.
struct _layerHeader {
uint16 x; // coordinates of top-left pixel of area
@ -247,7 +244,6 @@ struct _layerHeader {
// walk-grid file header
// walk-grid data
//----------------------------------------------------------
// Walk-Grid Header - taken directly from old "header.h" in STD_INC
struct _walkGridHeader {
@ -264,8 +260,6 @@ struct _walkGridHeader {
// 4 * 256 bytes of palette data
// 256k palette match table
//----------------------------------------------------------
// an object hub - which represents all that remains of the compact concept
#define TREE_SIZE 3
@ -293,8 +287,6 @@ struct _textHeader {
// line of text,0
// line of text,0
// ----------------------------------------------------------
#if !defined(__GNUC__)
#pragma END_PACK_STRUCTS
#endif

View File

@ -18,6 +18,7 @@
*/
#include "common/stdafx.h"
#include "common/util.h"
#include "sword2/sword2.h"
#include "sword2/interpreter.h"
@ -193,6 +194,9 @@ void Logic::setupOpcodes(void) {
int32 Logic::executeOpcode(int i, int32 *params) {
OpcodeProc op = _opcodes[i].proc;
debug(5, "%s", _opcodes[i].desc);
return (this->*op) (params);
}
@ -315,8 +319,6 @@ int Logic::runScript(char *scriptData, char *objectData, uint32 *offset) {
assert(parameter <= MAX_FN_NUMBER);
// amount to adjust stack by (no of parameters)
Read8ip(value);
debug(5, "Call mcode %d with stack = %x", parameter, stack2 + stackPointer2 - value);
retVal = executeOpcode(parameter, stack2 + stackPointer2 - value);
stackPointer2 -= value;

View File

@ -53,7 +53,7 @@ int Logic::processSession(void) {
// processing on the current list
while (_pc != 0xffffffff) {
head = (_standardHeader*) _vm->_resman->openResource(run_list);
head = (_standardHeader *) _vm->_resman->openResource(run_list);
if (head->fileType != RUN_LIST)
error("Logic_engine %d not a run_list", run_list);
@ -77,7 +77,7 @@ int Logic::processSession(void) {
return 0;
}
head = (_standardHeader*) _vm->_resman->openResource(ID);
head = (_standardHeader *) _vm->_resman->openResource(ID);
if (head->fileType != GAME_OBJECT)
error("Logic_engine %d not an object", ID);
@ -111,7 +111,7 @@ int Logic::processSession(void) {
// this is the script data
// raw_script_ad = (char *) (_curObjectHub + 1);
raw_script_ad = (char*) head;
raw_script_ad = (char *) head;
// script and data object are us/same
ret = runScript(raw_script_ad, raw_script_ad, &_curObjectHub->script_pc[LEVEL]);
@ -121,19 +121,19 @@ int Logic::processSession(void) {
// get the foreign objects script data address
raw_data_ad = (char*) head;
raw_data_ad = (char *) head;
far_head = (_standardHeader*) _vm->_resman->openResource(script / SIZE);
if (far_head->fileType != GAME_OBJECT && far_head->fileType != SCREEN_MANAGER)
error("Logic_engine %d not a far object (its a %d)", script / SIZE, far_head->fileType);
// raw_script_ad = (char*) (head + 1) + sizeof(_standardHeader);
// raw_script_ad = (char *) (head + 1) + sizeof(_standardHeader);
// get our objects data address
// raw_data_ad = (char*) (_curObjectHub + 1);
// raw_data_ad = (char *) (_curObjectHub + 1);
raw_script_ad = (char*) far_head;
raw_script_ad = (char *) far_head;
ret = runScript(raw_script_ad, raw_data_ad, &_curObjectHub->script_pc[LEVEL]);

View File

@ -331,7 +331,7 @@ void Sword2Engine::dragMouse(void) {
_logic->setPlayerActionEvent(CUR_PLAYER_ID, _mouseTouching);
debug(5, "Used \"%s\" on \"%s\"", fetchObjectName(OBJECT_HELD), fetchObjectName(CLICKED_ID));
debug(2, "Used \"%s\" on \"%s\"", fetchObjectName(OBJECT_HELD), fetchObjectName(CLICKED_ID));
// Hide menu - back to normal menu mode
@ -647,7 +647,26 @@ void Sword2Engine::normalMouse(void) {
EXIT_CLICK_ID = 0;
EXIT_FADING = 0;
_logic->setPlayerActionEvent(CUR_PLAYER_ID, _mouseTouching);
// WORKAROUND: Examining the lift while at the top of the
// pyramid causes the game to hang. It looks like a script
// bug to me: the script hides the mouse cursor, checks if the
// player pressed the left mouse button and, if not, jumps to
// an end of script instruction.
//
// One idea would be to redirect the action to the elevator
// object at the bottom of the pyramid instead, but I don't
// know if that's a safe thing to do so for now I've disabled
// it. Maybe we could find a better workaround if we had a
// script decompiler...
//
// I'm checking the status of the left button rather than the
// right button because that's what I think the script does.
if (_mouseTouching == 2773 && !LEFT_BUTTON) {
warning("Ignoring action to work around script bug at pyramid top");
// _logic->setPlayerActionEvent(CUR_PLAYER_ID, 2737);
} else
_logic->setPlayerActionEvent(CUR_PLAYER_ID, _mouseTouching);
if (OBJECT_HELD)
debug(2, "Used \"%s\" on \"%s\"", fetchObjectName(OBJECT_HELD), fetchObjectName(CLICKED_ID));

View File

@ -27,29 +27,16 @@
namespace Sword2 {
// ---------------------------------------------------------------------------
// welcome to the easy resource manager - written in simple code for easy
// Welcome to the easy resource manager - written in simple code for easy
// maintenance
//
// the resource compiler will create two files
// The resource compiler will create two files
//
// resource.inf which is a list of ascii cluster file names
// resource.tab which is a table which tells us which cluster a resource
// is located in and the number within the cluster
// ---------------------------------------------------------------------------
#define NONE 0
#define FETCHING 1
#define BUFFERSIZE 4096
// ---------------------------------------------------------------------------
//
//
// resman.
//
//
// ---------------------------------------------------------------------------
enum {
BOTH = 0x0, // Cluster is on both CDs
CD1 = 0x1, // Cluster is on CD1 only
@ -214,7 +201,7 @@ ResourceManager::~ResourceManager(void) {
void convertEndian(uint8 *file, uint32 len) {
int i;
_standardHeader *hdr = (_standardHeader *)file;
_standardHeader *hdr = (_standardHeader *) file;
file += sizeof(_standardHeader);
@ -223,7 +210,7 @@ void convertEndian(uint8 *file, uint32 len) {
switch (hdr->fileType) {
case ANIMATION_FILE: {
_animHeader *animHead = (_animHeader *)file;
_animHeader *animHead = (_animHeader *) file;
SWAP16(animHead->noAnimFrames);
SWAP16(animHead->feetStartX);
@ -360,7 +347,7 @@ void convertEndian(uint8 *file, uint32 len) {
}
uint16 *node = (uint16 *) (file + sizeof(_walkGridHeader) + walkGridHeader->numBars * sizeof(_barData));
for (i = 0; i < walkGridHeader->numNodes*2; i++) {
for (i = 0; i < walkGridHeader->numNodes * 2; i++) {
SWAP16(*node);
node++;
}
@ -372,7 +359,7 @@ void convertEndian(uint8 *file, uint32 len) {
case PARALLAX_FILE_null:
break;
case RUN_LIST: {
uint32 *list = (uint32 *)file;
uint32 *list = (uint32 *) file;
while (*list) {
SWAP32(*list);
list++;
@ -380,7 +367,7 @@ void convertEndian(uint8 *file, uint32 len) {
break;
}
case TEXT_FILE: {
_textHeader *textHeader = (_textHeader *)file;
_textHeader *textHeader = (_textHeader *) file;
SWAP32(textHeader->noOfLines);
break;
}
@ -393,7 +380,7 @@ void convertEndian(uint8 *file, uint32 len) {
}
}
uint8 *ResourceManager::openResource(uint32 res) {
uint8 *ResourceManager::openResource(uint32 res, bool dump) {
// returns ad of resource. Loads if not in memory
// retains a count
// resource can be aged out of memory if count = 0
@ -407,10 +394,7 @@ uint8 *ResourceManager::openResource(uint32 res) {
uint32 table_offset;
//#ifdef _SWORD2_DEBUG
if (res >= _totalResFiles)
error("open illegal resource %d (there are %d resources 0-%d)", res, _totalResFiles, _totalResFiles - 1);
//#endif
assert(res < _totalResFiles);
// is the resource in memory already?
// if the file is not in memory then age should and MUST be 0
@ -422,10 +406,7 @@ uint8 *ResourceManager::openResource(uint32 res) {
// points to the number of the ascii filename
parent_res_file = _resConvTable[res * 2];
//#ifdef _SWORD2_DEBUG
if (parent_res_file == 0xffff)
error("open tried to open null & void resource number %d", res);
//#endif
assert(parent_res_file != 0xffff);
// relative resource within the file
actual_res = _resConvTable[(res * 2) + 1];
@ -438,9 +419,8 @@ uint8 *ResourceManager::openResource(uint32 res) {
// of the CDs, remember which one so that we can play the
// correct music.
if (!(_cdTab[parent_res_file] & LOCAL_PERM)) {
if (!(_cdTab[parent_res_file] & LOCAL_PERM))
_curCd = _cdTab[parent_res_file] & 3;
}
// Actually, as long as the file can be found we don't really
// care which CD it's on. But if we can't find it, keep asking
@ -482,6 +462,69 @@ uint8 *ResourceManager::openResource(uint32 res) {
// hurray, load it in.
file.read(_resList[res]->ad, len);
if (dump) {
_standardHeader *header = (_standardHeader *) _resList[res]->ad;
char buf[256];
char tag[10];
File out;
switch (header->fileType) {
case ANIMATION_FILE:
strcpy(tag, "anim");
break;
case SCREEN_FILE:
strcpy(tag, "layer");
break;
case GAME_OBJECT:
strcpy(tag, "object");
break;
case WALK_GRID_FILE:
strcpy(tag, "walkgrid");
break;
case GLOBAL_VAR_FILE:
strcpy(tag, "globals");
break;
case PARALLAX_FILE_null:
strcpy(tag, "parallax"); // Not used!
break;
case RUN_LIST:
strcpy(tag, "runlist");
break;
case TEXT_FILE:
strcpy(tag, "text");
break;
case SCREEN_MANAGER:
strcpy(tag, "screen");
break;
case MOUSE_FILE:
strcpy(tag, "mouse");
break;
case ICON_FILE:
strcpy(tag, "icon");
break;
default:
strcpy(tag, "unknown");
break;
}
#if defined(MACOS_CARBON)
sprintf(buf, ":dumps:%s-%d", tag, res);
#else
sprintf(buf, "dumps/%s-%d", tag, res);
#endif
out.open(buf, "");
if (!out.isOpen()) {
out.open(buf, "", File::kFileWriteMode);
if (out.isOpen())
out.write(_resList[res]->ad, len);
}
if (out.isOpen())
out.close();
}
// close the cluster
file.close();
@ -489,7 +532,7 @@ uint8 *ResourceManager::openResource(uint32 res) {
convertEndian((uint8 *) _resList[res]->ad, len);
#endif
} else {
debug(5, "RO %d, already open count=%d", res, _count[res]);
debug(9, "RO %d, already open count=%d", res, _count[res]);
}
// number of times opened - the file won't move in memory while count
@ -530,17 +573,13 @@ uint8 ResourceManager::checkValid(uint32 res) {
void ResourceManager::nextCycle(void) {
// increment the cycle and calculate actual per-cycle memory useage
#ifdef _SWORD2_DEBUG
uint32 j;
#endif
#ifdef _SWORD2_DEBUG
_currentMemoryUsage = 0;
for (j = 1; j < _totalResFiles; j++) {
for (int i = 1; i < _totalResFiles; i++) {
// was accessed last cycle
if (_age[j] == _resTime)
_currentMemoryUsage += _resList[j]->size;
if (_age[i] == _resTime)
_currentMemoryUsage += _resList[i]->size;
}
#endif
@ -566,14 +605,8 @@ void ResourceManager::closeResource(uint32 res) {
// decrements the count
// resource floats when count = 0
//#ifdef _SWORD2_DEBUG
if (res >= _totalResFiles)
error("closing illegal resource %d (there are %d resources 0-%d)", res, _totalResFiles, _totalResFiles - 1);
//closing but isnt open?
if (!(_count[res]))
error("closeResource: closing %d but it isn't open", res);
//#endif
assert(res < _totalResFiles);
assert(_count[res]);
//one less has it open
_count[res]--;
@ -712,47 +745,12 @@ void ResourceManager::examine(int res) {
Debug_Printf("%d is a null & void resource number\n", res);
else {
// open up the resource and take a look inside!
file_header = (_standardHeader*) openResource(res);
file_header = (_standardHeader *) openResource(res);
// Debug_Printf("%d\n", file_header->fileType);
// Debug_Printf("%s\n", file_header->name);
//----------------------------------------------------
// resource types: (taken from header.h)
// 1: ANIMATION_FILE
// all normal animations & sprites including mega-sets &
// font files which are the same format
// 2: SCREEN_FILE
// each contains background, palette, layer sprites,
// parallax layers & shading mask
// 3: GAME_OBJECT
// each contains object hub + structures + script data
// 4: WALK_GRID_FILE
// walk-grid data
// 5: GLOBAL_VAR_FILE
// all the global script variables in one file; "there can
// be only one"
// 6: PARALLAX_FILE_null
// NOT USED
// 7: RUN_LIST
// each contains a list of object resource ids
// 8: TEXT_FILE
// each contains all the lines of text for a location or a
// character's conversation script
// 9: SCREEN_MANAGER
// one for each location; this contains special startup
// scripts
// 10: MOUSE_FILE
// mouse pointers and luggage icons (sprites in General,
// Mouse pointers & Luggage icons)
// 11: WAV_FILE
// NOT USED HERE
// 12: ICON_FILE
// menu icon (sprites in General and Menu icons)
// 13: PALETTE_FILE
// NOT USED HERE
//----------------------------------------------------
// Resource types. See header.h
switch (file_header->fileType) {
case ANIMATION_FILE:

View File

@ -36,7 +36,7 @@ public:
// The resource is locked while count != 0
// Resource floats when count = 0
uint8 *openResource(uint32 res);
uint8 *openResource(uint32 res, bool dump = false);
void closeResource(uint32 res); // decrements the count
// returns '0' if resource out of range or null, otherwise '1' for ok

View File

@ -87,15 +87,20 @@ int32 Logic::fnChoose(int32 *params) {
// the human is switched off so there will be no normal mouse engine
_mouseEvent *me;
uint32 j, hit;
uint32 i;
int hit;
uint8 *icon;
uint32 pos = 0;
AUTO_SELECTED = 0; // see below
// new thing to intercept objects held at time of clicking on a person
if (OBJECT_HELD) {
// So that, if there is no match, the speech script uses the
// default text for objects that are not accounted for
int response = _defaultResponseId;
// If we are using a luggage icon on the person, scan the
// subject list to see if this icon would have been available
// at this time.
@ -108,28 +113,20 @@ int32 Logic::fnChoose(int32 *params) {
// Note that we won't display the subject icons in this case!
// scan the subject list for a match with our 'object_held'
while (pos < IN_SUBJECT) {
if (_subjectList[pos].res == OBJECT_HELD) {
// if we've found a match, clear it so it
// doesn't keep happening!
OBJECT_HELD = 0;
// clear the subject list
IN_SUBJECT = 0;
// return special subject chosen code (same
for (i = 0; i < IN_SUBJECT; i++) {
if (_subjectList[i].res == OBJECT_HELD) {
// Return special subject chosen code (same
// as in normal chooser routine below)
return IR_CONT + (_subjectList[pos].ref << 3);
response = _subjectList[i].ref;
break;
}
pos++;
}
OBJECT_HELD = 0; // clear it so it doesn't keep happening!
IN_SUBJECT = 0; // clear the subject list
// so that the speech script uses the default text for
// objects that are not accounted for
return IR_CONT + (_defaultResponseId << 3);
return IR_CONT + (response << 3);
}
// new thing for skipping chooser with "nothing else to say" text
@ -156,16 +153,16 @@ int32 Logic::fnChoose(int32 *params) {
// init top menu from master list
// all icons are highlighted / full colour
for (j = 0; j < 15; j++) {
if (j < IN_SUBJECT) {
debug(5, " ICON res %d for %d", _subjectList[j].res, j);
icon = _vm->_resman->openResource(_subjectList[j].res) + sizeof(_standardHeader) + RDMENU_ICONWIDE * RDMENU_ICONDEEP;
_vm->_graphics->setMenuIcon(RDMENU_BOTTOM, (uint8) j, icon);
_vm->_resman->closeResource(_subjectList[j].res);
for (i = 0; i < 15; i++) {
if (i < IN_SUBJECT) {
debug(5, " ICON res %d for %d", _subjectList[i].res, i);
icon = _vm->_resman->openResource(_subjectList[i].res) + sizeof(_standardHeader) + RDMENU_ICONWIDE * RDMENU_ICONDEEP;
_vm->_graphics->setMenuIcon(RDMENU_BOTTOM, (uint8) i, icon);
_vm->_resman->closeResource(_subjectList[i].res);
} else {
//no icon here
debug(5, " NULL for %d", j);
_vm->_graphics->setMenuIcon(RDMENU_BOTTOM, (uint8) j, NULL);
// no icon here
debug(5, " NULL for %d", i);
_vm->_graphics->setMenuIcon(RDMENU_BOTTOM, (uint8) i, NULL);
}
}
@ -179,68 +176,63 @@ int32 Logic::fnChoose(int32 *params) {
// again next cycle
return IR_REPEAT;
} else {
// menu is there - we're just waiting for a click
debug(5, "choosing");
}
me = _vm->_input->mouseEvent();
// menu is there - we're just waiting for a click
debug(5, "choosing");
// we only care about left clicks
// we ignore mouse releases
me = _vm->_input->mouseEvent();
if (me && (me->buttons & RD_LEFTBUTTONDOWN)) {
// check for click on a menu
// if so then end the choose, highlight only the
// chosen, blank the mouse and return the ref code * 8
if (_vm->_input->_mouseY > 399 && _vm->_input->_mouseX >= 24 && _vm->_input->_mouseX < 640 - 24) {
//which are we over?
hit = (_vm->_input->_mouseX - 24) / 40;
//clicked on something - what button?
if (hit < IN_SUBJECT) {
debug(5, "Icons available:");
// change icons
for (j = 0; j < IN_SUBJECT; j++) {
debug(5, "%s", _vm->fetchObjectName(_subjectList[j].res));
// change all others to grey
if (j != hit) {
icon = _vm->_resman->openResource( _subjectList[j].res ) + sizeof(_standardHeader);
_vm->_graphics->setMenuIcon(RDMENU_BOTTOM, (uint8) j, icon);
_vm->_resman->closeResource(_subjectList[j].res);
}
}
debug(5, "Selected: %s", _vm->fetchObjectName(_subjectList[hit].res));
// this is our looping flag
_choosing = false;
IN_SUBJECT = 0;
// blank mouse again
_vm->setMouse(0);
debug(5, "hit %d - ref %d ref*8 %d", hit, _subjectList[hit].ref, _subjectList[hit].ref * 8);
// for non-speech scripts that manually
// call the chooser
RESULT = _subjectList[hit].res;
// return special subject chosen code
return IR_CONT + (_subjectList[hit].ref << 3);
}
}
}
// we only care about left clicks
// we ignore mouse releases
if (!me || !(me->buttons & RD_LEFTBUTTONDOWN) || _vm->_input->_mouseY < 400) {
debug(5, "end choose");
// again next cycle
return IR_REPEAT;
}
// Check for click on a menu. If so then end the choose, highlight only
// the chosen, blank the mouse and return the ref code * 8
hit = _vm->menuClick(IN_SUBJECT);
if (hit < 0) {
debug(5, "end choose");
return IR_REPEAT;
}
debug(5, "Icons available:");
// change icons
for (i = 0; i < IN_SUBJECT; i++) {
debug(5, "%s", _vm->fetchObjectName(_subjectList[i].res));
// change all others to grey
if (i != (uint32) hit) {
icon = _vm->_resman->openResource(_subjectList[i].res) + sizeof(_standardHeader);
_vm->_graphics->setMenuIcon(RDMENU_BOTTOM, (uint8) i, icon);
_vm->_resman->closeResource(_subjectList[i].res);
}
}
debug(2, "Selected: %s", _vm->fetchObjectName(_subjectList[hit].res));
// this is our looping flag
_choosing = false;
IN_SUBJECT = 0;
// blank mouse again
_vm->setMouse(0);
debug(5, "hit %d - ref %d ref*8 %d", hit, _subjectList[hit].ref, _subjectList[hit].ref * 8);
// for non-speech scripts that manually
// call the chooser
RESULT = _subjectList[hit].res;
// return special subject chosen code
return IR_CONT + (_subjectList[hit].ref << 3);
}
int32 Logic::fnStartConversation(int32 *params) {
@ -380,7 +372,7 @@ int32 Logic::fnTheyDoWeWait(int32 *params) {
if (!INS_COMMAND && RESULT == 1 && ob_logic->looping == 0) {
// first time so set up targets command if target is waiting
debug(5, "FNtdww sending command to %d", target);
debug(5, "fnTheyDoWeWait sending command to %d", target);
SPEECH_ID = params[1];
INS_COMMAND = params[2];
@ -413,7 +405,7 @@ int32 Logic::fnTheyDoWeWait(int32 *params) {
if (RESULT == 1) {
// its waiting now so we can be finished with all this
debug(5, "FNtdww finished");
debug(5, "fnTheyDoWeWait finished");
// not looping anymore
ob_logic->looping = 0;
@ -424,7 +416,7 @@ int32 Logic::fnTheyDoWeWait(int32 *params) {
return IR_CONT;
}
debug(5, "FNtdww just waiting");
debug(5, "fnTheyDoWeWait just waiting");
// debug flag to indicate who we're waiting for - see debug.cpp
_speechScriptWaiting = target;
@ -572,7 +564,7 @@ int32 Logic::fnSpeechProcess(int32 *params) {
debug(5, " SP");
while(1) {
while (1) {
//we are currently running a command
switch (ob_speech->command) {
case 0:

View File

@ -114,8 +114,6 @@ private:
void startNewPalette(void);
void processLayer(uint32 layer_number);
int menuClick(int menu_items);
void getPlayerStructures(void);
void putPlayerStructures(void);
@ -205,6 +203,8 @@ public:
menu_object _masterMenuList[TOTAL_engine_pockets];
uint32 _totalMasters;
int menuClick(int menu_items);
void buildMenu(void);
void buildSystemMenu(void);