aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/kernel.cpp11
-rw-r--r--engines/sci/engine/kernel.h9
-rw-r--r--engines/sci/engine/kernel32.cpp233
-rw-r--r--engines/sci/engine/kevent.cpp6
-rw-r--r--engines/sci/engine/kfile.cpp4
-rw-r--r--engines/sci/engine/kgraphics.cpp2
-rw-r--r--engines/sci/engine/kscripts.cpp3
-rw-r--r--engines/sci/engine/script.cpp4
-rw-r--r--engines/sci/engine/seg_manager.cpp86
-rw-r--r--engines/sci/engine/seg_manager.h15
-rw-r--r--engines/sci/engine/segment.cpp41
-rw-r--r--engines/sci/engine/segment.h111
-rw-r--r--engines/sci/engine/vm.h4
-rw-r--r--engines/sci/gui/gui_dummy.h55
-rw-r--r--engines/sci/sci.cpp23
15 files changed, 592 insertions, 15 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 73c65245cd..717e850c3f 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -187,7 +187,7 @@ SciKernelFunction kfunct_mappers[] = {
/*00*/ DEFUN("Load", kLoad, "iii*"),
/*01*/ DEFUN("UnLoad", kUnLoad, "i.*"),
/*02*/ DEFUN("ScriptID", kScriptID, "Ioi*"),
- /*03*/ DEFUN("DisposeScript", kDisposeScript, "Oi"), // Work around QfG1 bug
+ /*03*/ DEFUN("DisposeScript", kDisposeScript, "Oii*"), // Work around QfG1 bug
/*04*/ DEFUN("Clone", kClone, "o"),
/*05*/ DEFUN("DisposeClone", kDisposeClone, "o"),
/*06*/ DEFUN("IsObject", kIsObject, "."),
@@ -217,7 +217,7 @@ SciKernelFunction kfunct_mappers[] = {
// FIXME: signature check removed (set to .*) as kGetEvent is different in Mac versions
/*1c*/ DEFUN("GetEvent", kGetEvent, ".*"),
///*1c*/ DEFUN("GetEvent", kGetEvent, "io"),
- /*1d*/ DEFUN("GlobalToLocal", kGlobalToLocal, "o"),
+ /*1d*/ DEFUN("GlobalToLocal", kGlobalToLocal, "oo*"),
/*1e*/ DEFUN("LocalToGlobal", kLocalToGlobal, "o"),
/*1f*/ DEFUN("MapKeyToDir", kMapKeyToDir, "o"),
/*20*/ DEFUN("DrawMenuBar", kDrawMenuBar, "i"),
@@ -336,6 +336,13 @@ SciKernelFunction kfunct_mappers[] = {
DEFUN("TextColors", kTextColors, ".*"),
DEFUN("TextFonts", kTextFonts, ".*"),
DEFUN("Portrait", kPortrait, ".*"),
+
+#ifdef ENABLE_SCI32
+ // SCI32 Kernel Functions
+ DEFUN("IsHiRes", kIsHiRes, ""),
+ DEFUN("Array", kArray, ".*"),
+ DEFUN("String", kString, ".*"),
+#endif
// its a stub, but its needed for Pharkas to work
DEFUN("PalVary", kPalVary, "ii*"),
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 758f9ae9d7..0e94fa5bc8 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -390,6 +390,13 @@ reg_t kPlatform(EngineState *s, int argc, reg_t *argv);
reg_t kTextColors(EngineState *s, int argc, reg_t *argv);
reg_t kTextFonts(EngineState *s, int argc, reg_t *argv);
+#ifdef ENABLE_SCI32
+// SCI2 Kernel Functions
+reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv);
+reg_t kArray(EngineState *s, int argc, reg_t *argv);
+reg_t kString(EngineState *s, int argc, reg_t *argv);
+#endif
+
} // End of namespace Sci
-#endif // SCI_ENGIENE_KERNEL_H
+#endif // SCI_ENGINE_KERNEL_H
diff --git a/engines/sci/engine/kernel32.cpp b/engines/sci/engine/kernel32.cpp
index 4c8b486653..c6ac0324d9 100644
--- a/engines/sci/engine/kernel32.cpp
+++ b/engines/sci/engine/kernel32.cpp
@@ -23,12 +23,14 @@
*
*/
+#ifdef ENABLE_SCI32
+
#include "sci/engine/kernel.h"
+#include "sci/engine/segment.h"
+#include "sci/engine/state.h"
namespace Sci {
-#ifdef ENABLE_SCI32
-
static const char *sci2_default_knames[] = {
/*0x00*/ "Load",
/*0x01*/ "UnLoad",
@@ -341,6 +343,231 @@ void Kernel::setKernelNamesSci21() {
_kernelNames = Common::StringList(sci21_default_knames, ARRAYSIZE(sci21_default_knames));
}
-#endif // ENABLE_SCI32
+// SCI2 Kernel Functions
+
+reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) {
+ // Returns 0 if the screen width or height is less than 640 or 400, respectively.
+ if (g_system->getWidth() < 640 || g_system->getHeight() < 400)
+ return make_reg(0, 0);
+
+ return make_reg(0, 1);
+}
+
+reg_t kArray(EngineState *s, int argc, reg_t *argv) {
+ switch (argv[0].toUint16()) {
+ case 0: { // New
+ reg_t arrayHandle;
+ SciArray<reg_t> *array = s->_segMan->allocateArray(&arrayHandle);
+ array->setType(argv[2].toUint16());
+ array->setSize(argv[1].toUint16());
+ return arrayHandle;
+ }
+ case 1: { // Size
+ SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]);
+ return make_reg(0, array->getSize());
+ }
+ case 2: { // At
+ SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]);
+ return array->getValue(argv[2].toUint16());
+ }
+ case 3: { // Atput
+ SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]);
+
+ uint32 index = argv[2].toUint16();
+ uint32 count = argc - 3;
+
+ if (index + count > 65535)
+ break;
+
+ if (array->getSize() < index + count)
+ array->setSize(index + count);
+
+ for (uint16 i = 0; i < count; i++)
+ array->setValue(i + index, argv[i + 3]);
+
+ return argv[1]; // We also have to return the handle
+ }
+ case 4: // Free
+ s->_segMan->freeArray(argv[1]);
+ return s->r_acc;
+ case 5: { // Fill
+ SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]);
+ uint16 index = argv[2].toUint16();
+
+ // A count of -1 means fill the rest of the array
+ uint16 count = argv[3].toSint16() == -1 ? array->getSize() - index : argv[3].toUint16();
+
+ if (array->getSize() < index + count)
+ array->setSize(index + count);
+
+ for (uint16 i = 0; i < count; i++)
+ array->setValue(i + index, argv[4]);
+
+ return argv[1];
+ }
+ case 6: { // Cpy
+ SciArray<reg_t> *array1 = s->_segMan->lookupArray(argv[1]);
+ SciArray<reg_t> *array2 = s->_segMan->lookupArray(argv[3]);
+ uint32 index1 = argv[2].toUint16();
+ uint32 index2 = argv[4].toUint16();
+
+ // The original engine ignores bad copies too
+ if (index2 > array2->getSize())
+ break;
+
+ // A count of -1 means fill the rest of the array
+ uint32 count = argv[5].toSint16() == -1 ? array2->getSize() - index2 : argv[5].toUint16();
+
+ if (array1->getSize() < index1 + count)
+ array1->setSize(index1 + count);
+
+ for (uint16 i = 0; i < count; i++)
+ array1->setValue(i + index1, array2->getValue(i + index2));
+
+ return argv[1];
+ }
+ case 7: // Cmp
+ // Not implemented in SSCI
+ return s->r_acc;
+ case 8: { // Dup
+ SciArray<reg_t> *array = s->_segMan->lookupArray(argv[1]);
+ reg_t arrayHandle;
+ SciArray<reg_t> *dupArray = s->_segMan->allocateArray(&arrayHandle);
+ *dupArray = SciArray<reg_t>(*array);
+ return arrayHandle;
+ }
+ case 9: // Getdata
+ if (!s->_segMan->isHeapObject(argv[1]))
+ return argv[1];
+
+ return GET_SEL32(s->_segMan, argv[1], data);
+ default:
+ error("Unknown kArray subop %d", argv[0].toUint16());
+ }
+
+ return NULL_REG;
+}
+
+reg_t kString(EngineState *s, int argc, reg_t *argv) {
+ switch (argv[0].toUint16()) {
+ case 0: { // New
+ reg_t stringHandle;
+ SciString *string = s->_segMan->allocateString(&stringHandle);
+ string->setType(3);
+ string->setSize(argv[1].toUint16());
+ return stringHandle;
+ }
+ case 1: // Size
+ return make_reg(0, s->_segMan->getString(argv[1]).size());
+ case 2: // At
+ return make_reg(0, s->_segMan->getString(argv[1])[argv[2].toUint16()]);
+ case 3: { // Atput
+ SciString *string = s->_segMan->lookupString(argv[1]);
+
+ uint32 index = argv[2].toUint16();
+ uint32 count = argc - 3;
+
+ if (index + count > 65535)
+ break;
+
+ if (string->getSize() < index + count)
+ string->setSize(index + count);
+
+ for (uint16 i = 0; i < count; i++)
+ string->setValue(i + index, argv[i + 3].toUint16());
+
+ return argv[1]; // We also have to return the handle
+ }
+ case 4: // Free
+ s->_segMan->freeString(argv[1]);
+ return s->r_acc;
+ case 5: { // Fill
+ SciString *string = s->_segMan->lookupString(argv[1]);
+ uint16 index = argv[2].toUint16();
+
+ // A count of -1 means fill the rest of the array
+ uint16 count = argv[3].toSint16() == -1 ? string->getSize() - index : argv[3].toUint16();
+
+ if (string->getSize() < index + count)
+ string->setSize(index + count);
+
+ for (uint16 i = 0; i < count; i++)
+ string->setValue(i + index, argv[4].toUint16());
+
+ return argv[1];
+ }
+ case 6: { // Cpy
+ SciString *string1 = s->_segMan->lookupString(argv[1]);
+ Common::String string2 = s->_segMan->getString(argv[3]);
+ uint32 index1 = argv[2].toUint16();
+ uint32 index2 = argv[4].toUint16();
+
+ // The original engine ignores bad copies too
+ if (index2 > string2.size())
+ break;
+
+ // A count of -1 means fill the rest of the array
+ uint32 count = argv[5].toSint16() == -1 ? string2.size() - index2 : argv[5].toUint16();
+
+ if (string1->getSize() < index1 + count)
+ string1->setSize(index1 + count);
+
+ for (uint16 i = 0; i < count; i++)
+ string1->setValue(i + index1, string2[i + index2]);
+
+ return argv[1];
+ }
+ case 7: { // Cmp
+ Common::String string1, string2;
+
+ if (argv[1].isNull())
+ string1 = "";
+ else
+ string1 = s->_segMan->lookupString(argv[1])->toString();
+
+ if (argv[2].isNull())
+ string2 = "";
+ else
+ string2 = s->_segMan->lookupString(argv[2])->toString();
+
+ if (argc == 4) // Strncmp
+ return make_reg(0, strncmp(string1.c_str(), string2.c_str(), argv[3].toUint16()));
+ else // Strcmp
+ return make_reg(0, strcmp(string1.c_str(), string2.c_str()));
+ }
+ case 8: { // Dup
+ SciString *string = s->_segMan->lookupString(argv[1]);
+ reg_t stringHandle;
+ SciString *dupString = s->_segMan->allocateString(&stringHandle);
+ *dupString = SciString(*string);
+ return stringHandle;
+ }
+ case 9: // Getdata
+ if (!s->_segMan->isHeapObject(argv[1]))
+ return argv[1];
+
+ return GET_SEL32(s->_segMan, argv[1], data);
+ case 10: { // Stringlen
+ SciString *sciString = s->_segMan->lookupString(argv[1]);
+ Common::String string = sciString->toString();
+ return make_reg(0, string.size());
+ }
+ case 11: // Printf
+ warning("kString(Printf)");
+ break;
+ case 12: // Printf Buf
+ warning("kString(PrintfBuf)");
+ break;
+ case 13: // atoi
+ warning("kString(atoi)");
+ break;
+ default:
+ error("Unknown kString subop %d", argv[0].toUint16());
+ }
+
+ return NULL_REG;
+}
} // End of namespace Sci
+
+#endif // ENABLE_SCI32
diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp
index 02e1961d80..ffdc597652 100644
--- a/engines/sci/engine/kevent.cpp
+++ b/engines/sci/engine/kevent.cpp
@@ -205,6 +205,12 @@ reg_t kMapKeyToDir(EngineState *s, int argc, reg_t *argv) {
}
reg_t kGlobalToLocal(EngineState *s, int argc, reg_t *argv) {
+#ifdef ENABLE_SCI32
+ // SCI32 has an extra argument for a plane here
+ if (argc > 1)
+ warning("kGlobalToLocal Plane: %04x:%04x", PRINT_REG(argv[1]));
+#endif
+
reg_t obj = argc ? argv[0] : NULL_REG; // Can this really happen? Lars
SegManager *segMan = s->_segMan;
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index c3b5f0f296..a7a39042dc 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -377,8 +377,8 @@ reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) {
reg_t kGetSaveDir(EngineState *s, int argc, reg_t *argv) {
#ifdef ENABLE_SCI32
// TODO: SCI32 uses a parameter here.
- if (argc > 0)
- warning("kGetSaveDir called with a parameter");
+ if (argc > 0)
+ warning("kGetSaveDir called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[0]));
#endif
return make_reg(s->sys_strings_segment, SYS_STRING_SAVEDIR);
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 0a836f581d..e5ca2d8fb4 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -292,7 +292,7 @@ reg_t kGraph(EngineState *s, int argc, reg_t *argv) {
break;
default:
- error("Unsupported kGraph() operation %04x", argv[0].toSint16());
+ warning("Unsupported kGraph() operation %04x", argv[0].toSint16());
}
#ifdef INCLUDE_OLDGFX
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 52e66e7fb5..51fe7b887c 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -225,7 +225,8 @@ reg_t kDisposeScript(EngineState *s, int argc, reg_t *argv) {
if (argc != 2) {
return s->r_acc;
} else {
- // This exists in the KQ5CD interpreter, but a test case hasn't been found yet
+ // This exists in the KQ5CD and GK1 interpreter. We know it is used when GK1 starts
+ // up, before the Sierra logo.
warning("kDisposeScript called with 2 parameters, still untested");
return argv[1];
}
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 7bd8402663..0bab7f31ae 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -237,6 +237,10 @@ void Kernel::mapSelectors() {
FIND_SELECTOR(topString);
FIND_SELECTOR(scaleX);
FIND_SELECTOR(scaleY);
+
+#ifdef ENABLE_SCI32
+ FIND_SELECTOR(data);
+#endif
}
void Kernel::dumpScriptObject(char *data, int seeker, int objsize) {
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 79f2e88f9e..5db6b88136 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -53,6 +53,11 @@ SegManager::SegManager(ResourceManager *resMan) {
Lists_seg_id = 0;
Nodes_seg_id = 0;
Hunks_seg_id = 0;
+
+#ifdef ENABLE_SCI32
+ Arrays_seg_id = 0;
+ String_seg_id = 0;
+#endif
_exportsAreWide = false;
_resMan = resMan;
@@ -1250,4 +1255,85 @@ void SegManager::createClassTable() {
_resMan->unlockResource(vocab996);
}
+#ifdef ENABLE_SCI32
+SciArray<reg_t> *SegManager::allocateArray(reg_t *addr) {
+ ArrayTable *table;
+ int offset;
+
+ if (!Arrays_seg_id) {
+ table = (ArrayTable *)allocSegment(new ArrayTable(), &(Arrays_seg_id));
+ } else
+ table = (ArrayTable *)_heap[Arrays_seg_id];
+
+ offset = table->allocEntry();
+
+ *addr = make_reg(Arrays_seg_id, offset);
+ return &(table->_table[offset]);
+}
+
+SciArray<reg_t> *SegManager::lookupArray(reg_t addr) {
+ if (_heap[addr.segment]->getType() != SEG_TYPE_ARRAY)
+ error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
+
+ ArrayTable *arrayTable = (ArrayTable *)_heap[addr.segment];
+
+ if (!arrayTable->isValidEntry(addr.offset))
+ error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
+
+ return &(arrayTable->_table[addr.offset]);
+}
+
+void SegManager::freeArray(reg_t addr) {
+ if (_heap[addr.segment]->getType() != SEG_TYPE_ARRAY)
+ error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
+
+ ArrayTable *arrayTable = (ArrayTable *)_heap[addr.segment];
+
+ if (!arrayTable->isValidEntry(addr.offset))
+ error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
+
+ arrayTable->freeEntry(addr.offset);
+}
+
+SciString *SegManager::allocateString(reg_t *addr) {
+ StringTable *table;
+ int offset;
+
+ if (!String_seg_id) {
+ table = (StringTable *)allocSegment(new StringTable(), &(String_seg_id));
+ } else
+ table = (StringTable *)_heap[String_seg_id];
+
+ offset = table->allocEntry();
+
+ *addr = make_reg(String_seg_id, offset);
+ return &(table->_table[offset]);
+}
+
+SciString *SegManager::lookupString(reg_t addr) {
+ if (_heap[addr.segment]->getType() != SEG_TYPE_STRING)
+ error("Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
+
+ StringTable *stringTable = (StringTable *)_heap[addr.segment];
+
+ if (!stringTable->isValidEntry(addr.offset))
+ error("Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
+
+ return &(stringTable->_table[addr.offset]);
+}
+
+void SegManager::freeString(reg_t addr) {
+ if (_heap[addr.segment]->getType() != SEG_TYPE_STRING)
+ error("Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
+
+ StringTable *stringTable = (StringTable *)_heap[addr.segment];
+
+ if (!stringTable->isValidEntry(addr.offset))
+ error("Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
+
+ stringTable->freeEntry(addr.offset);
+}
+
+#endif
+
} // End of namespace Sci
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 2e785b1341..4d385e0d32 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -440,6 +440,16 @@ public:
public: // TODO: make private
Common::Array<SegmentObj *> _heap;
Common::Array<Class> _classtable; /**< Table of all classes */
+
+#ifdef ENABLE_SCI32
+ SciArray<reg_t> *allocateArray(reg_t *addr);
+ SciArray<reg_t> *lookupArray(reg_t addr);
+ void freeArray(reg_t addr);
+ SciString *allocateString(reg_t *addr);
+ SciString *lookupString(reg_t addr);
+ void freeString(reg_t addr);
+ SegmentId getStringSegmentId() { return String_seg_id; }
+#endif
private:
/** Map script ids to segment ids. */
@@ -454,6 +464,11 @@ private:
SegmentId Nodes_seg_id; ///< ID of the (a) node segment
SegmentId Hunks_seg_id; ///< ID of the (a) hunk segment
+#ifdef ENABLE_SCI32
+ SegmentId Arrays_seg_id;
+ SegmentId String_seg_id;
+#endif
+
private:
SegmentObj *allocSegment(SegmentObj *mem, SegmentId *segid);
LocalVariables *allocLocalsSegment(Script *scr, int count);
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index fee8a9f4a7..e8b47727ba 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -66,6 +66,14 @@ SegmentObj *SegmentObj::createSegmentObj(SegmentType type) {
case SEG_TYPE_DYNMEM:
mem = new DynMem();
break;
+#ifdef ENABLE_SCI32
+ case SEG_TYPE_ARRAY:
+ mem = new ArrayTable();
+ break;
+ case SEG_TYPE_STRING:
+ mem = new StringTable();
+ break;
+#endif
default:
error("Unknown SegmentObj type %d", type);
break;
@@ -478,5 +486,38 @@ void DynMem::listAllDeallocatable(SegmentId segId, void *param, NoteCallback not
(*note)(param, make_reg(segId, 0));
}
+#ifdef ENABLE_SCI32
+
+Common::String SciString::toString() {
+ if (_type != 3)
+ error("SciString::toString(): Array is not a string");
+
+ Common::String string;
+ for (uint32 i = 0; i < _size && _data[i] != 0; i++)
+ string += _data[i];
+
+ return string;
+}
+
+void SciString::fromString(Common::String string) {
+ if (_type != 3)
+ error("SciString::fromString(): Array is not a string");
+
+ if (string.size() > _size)
+ setSize(string.size());
+
+ for (uint32 i = 0; i < string.size(); i++)
+ _data[i] = string[i];
+}
+
+SegmentRef StringTable::dereference(reg_t pointer) {
+ SegmentRef ret;
+ ret.isRaw = false;
+ ret.maxSize = _table[pointer.offset].getSize();
+ ret.raw = (byte*)_table[pointer.offset].getRawData();
+ return ret;
+}
+
+#endif
} // End of namespace Sci
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 7266dc3b38..a6ffeb773a 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -63,6 +63,11 @@ enum SegmentType {
SEG_TYPE_HUNK = 8,
SEG_TYPE_DYNMEM = 9,
SEG_TYPE_STRING_FRAG = 10, // obsolete, we keep it to be able to load old saves
+
+#ifdef ENABLE_SCI32
+ SEG_TYPE_ARRAY = 11,
+ SEG_TYPE_STRING = 12,
+#endif
SEG_TYPE_MAX // For sanity checking
};
@@ -659,6 +664,112 @@ public:
virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
+#ifdef ENABLE_SCI32
+
+template <typename T>
+class SciArray {
+public:
+ SciArray() {
+ _type = -1;
+ _data = NULL;
+ _size = 0;
+ _actualSize = 0;
+ }
+
+ ~SciArray() {
+ delete[] _data;
+ }
+
+ void setType(byte type) {
+ if (_type >= 0)
+ error("SciArray::setType(): Type already set");
+
+ _type = type;
+ }
+
+ void setSize(uint32 size) {
+ if (_type < 0)
+ error("SciArray::setSize(): No type set");
+
+ // Check if we don't have to do anything
+ if (_size == size)
+ return;
+
+ // Check if we don't have to expand the array
+ if (size <= _actualSize) {
+ _size = size;
+ return;
+ }
+
+ // So, we're going to have to create an array of some sort
+ T *newArray = new T[size];
+
+ // Check if we never created an array before
+ if (!_data) {
+ _data = newArray;
+ return;
+ }
+
+ // Copy data from the old array to the new
+ memcpy(newArray, _data, _size * sizeof(T));
+
+ // Now set the new array to the old and set the sizes
+ delete[] _data;
+ _data = newArray;
+ _size = _actualSize = size;
+ }
+
+ T getValue(uint16 index) {
+ if (index >= _size)
+ error("SciArray::getValue(): %d is out of bounds (%d)", index, _size);
+
+ return _data[index];
+ }
+
+ void setValue(uint16 index, T value) {
+ if (index >= _size)
+ error("SciArray::setValue(): %d is out of bounds (%d)", index, _size);
+
+ _data[index] = value;
+ }
+
+ byte getType() { return _type; }
+ uint32 getSize() { return _size; }
+ T *getRawData() { return _data; }
+
+ //Common::String toString();
+ //void fromString(Common::String string);
+
+protected:
+ int8 _type;
+ T *_data;
+ uint32 _size; // _size holds the number of entries that the scripts have requested
+ uint32 _actualSize; // _actualSize is the actual numbers of entries allocated
+};
+
+class SciString : public SciArray<char> {
+public:
+ SciString() : SciArray<char>() {}
+
+ Common::String toString();
+ void fromString(Common::String string);
+};
+
+struct ArrayTable : public Table<SciArray<reg_t> > {
+ ArrayTable() : Table<SciArray<reg_t> >(SEG_TYPE_ARRAY) {}
+
+ virtual void saveLoadWithSerializer(Common::Serializer &ser) {}
+};
+
+struct StringTable : public Table<SciString> {
+ StringTable() : Table<SciString>(SEG_TYPE_STRING) {}
+
+ virtual void saveLoadWithSerializer(Common::Serializer &ser) {}
+ SegmentRef dereference(reg_t pointer);
+};
+
+#endif
+
} // End of namespace Sci
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index def56cbcb9..25bca2148c 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -195,6 +195,10 @@ struct SelectorCache {
// Used for auto detection purposes
Selector overlay; ///< Used to determine if a game is using old gfx functions or not
Selector setCursor; ///< For cursor semantics autodetection
+
+#ifdef ENABLE_SCI32
+ Selector data; // Used by Array()
+#endif
};
// A reference to an object's variable.
diff --git a/engines/sci/gui/gui_dummy.h b/engines/sci/gui/gui_dummy.h
new file mode 100644
index 0000000000..6ba5a8c8de
--- /dev/null
+++ b/engines/sci/gui/gui_dummy.h
@@ -0,0 +1,55 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef SCI_GUI_DUMMY_H
+#define SCI_GUI_DUMMY_H
+
+#include "sci/gui/gui.h"
+
+namespace Sci {
+
+class SciGuiDummy : public SciGui {
+public:
+ SciGuiDummy(EngineState *s, SciGuiScreen *screen, SciGuiPalette *palette, SciGuiCursor *cursor) : SciGui(s, screen, palette, cursor) {}
+ virtual ~SciGuiDummy() {}
+
+ virtual uint16 onControl(byte screenMask, Common::Rect rect) { return 0; }
+ virtual void animate(reg_t listReference, bool cycle, int argc, reg_t *argv) {}
+ virtual void addToPicList(reg_t listReference, int argc, reg_t *argv) {}
+ virtual void addToPicView(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 leftPos, int16 topPos, int16 priority, int16 control) {}
+ virtual void setNowSeen(reg_t objectReference) {}
+ virtual bool canBeHere(reg_t curObject, reg_t listReference) { return false; }
+ virtual bool isItSkip(GuiResourceId viewId, int16 loopNo, int16 celNo, Common::Point position) { return false; }
+ virtual void baseSetter(reg_t object) {}
+
+ virtual int16 getCelWidth(GuiResourceId viewId, int16 loopNo, int16 celNo) { return 0; }
+ virtual int16 getCelHeight(GuiResourceId viewId, int16 loopNo, int16 celNo) { return 0; }
+ virtual int16 getLoopCount(GuiResourceId viewId) { return 0; }
+ virtual int16 getCelCount(GuiResourceId viewId, int16 loopNo) { return 0; }
+};
+
+} // End of namespace Sci
+
+#endif
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 5daa8e2e23..c9e33ac85f 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -44,6 +44,9 @@
#include "sci/sfx/audio.h"
#include "sci/sfx/soundcmd.h"
#include "sci/gui/gui.h"
+#ifdef ENABLE_SCI32
+#include "sci/gui/gui_dummy.h"
+#endif
#include "sci/gui/gui_palette.h"
#include "sci/gui/gui_cursor.h"
#include "sci/gui/gui_screen.h"
@@ -114,11 +117,12 @@ Common::Error SciEngine::run() {
return Common::kNoGameDataFoundError;
}
- bool upscaledHires = false;
-
// Scale the screen, if needed
- if (!strcmp(getGameID(), "kq6") && getPlatform() == Common::kPlatformWindows)
- upscaledHires = true;
+ bool upscaledHires = (!strcmp(getGameID(), "kq6")
+#ifdef ENABLE_SCI32
+ || getSciVersion() >= SCI_VERSION_2
+#endif
+ ) && getPlatform() == Common::kPlatformWindows;
// TODO: Detect japanese editions and set upscaledHires on those as well
// TODO: Possibly look at first picture resource and determine if its hires or not
@@ -144,6 +148,12 @@ Common::Error SciEngine::run() {
if (script_init_engine(_gamestate))
return Common::kUnknownError;
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2) {
+ // Falsify the Views with a Dummy GUI
+ _gamestate->_gui = new SciGuiDummy(_gamestate, screen, palette, cursor);
+ } else {
+#endif
#ifdef INCLUDE_OLDGFX
#ifndef USE_OLDGFX
_gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor); // new
@@ -151,7 +161,10 @@ Common::Error SciEngine::run() {
_gamestate->_gui = new SciGui32(_gamestate, screen, palette, cursor); // old
#endif
#else
- _gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor);
+ _gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor);
+#endif
+#ifdef ENABLE_SCI32
+ }
#endif
if (game_init(_gamestate)) { /* Initialize */