aboutsummaryrefslogtreecommitdiff
path: root/engines/made/database.cpp
diff options
context:
space:
mode:
authorBenjamin Haisch2008-05-05 10:45:11 +0000
committerBenjamin Haisch2008-05-05 10:45:11 +0000
commitb6c7385eb4fea90dd315124fe5bffe874430eb48 (patch)
tree2ac22b5cafe9b9e5bbb7cbf616f0e5c41b34ba64 /engines/made/database.cpp
parent665caae8b4e06a8a87ab41de0f2361bba4c7cf4f (diff)
downloadscummvm-rg350-b6c7385eb4fea90dd315124fe5bffe874430eb48.tar.gz
scummvm-rg350-b6c7385eb4fea90dd315124fe5bffe874430eb48.tar.bz2
scummvm-rg350-b6c7385eb4fea90dd315124fe5bffe874430eb48.zip
- Renamed XmidiResource to GenericResource
- Added MIDI resource type - Added ScriptFunctionsLgop2 and ScriptFunctionsMhne (for Leather Goddesses of Phobos 2 and The Manhole: New and Enhanced, resp.) - Many changes for LGOP2 and The Manhole: N&E Note about the new ScriptFunctions classes: I copied the ScriptFunctionsRtz class and so duplicated a lot of code. Most of the opcode functions are the same in all games but there might be differences. Once all common opcode functions have been figured out, they'll be moved to a common place (like the ScriptFunctions class). svn-id: r31871
Diffstat (limited to 'engines/made/database.cpp')
-rw-r--r--engines/made/database.cpp154
1 files changed, 133 insertions, 21 deletions
diff --git a/engines/made/database.cpp b/engines/made/database.cpp
index 108d1391e5..406639a1fc 100644
--- a/engines/made/database.cpp
+++ b/engines/made/database.cpp
@@ -47,7 +47,7 @@ Object::~Object() {
delete[] _objData;
}
-int Object::load(Common::SeekableReadStream &source) {
+int Object::loadVersion2(Common::SeekableReadStream &source) {
_freeData = true;
uint16 type = source.readUint16LE();
if (type == 0x7FFF) {
@@ -59,6 +59,27 @@ int Object::load(Common::SeekableReadStream &source) {
byte count2 = source.readByte();
_objSize = (count1 + count2) * 2;
}
+ source.seek(-4, SEEK_CUR);
+ _objSize += 6;
+ _objData = new byte[_objSize];
+ WRITE_LE_UINT16(_objData, 1);
+ source.read(_objData + 2, _objSize - 2);
+ return _objSize - 2;
+}
+
+int Object::loadVersion3(Common::SeekableReadStream &source) {
+ _freeData = true;
+ source.readUint16LE(); // skip flags
+ uint16 type = source.readUint16LE();
+ if (type == 0x7FFF) {
+ _objSize = source.readUint16LE();
+ } else if (type == 0x7FFE) {
+ _objSize = source.readUint16LE() * 2;
+ } else if (type < 0x7FFE) {
+ byte count1 = source.readByte();
+ byte count2 = source.readByte();
+ _objSize = (count1 + count2) * 2;
+ }
source.seek(-6, SEEK_CUR);
_objSize += 6;
_objData = new byte[_objSize];
@@ -66,7 +87,7 @@ int Object::load(Common::SeekableReadStream &source) {
return _objSize;
}
-int Object::load(byte *source) {
+int Object::loadVersion3(byte *source) {
_objData = source;
_freeData = false;
if (getClass() < 0x7FFE) {
@@ -175,11 +196,14 @@ void Object::dump(const char *filename) {
}
GameDatabase::GameDatabase(MadeEngine *vm) : _vm(vm) {
+ _gameText = NULL;
}
GameDatabase::~GameDatabase() {
if (_gameState)
delete[] _gameState;
+ if (_gameText)
+ delete[] _gameText;
}
void GameDatabase::open(const char *filename) {
@@ -218,7 +242,7 @@ void GameDatabase::loadVersion2(Common::SeekableReadStream &sourceS) {
sourceS.seek(0x1C);
- uint32 textStartOffs = sourceS.readUint16LE() * 512;
+ uint32 textOffs = sourceS.readUint16LE() * 512;
uint16 objectCount = sourceS.readUint16LE();
uint16 varObjectCount = sourceS.readUint16LE();
_gameStateSize = sourceS.readUint16LE() * 2;
@@ -228,25 +252,31 @@ void GameDatabase::loadVersion2(Common::SeekableReadStream &sourceS) {
_mainCodeObjectIndex = sourceS.readUint16LE();
sourceS.readUint16LE(); // unknown
uint32 objectsSize = sourceS.readUint32LE() * 2;
+ uint32 textSize = objectsOffs - textOffs;
- debug(2, "textStartOffs = %08X; objectCount = %d; varObjectCount = %d; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", textStartOffs, objectCount, varObjectCount, _gameStateSize, objectsOffs, objectsSize);
+ debug(2, "textOffs = %08X; textSize = %08X; objectCount = %d; varObjectCount = %d; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", textOffs, textSize, objectCount, varObjectCount, _gameStateSize, objectsOffs, objectsSize);
_gameState = new byte[_gameStateSize];
memset(_gameState, 0, _gameStateSize);
+ sourceS.seek(textOffs);
+ _gameText = new char[textSize];
+ sourceS.read(_gameText, textSize);
+ // "Decrypt" the text data
+ for (int i = 0; i < textSize; i++)
+ _gameText[i] += 0x1E;
+
sourceS.seek(objectsOffs);
for (uint32 i = 0; i < objectCount; i++) {
Object *obj = new Object();
- int objSize = obj->load(sourceS);
+ int objSize = obj->loadVersion2(sourceS);
objSize = objSize % 2;
// objects are aligned on 2-byte-boundaries, skip unused bytes
sourceS.skip(objSize);
_objects.push_back(obj);
}
- printf("ok!\n"); fflush(stdout);
-
}
void GameDatabase::loadVersion3(Common::SeekableReadStream &sourceS) {
@@ -286,11 +316,10 @@ void GameDatabase::loadVersion3(Common::SeekableReadStream &sourceS) {
if (objectOffsets[i] & 1) {
debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1);
sourceS.seek(objectsOffs + objectOffsets[i] - 1);
- sourceS.readUint16LE(); // skip flags
- obj->load(sourceS);
+ obj->loadVersion3(sourceS);
} else {
debug(2, "-> var\n");
- obj->load(_gameState + objectOffsets[i]);
+ obj->loadVersion3(_gameState + objectOffsets[i]);
}
_objects.push_back(obj);
}
@@ -378,13 +407,80 @@ void GameDatabase::setVar(int16 index, int16 value) {
WRITE_LE_UINT16(_gameState + index * 2, value);
}
-int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
+int16 *GameDatabase::getObjectPropertyPtrV2(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
Object *obj = getObject(objectIndex);
int16 *prop = (int16*)obj->getData();
byte count1 = obj->getCount1();
byte count2 = obj->getCount2();
-
+
+ int16 *propPtr1 = prop + count1;
+ int16 *propPtr2 = prop + count2;
+
+ // First see if the property exists in the given object
+ while (count2-- > 0) {
+ if ((READ_LE_UINT16(prop) & 0x7FFF) == propertyId) {
+ propertyFlag = obj->getFlags() & 1;
+ return propPtr1;
+ }
+ prop++;
+ propPtr1++;
+ }
+
+ // Now check in the object hierarchy of the given object
+ int16 parentObjectIndex = obj->getClass();
+ if (parentObjectIndex == 0) {
+ //debug(2, "! NULL(np)\n");
+ return NULL;
+ }
+
+ while (parentObjectIndex != 0) {
+
+ //debug(2, "parentObjectIndex = %04X\n", parentObjectIndex);
+
+ obj = getObject(parentObjectIndex);
+
+ prop = (int16*)obj->getData();
+ count1 = obj->getCount1();
+ count2 = obj->getCount2();
+
+ propPtr1 = propPtr2 + count1 - count2;
+ int16 *propertyPtr = prop + count1;
+
+ while (count2-- > 0) {
+ if (!(READ_LE_UINT16(prop) & 0x8000)) {
+ if ((READ_LE_UINT16(prop) & 0x7FFF) == propertyId) {
+ propertyFlag = obj->getFlags() & 1;
+ return propPtr1;
+ } else {
+ propPtr1++;
+ }
+ } else {
+ if ((READ_LE_UINT16(prop) & 0x7FFF) == propertyId) {
+ propertyFlag = obj->getFlags() & 1;
+ return propertyPtr;
+ }
+ }
+ prop++;
+ propertyPtr++;
+ }
+
+ parentObjectIndex = obj->getClass();
+
+ }
+
+ //debug(2, "! NULL(nf)\n");
+ return NULL;
+
+}
+
+int16 *GameDatabase::getObjectPropertyPtrV3(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
+ Object *obj = getObject(objectIndex);
+
+ int16 *prop = (int16*)obj->getData();
+ byte count1 = obj->getCount1();
+ byte count2 = obj->getCount2();
+
int16 *propPtr1 = prop + count1;
int16 *propPtr2 = prop + count2;
@@ -402,27 +498,27 @@ int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, i
prop++;
propPtr1++;
}
-
+
// Now check in the object hierarchy of the given object
int16 parentObjectIndex = obj->getClass();
if (parentObjectIndex == 0) {
//debug(2, "! NULL(np)\n");
return NULL;
}
-
+
while (parentObjectIndex != 0) {
-
+
//debug(2, "parentObjectIndex = %04X\n", parentObjectIndex);
obj = getObject(parentObjectIndex);
-
+
prop = (int16*)obj->getData();
count1 = obj->getCount1();
count2 = obj->getCount2();
propPtr1 = propPtr2 + count1 - count2;
int16 *propertyPtr = prop + count1;
-
+
while (count2-- > 0) {
if (!(READ_LE_UINT16(prop) & 0x8000)) {
if ((READ_LE_UINT16(prop) & 0x3FFF) == propertyId) {
@@ -450,14 +546,26 @@ int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, i
prop++;
propertyPtr++;
}
-
+
parentObjectIndex = obj->getClass();
-
+
}
//debug(2, "! NULL(nf)\n");
return NULL;
-
+
+}
+
+int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
+ switch (_vm->_engineVersion) {
+ case 2:
+ return getObjectPropertyPtrV2(objectIndex, propertyId, propertyFlag);
+ case 3:
+ return getObjectPropertyPtrV3(objectIndex, propertyId, propertyFlag);
+ default:
+ error("GameDatabase::getObjectPropertyPtr() Unknown engine version");
+ return NULL;
+ }
}
int16 GameDatabase::getObjectProperty(int16 objectIndex, int16 propertyId) {
@@ -467,7 +575,7 @@ int16 GameDatabase::getObjectProperty(int16 objectIndex, int16 propertyId) {
int16 propertyFlag;
int16 *property = getObjectPropertyPtr(objectIndex, propertyId, propertyFlag);
-
+
if (property) {
return (int16)READ_LE_UINT16(property);
} else {
@@ -498,6 +606,10 @@ int16 GameDatabase::setObjectProperty(int16 objectIndex, int16 propertyId, int16
}
+const char *GameDatabase::getString(uint16 offset) {
+ return (const char*)&_gameText[offset * 4];
+}
+
void GameDatabase::dumpObject(int16 index) {
Object *obj = getObject(index);
char fn[512];