Skip to content

Commit 68396c1

Browse files
committed
GOB: Display hotspot creation details in degob
Previously, hotspot creation blocks were represented by a single "hotspots->evaluate()" line without any further details. We now display the hotspot data defined by these blocks (coordinates, type, callbacks offsets...). As a consequence, functions only reachable as a hotspot callback will now appear in degob output, while they were previously forgotten.
1 parent 70264bf commit 68396c1

File tree

3 files changed

+142
-2
lines changed

3 files changed

+142
-2
lines changed

engines/gob/degob_script.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ uint32 Script::getPos() const { return _ptr - _totData; }
239239
uint32 Script::lastOffsetPos() const { return _lastOffsetPos - _totData; }
240240
void Script::updateOffsetPos(uint32 pos) { _lastOffsetPos = _totData + pos; }
241241
void Script::skip(uint32 off) { seek(off, SEEK_CUR); }
242+
void Script::skipBlock() {seek(peekUint16(2) + 2, SEEK_CUR);}
242243
void Script::seek(uint32 off, int whence) {
243244
switch (whence) {
244245
case SEEK_END:

engines/gob/degob_script.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class Script {
7171
uint32 lastOffsetPos() const;
7272
void updateOffsetPos(uint32 pos);
7373
void skip(uint32 off);
74+
void skipBlock();
7475
void seek(uint32 off, int whence = SEEK_SET);
7576

7677
// Properties getter
@@ -234,6 +235,7 @@ class Script_v1 : public Script {
234235

235236
// Control functions
236237
void o1_callSub(FuncParams &params);
238+
void hotspotsEvaluate();
237239
void o1_switch(FuncParams &params);
238240
void o1_repeatUntil(FuncParams &params);
239241
void o1_whileDo(FuncParams &params);

engines/gob/degob_script_v1.cpp

Lines changed: 139 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,137 @@ void Script_v1::o1_goblinFunc(FuncParams &params) {
740740
goblinOpcode(cmd, gobParams);
741741
}
742742

743+
enum Type {
744+
kTypeNone = 0,
745+
kTypeMove = 1,
746+
kTypeClick = 2,
747+
kTypeInput1NoLeave = 3,
748+
kTypeInput1Leave = 4,
749+
kTypeInput2NoLeave = 5,
750+
kTypeInput2Leave = 6,
751+
kTypeInput3NoLeave = 7,
752+
kTypeInput3Leave = 8,
753+
kTypeInputFloatNoLeave = 9,
754+
kTypeInputFloatLeave = 10,
755+
kTypeEnable2 = 11,
756+
kTypeEnable1 = 12,
757+
kTypeClickEnter = 21
758+
};
759+
760+
void Script_v1::hotspotsEvaluate()
761+
{
762+
skip(1);
763+
byte count = readUint8();
764+
printIndent();
765+
print("set_hotspot_count(%d);\n", count);
766+
767+
printIndent();
768+
print("set_hotspot_properties(handleMouse=%d, duration=%d, leaveWinIndex=%d, hotspotIndex1=%d, hotspotIndex2=%d, needRecalc=%d)\n",
769+
peekUint8(0),
770+
peekUint8(1),
771+
peekUint8(2),
772+
peekUint8(3),
773+
peekUint8(4),
774+
peekUint8(5) != 0);
775+
776+
skip(6);
777+
778+
for (uint16 i = 0; i < count; i++) {
779+
printIndent();
780+
print("add_hotspot(%d, ", i);
781+
byte type = readUint8();
782+
print("%d", type);
783+
if ((type & 0x40) != 0) {
784+
type -= 0x40;
785+
print(", %d", readUint8());
786+
}
787+
if ((type & 0x80) != 0) {
788+
// Complex coordinate expressions
789+
print(", %d", getPos());
790+
print(", %s", readExpr().c_str());
791+
print(", %s", readExpr().c_str());
792+
print(", %s", readExpr().c_str());
793+
print(", %s", readExpr().c_str());
794+
} else {
795+
// Immediate values
796+
print(", %d", readUint16());
797+
print(", %d", readUint16());
798+
print(", %d", readUint16());
799+
print(", %d", readUint16());
800+
}
801+
802+
type &= 0x7F;
803+
804+
// Evaluate parameters for the new hotspot
805+
switch (type) {
806+
// TODO: handle kTypeEnable1 and kTypeEnable2 types
807+
case kTypeNone:
808+
skip(6);
809+
print(", %d", getPos());
810+
addFuncOffset(getPos());
811+
skipBlock();
812+
print(", %d", getPos());
813+
addFuncOffset(getPos());
814+
skipBlock();
815+
break;
816+
817+
case kTypeMove:
818+
print(", %d", readUint16());
819+
print(", %d", readUint16());
820+
print(", %d", readUint16());
821+
print(", %d", getPos());
822+
addFuncOffset(getPos());
823+
skipBlock();
824+
print(", %d", getPos());
825+
addFuncOffset(getPos());
826+
skipBlock();
827+
break;
828+
829+
case kTypeInput1NoLeave:
830+
case kTypeInput1Leave:
831+
case kTypeInput2NoLeave:
832+
case kTypeInput2Leave:
833+
case kTypeInput3NoLeave:
834+
case kTypeInput3Leave:
835+
case kTypeInputFloatNoLeave:
836+
case kTypeInputFloatLeave:
837+
print(", %d", readUint16());
838+
print(", %d", readUint16());
839+
print(", %d", readUint8());
840+
print(", %d", readUint8());
841+
if ((type >= kTypeInput2NoLeave) && (type <= kTypeInput3Leave)) {
842+
print(", %d", readUint16());
843+
print(", %s", readString());
844+
}
845+
skipBlock();
846+
break;
847+
848+
case 20:
849+
case kTypeClick:
850+
print(", %d", readUint16());
851+
print(", %d", readUint16());
852+
print(", %d", readUint16());
853+
print(", 0");
854+
print(", %d", getPos());
855+
addFuncOffset(getPos());
856+
skipBlock();
857+
break;
858+
859+
case kTypeClickEnter:
860+
print(", %d", readUint16());
861+
print(", %d", readUint16());
862+
print(", %d", readUint16() & 3);
863+
print(", %d", getPos());
864+
addFuncOffset(getPos());
865+
skipBlock();
866+
print(", 0");
867+
break;
868+
}
869+
870+
print(");\n");
871+
}
872+
}
873+
743874
void Script_v1::o1_callSub(FuncParams &params) {
744875
uint16 offset = readUint16();
745876

@@ -753,8 +884,14 @@ void Script_v1::o1_callSub(FuncParams &params) {
753884
print("sub_%d();\n", offset);
754885
if (offset >= 128)
755886
addFuncOffset(offset);
756-
} else if (peekUint8() == 2)
757-
print("_hotspots->evaluate()(%d);\n", offset);
887+
} else if (peekUint8() == 2) {
888+
print("_hotspots->evaluate()(%d) {\n", offset);
889+
incIndent();
890+
hotspotsEvaluate();
891+
decIndent();
892+
printIndent();
893+
print("}\n");
894+
}
758895
else
759896
print("<Unknown block type %d (%d)>\n", peekUint8(), offset);
760897

0 commit comments

Comments
 (0)