2009-02-17 15:09:09 +00:00
|
|
|
/* 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$
|
|
|
|
*
|
|
|
|
*/
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
|
2009-02-27 02:23:40 +00:00
|
|
|
#include "sci/engine/state.h"
|
2009-02-27 02:23:00 +00:00
|
|
|
#include "sci/scicore/resource.h"
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 10:23:36 +00:00
|
|
|
namespace Sci {
|
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
// Default kernel name table
|
2009-02-15 06:10:59 +00:00
|
|
|
#define SCI0_KNAMES_WELL_DEFINED 0x6e
|
|
|
|
#define SCI0_KNAMES_DEFAULT_ENTRIES_NR 0x72
|
2009-03-01 01:52:50 +00:00
|
|
|
#define SCI1_KNAMES_DEFAULT_ENTRIES_NR 0x7E
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
const char *sci0_default_knames[SCI0_KNAMES_DEFAULT_ENTRIES_NR] = {
|
|
|
|
/*0x00*/ "Load",
|
|
|
|
/*0x01*/ "UnLoad",
|
|
|
|
/*0x02*/ "ScriptID",
|
|
|
|
/*0x03*/ "DisposeScript",
|
|
|
|
/*0x04*/ "Clone",
|
|
|
|
/*0x05*/ "DisposeClone",
|
|
|
|
/*0x06*/ "IsObject",
|
|
|
|
/*0x07*/ "RespondsTo",
|
|
|
|
/*0x08*/ "DrawPic",
|
|
|
|
/*0x09*/ "Show",
|
|
|
|
/*0x0a*/ "PicNotValid",
|
|
|
|
/*0x0b*/ "Animate",
|
|
|
|
/*0x0c*/ "SetNowSeen",
|
|
|
|
/*0x0d*/ "NumLoops",
|
|
|
|
/*0x0e*/ "NumCels",
|
|
|
|
/*0x0f*/ "CelWide",
|
|
|
|
/*0x10*/ "CelHigh",
|
|
|
|
/*0x11*/ "DrawCel",
|
|
|
|
/*0x12*/ "AddToPic",
|
|
|
|
/*0x13*/ "NewWindow",
|
|
|
|
/*0x14*/ "GetPort",
|
|
|
|
/*0x15*/ "SetPort",
|
|
|
|
/*0x16*/ "DisposeWindow",
|
|
|
|
/*0x17*/ "DrawControl",
|
|
|
|
/*0x18*/ "HiliteControl",
|
|
|
|
/*0x19*/ "EditControl",
|
|
|
|
/*0x1a*/ "TextSize",
|
|
|
|
/*0x1b*/ "Display",
|
|
|
|
/*0x1c*/ "GetEvent",
|
|
|
|
/*0x1d*/ "GlobalToLocal",
|
|
|
|
/*0x1e*/ "LocalToGlobal",
|
|
|
|
/*0x1f*/ "MapKeyToDir",
|
|
|
|
/*0x20*/ "DrawMenuBar",
|
|
|
|
/*0x21*/ "MenuSelect",
|
|
|
|
/*0x22*/ "AddMenu",
|
|
|
|
/*0x23*/ "DrawStatus",
|
|
|
|
/*0x24*/ "Parse",
|
|
|
|
/*0x25*/ "Said",
|
|
|
|
/*0x26*/ "SetSynonyms",
|
|
|
|
/*0x27*/ "HaveMouse",
|
|
|
|
/*0x28*/ "SetCursor",
|
|
|
|
/*0x29*/ "FOpen",
|
|
|
|
/*0x2a*/ "FPuts",
|
|
|
|
/*0x2b*/ "FGets",
|
|
|
|
/*0x2c*/ "FClose",
|
|
|
|
/*0x2d*/ "SaveGame",
|
|
|
|
/*0x2e*/ "RestoreGame",
|
|
|
|
/*0x2f*/ "RestartGame",
|
|
|
|
/*0x30*/ "GameIsRestarting",
|
|
|
|
/*0x31*/ "DoSound",
|
|
|
|
/*0x32*/ "NewList",
|
|
|
|
/*0x33*/ "DisposeList",
|
|
|
|
/*0x34*/ "NewNode",
|
|
|
|
/*0x35*/ "FirstNode",
|
|
|
|
/*0x36*/ "LastNode",
|
|
|
|
/*0x37*/ "EmptyList",
|
|
|
|
/*0x38*/ "NextNode",
|
|
|
|
/*0x39*/ "PrevNode",
|
|
|
|
/*0x3a*/ "NodeValue",
|
|
|
|
/*0x3b*/ "AddAfter",
|
|
|
|
/*0x3c*/ "AddToFront",
|
|
|
|
/*0x3d*/ "AddToEnd",
|
|
|
|
/*0x3e*/ "FindKey",
|
|
|
|
/*0x3f*/ "DeleteKey",
|
|
|
|
/*0x40*/ "Random",
|
|
|
|
/*0x41*/ "Abs",
|
|
|
|
/*0x42*/ "Sqrt",
|
|
|
|
/*0x43*/ "GetAngle",
|
|
|
|
/*0x44*/ "GetDistance",
|
|
|
|
/*0x45*/ "Wait",
|
|
|
|
/*0x46*/ "GetTime",
|
|
|
|
/*0x47*/ "StrEnd",
|
|
|
|
/*0x48*/ "StrCat",
|
|
|
|
/*0x49*/ "StrCmp",
|
|
|
|
/*0x4a*/ "StrLen",
|
|
|
|
/*0x4b*/ "StrCpy",
|
|
|
|
/*0x4c*/ "Format",
|
|
|
|
/*0x4d*/ "GetFarText",
|
|
|
|
/*0x4e*/ "ReadNumber",
|
|
|
|
/*0x4f*/ "BaseSetter",
|
|
|
|
/*0x50*/ "DirLoop",
|
|
|
|
/*0x51*/ "CanBeHere",
|
|
|
|
/*0x52*/ "OnControl",
|
|
|
|
/*0x53*/ "InitBresen",
|
|
|
|
/*0x54*/ "DoBresen",
|
|
|
|
/*0x55*/ "DoAvoider",
|
|
|
|
/*0x56*/ "SetJump",
|
|
|
|
/*0x57*/ "SetDebug",
|
|
|
|
/*0x58*/ "InspectObj",
|
|
|
|
/*0x59*/ "ShowSends",
|
|
|
|
/*0x5a*/ "ShowObjs",
|
|
|
|
/*0x5b*/ "ShowFree",
|
|
|
|
/*0x5c*/ "MemoryInfo",
|
|
|
|
/*0x5d*/ "StackUsage",
|
|
|
|
/*0x5e*/ "Profiler",
|
|
|
|
/*0x5f*/ "GetMenu",
|
|
|
|
/*0x60*/ "SetMenu",
|
|
|
|
/*0x61*/ "GetSaveFiles",
|
|
|
|
/*0x62*/ "GetCWD",
|
|
|
|
/*0x63*/ "CheckFreeSpace",
|
|
|
|
/*0x64*/ "ValidPath",
|
|
|
|
/*0x65*/ "CoordPri",
|
|
|
|
/*0x66*/ "StrAt",
|
|
|
|
/*0x67*/ "DeviceInfo",
|
|
|
|
/*0x68*/ "GetSaveDir",
|
|
|
|
/*0x69*/ "CheckSaveGame",
|
|
|
|
/*0x6a*/ "ShakeScreen",
|
|
|
|
/*0x6b*/ "FlushResources",
|
|
|
|
/*0x6c*/ "SinMult",
|
|
|
|
/*0x6d*/ "CosMult",
|
|
|
|
/*0x6e*/ "SinDiv",
|
|
|
|
/*0x6f*/ "CosDiv",
|
|
|
|
/*0x70*/ "Graph",
|
|
|
|
/*0x71*/ SCRIPT_UNKNOWN_FUNCTION_STRING
|
2009-02-15 06:10:59 +00:00
|
|
|
};
|
|
|
|
|
2009-03-01 01:52:50 +00:00
|
|
|
const char *sci1_default_knames[SCI1_KNAMES_DEFAULT_ENTRIES_NR] = {
|
|
|
|
"Load",
|
|
|
|
"UnLoad",
|
|
|
|
"ScriptID",
|
|
|
|
"DisposeScript",
|
|
|
|
"Clone",
|
|
|
|
"DisposeClone",
|
|
|
|
"IsObject",
|
|
|
|
"RespondsTo",
|
|
|
|
"DrawPic",
|
|
|
|
"Show",
|
|
|
|
"PicNotValid",
|
|
|
|
"Animate",
|
|
|
|
"SetNowSeen",
|
|
|
|
"NumLoops",
|
|
|
|
"NumCels",
|
|
|
|
"CelWide",
|
|
|
|
"CelHigh",
|
|
|
|
"DrawCel",
|
|
|
|
"AddToPic",
|
|
|
|
"NewWindow",
|
|
|
|
"GetPort",
|
|
|
|
"SetPort",
|
|
|
|
"DisposeWindow",
|
|
|
|
"DrawControl",
|
|
|
|
"HiliteControl",
|
|
|
|
"EditControl",
|
|
|
|
"TextSize",
|
|
|
|
"Display",
|
|
|
|
"GetEvent",
|
|
|
|
"GlobalToLocal",
|
|
|
|
"LocalToGlobal",
|
|
|
|
"MapKeyToDir",
|
|
|
|
"DrawMenuBar",
|
|
|
|
"MenuSelect",
|
|
|
|
"AddMenu",
|
|
|
|
"DrawStatus",
|
|
|
|
"Parse",
|
|
|
|
"Said",
|
|
|
|
"SetSynonyms",
|
|
|
|
"HaveMouse",
|
|
|
|
"SetCursor",
|
|
|
|
"SaveGame",
|
|
|
|
"RestoreGame",
|
|
|
|
"RestartGame",
|
|
|
|
"GameIsRestarting",
|
|
|
|
"DoSound",
|
|
|
|
"NewList",
|
|
|
|
"DisposeList",
|
|
|
|
"NewNode",
|
|
|
|
"FirstNode",
|
|
|
|
"LastNode",
|
|
|
|
"EmptyList",
|
|
|
|
"NextNode",
|
|
|
|
"PrevNode",
|
|
|
|
"NodeValue",
|
|
|
|
"AddAfter",
|
|
|
|
"AddToFront",
|
|
|
|
"AddToEnd",
|
|
|
|
"FindKey",
|
|
|
|
"DeleteKey",
|
|
|
|
"Random",
|
|
|
|
"Abs",
|
|
|
|
"Sqrt",
|
|
|
|
"GetAngle",
|
|
|
|
"GetDistance",
|
|
|
|
"Wait",
|
|
|
|
"GetTime",
|
|
|
|
"StrEnd",
|
|
|
|
"StrCat",
|
|
|
|
"StrCmp",
|
|
|
|
"StrLen",
|
|
|
|
"StrCpy",
|
|
|
|
"Format",
|
|
|
|
"GetFarText",
|
|
|
|
"ReadNumber",
|
|
|
|
"BaseSetter",
|
|
|
|
"DirLoop",
|
|
|
|
"CanBeHere",
|
|
|
|
"OnControl",
|
|
|
|
"InitBresen",
|
|
|
|
"DoBresen",
|
|
|
|
"DoAvoider",
|
|
|
|
"SetJump",
|
|
|
|
"SetDebug",
|
|
|
|
"InspectObj",
|
|
|
|
"ShowSends",
|
|
|
|
"ShowObjs",
|
|
|
|
"ShowFree",
|
|
|
|
"MemoryInfo",
|
|
|
|
"StackUsage",
|
|
|
|
"Profiler",
|
|
|
|
"GetMenu",
|
|
|
|
"SetMenu",
|
|
|
|
"GetSaveFiles",
|
|
|
|
"GetCWD",
|
|
|
|
"CheckFreeSpace",
|
|
|
|
"ValidPath",
|
|
|
|
"CoordPri",
|
|
|
|
"StrAt",
|
|
|
|
"DeviceInfo",
|
|
|
|
"GetSaveDir",
|
|
|
|
"CheckSaveGame",
|
|
|
|
"ShakeScreen",
|
|
|
|
"FlushResources",
|
|
|
|
"SinMult",
|
|
|
|
"CosMult",
|
|
|
|
"SinDiv",
|
|
|
|
"CosDiv",
|
|
|
|
"Graph",
|
|
|
|
"Joystick",
|
|
|
|
"ShiftScreen",
|
|
|
|
"Palette",
|
|
|
|
"MemorySegment",
|
|
|
|
"Intersections",
|
|
|
|
"Memory",
|
|
|
|
"ListOps",
|
|
|
|
"FileIO",
|
|
|
|
"DoAudio",
|
|
|
|
"DoSync",
|
|
|
|
"AvoidPath",
|
|
|
|
"Sort",
|
|
|
|
"ATan",
|
|
|
|
"Lock",
|
|
|
|
"StrSplit",
|
|
|
|
"GetMessage",
|
|
|
|
SCRIPT_UNKNOWN_FUNCTION_STRING
|
|
|
|
};
|
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
int getInt(unsigned char* d) {
|
|
|
|
return d[0] | (d[1] << 8);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
int *vocabulary_get_classes(ResourceManager *resmgr, int* count) {
|
2009-02-28 21:59:49 +00:00
|
|
|
Resource* r;
|
2009-02-15 22:28:50 +00:00
|
|
|
int *c;
|
|
|
|
unsigned int i;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-28 23:46:50 +00:00
|
|
|
if ((r = resmgr->findResource(kResourceTypeVocab, 996, 0)) == NULL)
|
2009-02-21 15:25:37 +00:00
|
|
|
return 0;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
c = (int *)sci_malloc(sizeof(int) * r->size / 2);
|
2009-02-15 22:28:50 +00:00
|
|
|
for (i = 2; i < r->size; i += 4) {
|
|
|
|
c[i/4] = getInt(r->data + i);
|
|
|
|
}
|
|
|
|
*count = r->size / 4;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
return c;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-02-20 15:24:22 +00:00
|
|
|
int vocabulary_get_class_count(ResourceManager *resmgr) {
|
2009-02-28 21:59:49 +00:00
|
|
|
Resource* r;
|
2009-02-21 15:25:37 +00:00
|
|
|
|
2009-02-28 23:46:50 +00:00
|
|
|
if ((r = resmgr->findResource(kResourceTypeVocab, 996, 0)) == 0)
|
2009-02-21 15:25:37 +00:00
|
|
|
return 0;
|
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
return r->size / 4;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-02-23 03:04:52 +00:00
|
|
|
bool vocabulary_get_snames(ResourceManager *resmgr, sci_version_t version, Common::StringList &selectorNames) {
|
2009-02-15 22:28:50 +00:00
|
|
|
int count;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-28 23:46:50 +00:00
|
|
|
Resource *r = resmgr->findResource(kResourceTypeVocab, 997, 0);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
if (!r) // No such resource?
|
2009-02-23 03:04:52 +00:00
|
|
|
return false;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
count = getInt(r->data) + 1; // Counter is slightly off
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-23 03:04:52 +00:00
|
|
|
for (int i = 0; i < count; i++) {
|
2009-02-15 22:28:50 +00:00
|
|
|
int offset = getInt(r->data + 2 + i * 2);
|
|
|
|
int len = getInt(r->data + offset);
|
2009-02-23 03:04:52 +00:00
|
|
|
|
|
|
|
Common::String tmp((const char *)r->data + offset + 2, len);
|
|
|
|
selectorNames.push_back(tmp);
|
2009-02-15 22:28:50 +00:00
|
|
|
if ((version != 0) && (version < SCI_VERSION_FTU_NEW_SCRIPT_HEADER)) {
|
2009-02-23 03:04:52 +00:00
|
|
|
// Early SCI versions used the LSB in the selector ID as a read/write
|
|
|
|
// toggle. To compensate for that, we add every selector name twice.
|
|
|
|
selectorNames.push_back(tmp);
|
2009-02-15 22:28:50 +00:00
|
|
|
}
|
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-23 03:04:52 +00:00
|
|
|
return true;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-02-23 03:04:52 +00:00
|
|
|
int vocabulary_lookup_sname(const Common::StringList &selectorNames, const char *sname) {
|
|
|
|
for (uint pos = 0; pos < selectorNames.size(); ++pos) {
|
|
|
|
if (selectorNames[pos] == sname)
|
2009-02-21 15:25:37 +00:00
|
|
|
return pos;
|
2009-02-15 22:28:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-02-20 15:24:22 +00:00
|
|
|
opcode* vocabulary_get_opcodes(ResourceManager *resmgr) {
|
2009-02-15 06:10:59 +00:00
|
|
|
opcode* o;
|
2009-02-15 22:28:50 +00:00
|
|
|
int count, i = 0;
|
2009-02-28 23:46:50 +00:00
|
|
|
Resource* r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_OPCODES, 0);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
// if the resource couldn't be loaded, leave
|
2009-02-15 06:10:59 +00:00
|
|
|
if (r == NULL) {
|
2009-02-21 14:11:41 +00:00
|
|
|
fprintf(stderr, "unable to load vocab.%03d\n", VOCAB_RESOURCE_OPCODES);
|
2009-02-15 06:10:59 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
count = getInt(r->data);
|
|
|
|
|
|
|
|
o = (opcode*)sci_malloc(sizeof(opcode) * 256);
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
int offset = getInt(r->data + 2 + i * 2);
|
|
|
|
int len = getInt(r->data + offset) - 2;
|
|
|
|
o[i].type = getInt(r->data + offset + 2);
|
|
|
|
o[i].number = i;
|
2009-02-21 15:25:37 +00:00
|
|
|
o[i].name = (char *)sci_malloc(len + 1);
|
2009-02-15 22:28:50 +00:00
|
|
|
memcpy(o[i].name, r->data + offset + 4, len);
|
|
|
|
o[i].name[len] = '\0';
|
2009-02-15 06:10:59 +00:00
|
|
|
#ifdef VOCABULARY_DEBUG
|
2009-02-15 22:28:50 +00:00
|
|
|
printf("Opcode %02X: %s, %d\n", i, o[i].name, o[i].type);
|
2009-02-15 06:10:59 +00:00
|
|
|
#endif
|
2009-02-15 22:28:50 +00:00
|
|
|
}
|
|
|
|
for (i = count; i < 256; i++) {
|
|
|
|
o[i].type = 0;
|
|
|
|
o[i].number = i;
|
2009-02-21 15:25:37 +00:00
|
|
|
o[i].name = (char *)sci_malloc(strlen("undefined") + 1);
|
2009-02-15 22:28:50 +00:00
|
|
|
strcpy(o[i].name, "undefined");
|
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
return o;
|
|
|
|
}
|
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
void vocabulary_free_opcodes(opcode *opcodes) {
|
2009-02-15 06:10:59 +00:00
|
|
|
int i;
|
|
|
|
if (!opcodes)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < 256; i++) {
|
|
|
|
if (opcodes[i].name)
|
|
|
|
free(opcodes[i].name);
|
|
|
|
}
|
|
|
|
free(opcodes);
|
|
|
|
}
|
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
// Alternative kernel func names retriever. Required for KQ1/SCI (at least).
|
2009-02-28 21:59:49 +00:00
|
|
|
static char **_vocabulary_get_knames0alt(int *names, Resource *r) {
|
2009-02-15 22:28:50 +00:00
|
|
|
unsigned int mallocsize = 32;
|
2009-02-21 15:25:37 +00:00
|
|
|
char **retval = (char **)sci_malloc(sizeof(char *) * mallocsize);
|
2009-02-15 22:28:50 +00:00
|
|
|
unsigned int i = 0, index = 0;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
while (index < r->size) {
|
|
|
|
int slen = strlen((char *) r->data + index) + 1;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
retval[i] = (char *)sci_malloc(slen);
|
2009-02-15 22:28:50 +00:00
|
|
|
memcpy(retval[i++], r->data + index, slen);
|
2009-02-21 15:25:37 +00:00
|
|
|
// Wouldn't normally read this, but the cleanup code wants to free() this
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
index += slen;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
if (i == mallocsize)
|
2009-02-21 15:25:37 +00:00
|
|
|
retval = (char **)sci_realloc(retval, sizeof(char *) * (mallocsize <<= 1));
|
2009-02-15 22:28:50 +00:00
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
*names = i + 1;
|
2009-02-21 15:25:37 +00:00
|
|
|
retval = (char **)sci_realloc(retval, sizeof(char *) * (i + 2));
|
|
|
|
retval[i] = (char *)sci_malloc(strlen(SCRIPT_UNKNOWN_FUNCTION_STRING) + 1);
|
2009-02-15 22:28:50 +00:00
|
|
|
strcpy(retval[i], SCRIPT_UNKNOWN_FUNCTION_STRING);
|
2009-02-21 15:25:37 +00:00
|
|
|
// The mystery kernel function- one in each SCI0 package
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
retval[i + 1] = NULL; // Required for cleanup
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
return retval;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
static char **vocabulary_get_knames0(ResourceManager *resmgr, int* names) {
|
2009-02-15 06:10:59 +00:00
|
|
|
char** t;
|
2009-02-15 22:28:50 +00:00
|
|
|
int count, i, index = 2, empty_to_add = 1;
|
2009-02-28 23:46:50 +00:00
|
|
|
Resource *r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES, 0);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
if (!r) { // No kernel name table found? Fall back to default table
|
|
|
|
t = (char **)sci_malloc((SCI0_KNAMES_DEFAULT_ENTRIES_NR + 1) * sizeof(char*));
|
|
|
|
*names = SCI0_KNAMES_DEFAULT_ENTRIES_NR - 1; // index of last element
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
for (i = 0; i < SCI0_KNAMES_DEFAULT_ENTRIES_NR; i++)
|
|
|
|
t[i] = sci_strdup(sci0_default_knames[i]);
|
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
t[SCI0_KNAMES_DEFAULT_ENTRIES_NR] = NULL; // Terminate list
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
count = getInt(r->data);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (count > 1023)
|
|
|
|
return _vocabulary_get_knames0alt(names, r);
|
|
|
|
|
|
|
|
if (count < SCI0_KNAMES_WELL_DEFINED) {
|
|
|
|
empty_to_add = SCI0_KNAMES_WELL_DEFINED - count;
|
|
|
|
sciprintf("Less than %d kernel functions; adding %d\n", SCI0_KNAMES_WELL_DEFINED, empty_to_add);
|
|
|
|
}
|
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
t = (char **)sci_malloc(sizeof(char*) * (count + 1 + empty_to_add));
|
2009-02-15 22:28:50 +00:00
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
int offset = getInt(r->data + index);
|
|
|
|
int len = getInt(r->data + offset);
|
2009-02-21 15:25:37 +00:00
|
|
|
//fprintf(stderr,"Getting name %d of %d...\n", i, count);
|
2009-02-15 22:28:50 +00:00
|
|
|
index += 2;
|
2009-02-21 15:25:37 +00:00
|
|
|
t[i] = (char *)sci_malloc(len + 1);
|
2009-02-15 06:10:59 +00:00
|
|
|
memcpy(t[i], r->data + offset + 2, len);
|
2009-02-15 22:28:50 +00:00
|
|
|
t[i][len] = '\0';
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < empty_to_add; i++) {
|
2009-02-21 15:25:37 +00:00
|
|
|
t[count + i] = (char *)sci_malloc(strlen(SCRIPT_UNKNOWN_FUNCTION_STRING) + 1);
|
2009-02-15 06:10:59 +00:00
|
|
|
strcpy(t[count + i], SCRIPT_UNKNOWN_FUNCTION_STRING);
|
|
|
|
}
|
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
t[count+empty_to_add] = 0;
|
|
|
|
*names = count + empty_to_add;
|
2009-02-21 15:25:37 +00:00
|
|
|
|
2009-02-15 06:10:59 +00:00
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
static char **vocabulary_get_knames1(ResourceManager *resmgr, int *count) {
|
|
|
|
char **t = NULL;
|
2009-03-25 22:37:08 +00:00
|
|
|
// vocab.999/999.voc is notoriously unreliable in SCI1 games, and should not be used
|
|
|
|
// We hardcode the default SCI1 kernel names here (i.e. the ones inside the "special"
|
|
|
|
// 999.voc file from FreeSCI). All SCI1 games seem to be working with this change, but
|
|
|
|
// if any SCI1 game has different kernel vocabulary names, it might not work. It seems
|
|
|
|
// that all SCI1 games use the same kernel vocabulary names though, so this seems to be
|
|
|
|
// a safe change. If there's any SCI1 game with different kernel vocabulary names, we can
|
|
|
|
// add special flags to it to our detector
|
|
|
|
t = (char **)sci_malloc((SCI1_KNAMES_DEFAULT_ENTRIES_NR + 1) * sizeof(char*));
|
|
|
|
*count = SCI1_KNAMES_DEFAULT_ENTRIES_NR - 1; // index of last element
|
|
|
|
|
|
|
|
for (int i = 0; i < SCI1_KNAMES_DEFAULT_ENTRIES_NR; i++)
|
|
|
|
t[i] = sci_strdup(sci1_default_knames[i]);
|
|
|
|
|
|
|
|
t[SCI1_KNAMES_DEFAULT_ENTRIES_NR] = NULL; // Terminate list
|
|
|
|
|
|
|
|
return t;
|
|
|
|
|
|
|
|
// Previous code, which used the unreliable 999.voc resource
|
|
|
|
#if 0
|
2009-02-15 22:28:50 +00:00
|
|
|
unsigned int size = 64, used = 0, pos = 0;
|
2009-02-28 23:46:50 +00:00
|
|
|
Resource *r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES, 0);
|
2009-03-25 22:37:08 +00:00
|
|
|
|
|
|
|
if (r == NULL) {// failed to open vocab.999 (happens with SCI1 demos)
|
2009-03-01 01:52:50 +00:00
|
|
|
t = (char **)sci_malloc((SCI1_KNAMES_DEFAULT_ENTRIES_NR + 1) * sizeof(char*));
|
|
|
|
*count = SCI1_KNAMES_DEFAULT_ENTRIES_NR - 1; // index of last element
|
|
|
|
|
|
|
|
for (int i = 0; i < SCI1_KNAMES_DEFAULT_ENTRIES_NR; i++)
|
|
|
|
t[i] = sci_strdup(sci1_default_knames[i]);
|
|
|
|
|
|
|
|
t[SCI1_KNAMES_DEFAULT_ENTRIES_NR] = NULL; // Terminate list
|
2009-02-15 22:28:50 +00:00
|
|
|
|
2009-03-01 01:52:50 +00:00
|
|
|
return t;
|
|
|
|
}
|
2009-02-15 22:28:50 +00:00
|
|
|
while (pos < r->size) {
|
|
|
|
int len;
|
|
|
|
if ((used == size - 1) || (!t)) {
|
|
|
|
size *= 2;
|
2009-02-21 15:25:37 +00:00
|
|
|
t = (char **)sci_realloc(t, size * sizeof(char*));
|
2009-02-15 22:28:50 +00:00
|
|
|
}
|
2009-02-21 15:25:37 +00:00
|
|
|
len = strlen((char *)r->data + pos);
|
|
|
|
t[used] = (char *)sci_malloc(len + 1);
|
|
|
|
strcpy(t[used], (char *)r->data + pos);
|
2009-02-15 22:28:50 +00:00
|
|
|
used++;
|
|
|
|
pos += len + 1;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-02-15 22:28:50 +00:00
|
|
|
*count = used;
|
2009-02-21 15:25:37 +00:00
|
|
|
t = (char **)sci_realloc(t, (used + 1) * sizeof(char*));
|
2009-02-15 22:28:50 +00:00
|
|
|
t[used] = NULL;
|
2009-02-21 15:25:37 +00:00
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
return t;
|
2009-03-25 22:37:08 +00:00
|
|
|
#endif
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-03-01 01:52:50 +00:00
|
|
|
//
|
|
|
|
static char **vocabulary_get_knames11(ResourceManager *resmgr, int *count) {
|
|
|
|
/*
|
|
|
|
999.voc format for SCI1.1 games:
|
|
|
|
[b] # of kernel functions
|
|
|
|
[w] unknown
|
|
|
|
[offset to function name info]
|
|
|
|
...
|
|
|
|
{[w name-len][function name]}
|
|
|
|
...
|
|
|
|
*/
|
|
|
|
char **t = NULL;
|
2009-03-01 03:31:52 +00:00
|
|
|
//unsigned int size = 64, pos = 3;
|
2009-03-01 01:52:50 +00:00
|
|
|
int len;
|
|
|
|
Resource *r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES, 0);
|
|
|
|
if(r == NULL) // failed to open vocab.999 (happens with SCI1 demos)
|
|
|
|
return 0; // FIXME: should return a default table for this engine
|
|
|
|
byte nCnt = *r->data, i;
|
|
|
|
t = (char **)sci_malloc(nCnt * sizeof(char*) + 1);
|
|
|
|
|
|
|
|
for (i = 0; i < nCnt; i++) {
|
|
|
|
int off = READ_LE_UINT16(r->data + 2 * i + 2);
|
|
|
|
len = READ_LE_UINT16(r->data + off);
|
|
|
|
t[i] = (char *)sci_malloc(len + 1);
|
|
|
|
memcpy(t[i], (char *)r->data + off + 2, len);
|
|
|
|
t[i][len] = 0;
|
|
|
|
}
|
|
|
|
*count = nCnt;
|
|
|
|
t[nCnt] = NULL;
|
|
|
|
|
|
|
|
return t;
|
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
char **vocabulary_get_knames(ResourceManager *resmgr, int *count) {
|
2009-02-28 22:19:22 +00:00
|
|
|
switch (resmgr->_sciVersion) {
|
2009-02-15 22:28:50 +00:00
|
|
|
case SCI_VERSION_0:
|
|
|
|
case SCI_VERSION_01:
|
2009-03-30 21:41:29 +00:00
|
|
|
return vocabulary_get_knames0(resmgr, count);
|
2009-02-15 22:28:50 +00:00
|
|
|
case SCI_VERSION_01_VGA:
|
|
|
|
case SCI_VERSION_01_VGA_ODD:
|
2009-03-30 21:41:29 +00:00
|
|
|
// HACK: KQ5 needs the SCI1 default vocabulary names to work correctly.
|
|
|
|
// Having more vocabulary names (like in SCI1) doesn't seem to have any
|
|
|
|
// ill effects, other than resulting in unmapped functions towards the
|
|
|
|
// end, which are never used by the game interpteter anyway
|
|
|
|
// return vocabulary_get_knames0(resmgr, count);
|
2009-02-15 22:28:50 +00:00
|
|
|
case SCI_VERSION_1_EARLY:
|
|
|
|
case SCI_VERSION_1_LATE:
|
2009-03-01 01:52:50 +00:00
|
|
|
return vocabulary_get_knames1(resmgr, count);
|
2009-02-15 22:28:50 +00:00
|
|
|
case SCI_VERSION_1_1:
|
2009-03-30 07:53:32 +00:00
|
|
|
return vocabulary_get_knames11(resmgr, count);
|
|
|
|
#ifdef ENABLE_SCI32
|
2009-02-15 22:28:50 +00:00
|
|
|
case SCI_VERSION_32:
|
2009-03-01 01:52:50 +00:00
|
|
|
return vocabulary_get_knames11(resmgr, count);
|
2009-03-30 07:53:32 +00:00
|
|
|
#endif
|
2009-02-15 22:28:50 +00:00
|
|
|
default:
|
|
|
|
return 0;
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-21 15:25:37 +00:00
|
|
|
void vocabulary_free_knames(char **names) {
|
|
|
|
int i = 0;
|
|
|
|
|
2009-02-15 22:28:50 +00:00
|
|
|
while (names[i]) {
|
2009-02-15 06:10:59 +00:00
|
|
|
free(names[i]);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(names);
|
|
|
|
}
|
2009-02-21 10:23:36 +00:00
|
|
|
|
|
|
|
} // End of namespace Sci
|