SCI32:
- Set signature for Array/String - Add the kernel table differences for the GK2 demo - Implement kMessage changes in SCI32 - Use an empty string as the default path for all games now (and modify kValidPath to accept that only as valid) - Add dereferencing for Arrays svn-id: r46756
This commit is contained in:
parent
fd2d0fc718
commit
5382aa1ab0
11 changed files with 125 additions and 41 deletions
|
@ -657,6 +657,10 @@ int determine_reg_type(SegManager *segMan, reg_t reg) {
|
|||
case SEG_TYPE_STACK:
|
||||
case SEG_TYPE_SYS_STRINGS:
|
||||
case SEG_TYPE_DYNMEM:
|
||||
#ifdef ENABLE_SCI32
|
||||
case SEG_TYPE_ARRAY:
|
||||
case SEG_TYPE_STRING:
|
||||
#endif
|
||||
return KSIG_REF;
|
||||
case SEG_TYPE_LISTS:
|
||||
return KSIG_LIST;
|
||||
|
@ -771,7 +775,7 @@ bool Kernel::loadKernelNames(Common::String gameId) {
|
|||
|
||||
#ifdef ENABLE_SCI32
|
||||
if (getSciVersion() >= SCI_VERSION_2_1)
|
||||
setKernelNamesSci21();
|
||||
setKernelNamesSci21(gameId);
|
||||
else if (getSciVersion() == SCI_VERSION_2)
|
||||
setKernelNamesSci2();
|
||||
else
|
||||
|
|
|
@ -111,7 +111,7 @@ private:
|
|||
/**
|
||||
* Sets the default kernel function names to the SCI2.1 kernel functions
|
||||
*/
|
||||
void setKernelNamesSci21();
|
||||
void setKernelNamesSci21(Common::String gameId);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
namespace Sci {
|
||||
|
||||
// NOTE: 0x72-0x79, 0x85-0x86, 0x88 are from the GK2 demo (which has debug support) and are
|
||||
// just Dummy in other SCI2 games.
|
||||
static const char *sci2_default_knames[] = {
|
||||
/*0x00*/ "Load",
|
||||
/*0x01*/ "UnLoad",
|
||||
|
@ -147,14 +149,14 @@ static const char *sci2_default_knames[] = {
|
|||
/*0x6f*/ "AvoidPath",
|
||||
/*0x70*/ "InPolygon",
|
||||
/*0x71*/ "MergePoly",
|
||||
/*0x72*/ "Dummy",
|
||||
/*0x73*/ "Dummy",
|
||||
/*0x74*/ "Dummy",
|
||||
/*0x75*/ "Dummy",
|
||||
/*0x76*/ "Dummy",
|
||||
/*0x77*/ "Dummy",
|
||||
/*0x78*/ "Dummy",
|
||||
/*0x79*/ "Dummy",
|
||||
/*0x72*/ "SetDebug",
|
||||
/*0x73*/ "InspectObject",
|
||||
/*0x74*/ "MemoryInfo",
|
||||
/*0x75*/ "Profiler",
|
||||
/*0x76*/ "Record",
|
||||
/*0x77*/ "PlayBack",
|
||||
/*0x78*/ "MonoOut",
|
||||
/*0x79*/ "SetFatalStr",
|
||||
/*0x7a*/ "GetCWD",
|
||||
/*0x7b*/ "ValidPath",
|
||||
/*0x7c*/ "FileIO",
|
||||
|
@ -166,12 +168,35 @@ static const char *sci2_default_knames[] = {
|
|||
/*0x82*/ "Array",
|
||||
/*0x83*/ "String",
|
||||
/*0x84*/ "RemapColors",
|
||||
/*0x85*/ "Dummy",
|
||||
/*0x86*/ "Dummy",
|
||||
/*0x85*/ "IntegrityChecking",
|
||||
/*0x86*/ "CheckIntegrity",
|
||||
/*0x87*/ "ObjectIntersect",
|
||||
/*0x88*/ "Dummy",
|
||||
/*0x88*/ "MarkMemory",
|
||||
/*0x89*/ "TextWidth",
|
||||
/*0x8a*/ "PointSize"
|
||||
/*0x8a*/ "PointSize",
|
||||
|
||||
// GK2 Demo only kernel functions
|
||||
/*0x8b*/ "AddLine",
|
||||
/*0x8c*/ "DeleteLine",
|
||||
/*0x8d*/ "UpdateLine",
|
||||
/*0x8e*/ "AddPolygon",
|
||||
/*0x8f*/ "DeletePolygon",
|
||||
/*0x90*/ "UpdatePolygon",
|
||||
/*0x91*/ "Bitmap",
|
||||
/*0x92*/ "ScrollWindow",
|
||||
/*0x93*/ "SetFontRes",
|
||||
/*0x94*/ "MovePlaneItems",
|
||||
/*0x95*/ "PreloadResource",
|
||||
/*0x96*/ "Dummy",
|
||||
/*0x97*/ "ResourceTrack",
|
||||
/*0x98*/ "CheckCDisc",
|
||||
/*0x99*/ "GetSaveCDisc",
|
||||
/*0x9a*/ "TestPoly",
|
||||
/*0x9b*/ "WinHelp",
|
||||
/*0x9c*/ "LoadChunk",
|
||||
/*0x9d*/ "SetPalStyleRange",
|
||||
/*0x9e*/ "AddPicAt",
|
||||
/*0x9f*/ "MessageBox"
|
||||
};
|
||||
|
||||
static const char *sci21_default_knames[] = {
|
||||
|
@ -302,7 +327,7 @@ static const char *sci21_default_knames[] = {
|
|||
/*0x7c*/ "SetQuitStr",
|
||||
/*0x7d*/ "GetConfig",
|
||||
/*0x7e*/ "Table",
|
||||
/*0x7f*/ "Dummy",
|
||||
/*0x7f*/ "WinHelp", // Windows only
|
||||
/*0x80*/ "Dummy",
|
||||
/*0x81*/ "Dummy",
|
||||
/*0x82*/ "Dummy",
|
||||
|
@ -314,7 +339,7 @@ static const char *sci21_default_knames[] = {
|
|||
/*0x88*/ "Dummy",
|
||||
/*0x89*/ "Dummy",
|
||||
/*0x8a*/ "LoadChunk",
|
||||
/*0x8b*/ "SetPalStyleRange"
|
||||
/*0x8b*/ "SetPalStyleRange",
|
||||
/*0x8c*/ "AddPicAt",
|
||||
/*0x8d*/ "Dummy",
|
||||
/*0x8e*/ "NewRoom",
|
||||
|
@ -324,11 +349,11 @@ static const char *sci21_default_knames[] = {
|
|||
/*0x92*/ "PlayVMD",
|
||||
/*0x93*/ "SetHotRectangles",
|
||||
/*0x94*/ "MulDiv",
|
||||
/*0x95*/ "Dummy",
|
||||
/*0x96*/ "Dummy",
|
||||
/*0x97*/ "Dummy",
|
||||
/*0x98*/ "Dummy",
|
||||
/*0x99*/ "Dummy",
|
||||
/*0x95*/ "GetSierraProfileInt", // Windows only
|
||||
/*0x96*/ "GetSierraProfileString", // Windows only
|
||||
/*0x97*/ "SetWindowsOption", // Windows only
|
||||
/*0x98*/ "GetWindowsOption", // Windows only
|
||||
/*0x99*/ "WinDLL", // Windows only
|
||||
|
||||
// SCI3
|
||||
/*0x9a*/ "Dummy",
|
||||
|
@ -336,12 +361,30 @@ static const char *sci21_default_knames[] = {
|
|||
/*0x9c*/ "DeletePic"
|
||||
};
|
||||
|
||||
enum {
|
||||
kKernelEntriesSci2 = 0x8b,
|
||||
kKernelEntriesGk2Demo = 0xa0,
|
||||
kKernelEntriesSci21 = 0x9a,
|
||||
kKernelEntriesSci3 = 0x9d
|
||||
};
|
||||
|
||||
void Kernel::setKernelNamesSci2() {
|
||||
_kernelNames = Common::StringList(sci2_default_knames, ARRAYSIZE(sci2_default_knames));
|
||||
_kernelNames = Common::StringList(sci2_default_knames, kKernelEntriesSci2);
|
||||
}
|
||||
|
||||
void Kernel::setKernelNamesSci21() {
|
||||
_kernelNames = Common::StringList(sci21_default_knames, ARRAYSIZE(sci21_default_knames));
|
||||
void Kernel::setKernelNamesSci21(Common::String gameId) {
|
||||
// The Gabriel Knight 2 demo uses a different kernel function set. It's pretty much a cross between
|
||||
// the SCI2 and SCI2.1 set. Strangely, the GK2 executable still has the 2.100.002 version string,
|
||||
// even though it wouldn't be compatible with the other 2.100.002 games...
|
||||
if (gameId == "gk2" && ((SciEngine *)g_engine)->isDemo()) {
|
||||
_kernelNames = Common::StringList(sci2_default_knames, kKernelEntriesGk2Demo);
|
||||
// OnMe is IsOnMe here, but they should be compatible
|
||||
_kernelNames[0x23] = "Robot"; // Graph in SCI2
|
||||
_kernelNames[0x2e] = "Priority"; // DisposeTextBitmap in SCI2
|
||||
} else {
|
||||
// TODO: Differentiate between SCI2.1/3
|
||||
_kernelNames = Common::StringList(sci21_default_knames, kKernelEntriesSci3);
|
||||
}
|
||||
}
|
||||
|
||||
// SCI2 Kernel Functions
|
||||
|
|
|
@ -592,8 +592,8 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) {
|
|||
reg_t kValidPath(EngineState *s, int argc, reg_t *argv) {
|
||||
Common::String path = s->_segMan->getString(argv[0]);
|
||||
|
||||
// FIXME: For now, we only accept the (fake) root dir "/" as a valid path.
|
||||
s->r_acc = make_reg(0, path == "/");
|
||||
// FIXME: For now, we only accept the (fake) dir "" as a valid path.
|
||||
s->r_acc = make_reg(0, path == "");
|
||||
|
||||
debug(3, "kValidPath(%s) -> %d", path.c_str(), s->r_acc.offset);
|
||||
|
||||
|
|
|
@ -640,6 +640,16 @@ reg_t kGetMessage(EngineState *s, int argc, reg_t *argv) {
|
|||
reg_t kMessage(EngineState *s, int argc, reg_t *argv) {
|
||||
uint func = argv[0].toUint16();
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
if (getSciVersion() >= SCI_VERSION_2) {
|
||||
// In complete weirdness, SCI32 bumps up subops 3-8 to 4-9 and stubs off subop 3.
|
||||
if (func == 3)
|
||||
warning("SCI32 kMessage(3)");
|
||||
else if (func > 3)
|
||||
func--;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((func != K_MESSAGE_NEXT) && (argc < 2)) {
|
||||
warning("Message: not enough arguments passed to subfunction %d", func);
|
||||
return NULL_REG;
|
||||
|
|
|
@ -363,6 +363,15 @@ Common::String MessageState::processString(const char *s) {
|
|||
}
|
||||
|
||||
void MessageState::outputString(reg_t buf, const Common::String &str) {
|
||||
#ifdef ENABLE_SCI32
|
||||
if (getSciVersion() >= SCI_VERSION_2) {
|
||||
SciString *sciString = _segMan->lookupString(buf);
|
||||
sciString->setSize(str.size() + 1);
|
||||
for (uint32 i = 0; i < str.size(); i++)
|
||||
sciString->setValue(i, str.c_str()[i]);
|
||||
sciString->setValue(str.size(), 0);
|
||||
} else {
|
||||
#endif
|
||||
SegmentRef buffer_r = _segMan->dereference(buf);
|
||||
|
||||
if ((unsigned)buffer_r.maxSize >= str.size() + 1) {
|
||||
|
@ -374,6 +383,9 @@ void MessageState::outputString(reg_t buf, const Common::String &str) {
|
|||
if (buffer_r.maxSize > 0)
|
||||
_segMan->strcpy(buf, "");
|
||||
}
|
||||
#ifdef ENABLE_SCI32
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MessageState::lastQuery(int &module, MessageTuple &tuple) {
|
||||
|
|
|
@ -929,7 +929,14 @@ byte *SegManager::derefBulkPtr(reg_t pointer, int entries) {
|
|||
}
|
||||
|
||||
reg_t *SegManager::derefRegPtr(reg_t pointer, int entries) {
|
||||
#ifdef ENABLE_SCI32
|
||||
// HACK: Due to a limitation in the SegManager, we don't know if the pointer needs to be
|
||||
// word aligned. If it's a new style array, then it is just accessing the arrays from a
|
||||
// table and this doesn't need to be true.
|
||||
if (pointer.offset & 1 && pointer.segment != Arrays_seg_id) {
|
||||
#else
|
||||
if (pointer.offset & 1) {
|
||||
#endif
|
||||
warning("Unaligned pointer read: %04x:%04x expected with word alignment", PRINT_REG(pointer));
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -493,6 +493,14 @@ void DynMem::listAllDeallocatable(SegmentId segId, void *param, NoteCallback not
|
|||
|
||||
#ifdef ENABLE_SCI32
|
||||
|
||||
SegmentRef ArrayTable::dereference(reg_t pointer) {
|
||||
SegmentRef ret;
|
||||
ret.isRaw = false;
|
||||
ret.maxSize = _table[pointer.offset].getSize() * 2;
|
||||
ret.reg = _table[pointer.offset].getRawData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Common::String SciString::toString() {
|
||||
if (_type != 3)
|
||||
error("SciString::toString(): Array is not a string");
|
||||
|
|
|
@ -757,6 +757,7 @@ struct ArrayTable : public Table<SciArray<reg_t> > {
|
|||
ArrayTable() : Table<SciArray<reg_t> >(SEG_TYPE_ARRAY) {}
|
||||
|
||||
virtual void saveLoadWithSerializer(Common::Serializer &ser) {}
|
||||
SegmentRef dereference(reg_t pointer);
|
||||
};
|
||||
|
||||
struct StringTable : public Table<SciString> {
|
||||
|
|
|
@ -179,13 +179,7 @@ Common::Error SciEngine::run() {
|
|||
|
||||
// Set the savegame dir (actually, we set it to a fake value,
|
||||
// since we cannot let the game control where saves are stored)
|
||||
// Some SCI1.1 games (e.g. SQ4CD) complain if this is empty
|
||||
#ifdef ENABLE_SCI32
|
||||
if (getSciVersion() >= SCI_VERSION_2)
|
||||
strcpy(_gamestate->sys_strings->_strings[SYS_STRING_SAVEDIR]._value, "");
|
||||
else
|
||||
#endif
|
||||
strcpy(_gamestate->sys_strings->_strings[SYS_STRING_SAVEDIR]._value, "/");
|
||||
|
||||
SciVersion soundVersion = _gamestate->detectDoSoundType();
|
||||
|
||||
|
@ -274,6 +268,10 @@ uint32 SciEngine::getFlags() const {
|
|||
return _gameDescription->flags;
|
||||
}
|
||||
|
||||
bool SciEngine::isDemo() const {
|
||||
return getFlags() & ADGF_DEMO;
|
||||
}
|
||||
|
||||
Common::String SciEngine::getSavegameName(int nr) const {
|
||||
return _targetName + Common::String::printf(".%03d", nr);
|
||||
}
|
||||
|
|
|
@ -134,6 +134,7 @@ public:
|
|||
Kernel *getKernel() const { return _kernel; }
|
||||
EngineState *getEngineState() const { return _gamestate; }
|
||||
Vocabulary *getVocabulary() const { return _vocabulary; }
|
||||
bool isDemo() const;
|
||||
|
||||
Common::String getSavegameName(int nr) const;
|
||||
Common::String getSavegamePattern() const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue