diff options
-rw-r--r-- | engines/agi/agi.h | 7 | ||||
-rw-r--r-- | engines/agi/detection.cpp | 2 | ||||
-rw-r--r-- | engines/agi/op_cmd.cpp | 22 | ||||
-rw-r--r-- | engines/agi/view.cpp | 9 |
4 files changed, 38 insertions, 2 deletions
diff --git a/engines/agi/agi.h b/engines/agi/agi.h index d5959382ef..7aa218d0fa 100644 --- a/engines/agi/agi.h +++ b/engines/agi/agi.h @@ -130,6 +130,9 @@ enum AgiGameType { /* * GF_OLDAMIGAV20 means that the interpreter is an old Amiga AGI interpreter that * uses value 20 for the computer type (v20 i.e. vComputer) rather than the usual value 5. + * + * GF_CLIPCOORDS means that views' coordinates must be clipped at least in commands + * position and position.v. */ enum AgiGameFeatures { GF_AGIMOUSE = (1 << 0), @@ -141,7 +144,8 @@ enum AgiGameFeatures { GF_FANMADE = (1 << 6), GF_MENUS = (1 << 7), GF_ESCPAUSE = (1 << 8), - GF_OLDAMIGAV20 = (1 << 9) + GF_OLDAMIGAV20 = (1 << 9), + GF_CLIPCOORDS = (1 << 10) }; struct AGIGameDescription; @@ -873,6 +877,7 @@ private: public: void setCel(VtEntry *, int); + void clipViewCoordinates(VtEntry *v); void setLoop(VtEntry *, int); void setView(VtEntry *, int); void startUpdate(VtEntry *); diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp index 39442a5c8e..94947f1395 100644 --- a/engines/agi/detection.cpp +++ b/engines/agi/detection.cpp @@ -2011,7 +2011,7 @@ static const AGIGameDescription gameDescriptions[] = { FANMADE_I("sq0", "v1.04", "2ad9d1a4624a98571ee77dcc83f231b6"), FANMADE_I("sqx", "v10.0 Feb 05", "c992ae2f8ab18360404efdf16fa9edd1"), FANMADE_I("sqx", "v10.0 Jul 18", "812edec45cefad559d190ffde2f9c910"), - FANMADE("Space Trek (v1.0)", "807a1aeadb2ace6968831d36ab5ea37a"), + FANMADE_F("Space Trek (v1.0)", "807a1aeadb2ace6968831d36ab5ea37a", GF_CLIPCOORDS), FANMADE("Special Delivery", "88764dfe61126b8e73612c851b510a33"), FANMADE("Speeder Bike Challenge (v1.0)", "2deb25bab379285ca955df398d96c1e7"), FANMADE("Star Commander 1 - The Escape (v1.0)", "a7806f01e6fa14ebc029faa58f263750"), diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp index 7418d043be..873c0c5a11 100644 --- a/engines/agi/op_cmd.cpp +++ b/engines/agi/op_cmd.cpp @@ -757,11 +757,33 @@ cmd(erase) { cmd(position) { vt.xPos = vt.xPos2 = p1; vt.yPos = vt.yPos2 = p2; + + // WORKAROUND: Part of the fix for bug #1659209 "AGI: Space Trek sprite duplication" + // with an accompanying identical workaround in position.v-command (i.e. command 0x26). + // These two workarounds together make up the whole fix. The bug was caused by + // wrongly written script data in Space Trek v1.0's scripts (At least logics 4 and 11). + // Position-command was called with horizontal values over 200 (Outside the screen!). + // Clipping the coordinates so the views stay wholly on-screen seems to fix the problems. + // It is probable (Would have to check better with disassembly to be completely sure) + // that AGI 2.440 clipped its coordinates in its position and position.v-commands + // although AGI 2.917 certainly doesn't (Checked that with disassembly) and that's why + // Space Trek may have worked better with AGI 2.440 than with some other AGI versions. + // I haven't checked but if Space Trek solely abuses the position-command we wouldn't + // strictly need the identical workaround in the position.v-command but it does make + // for a nice symmetry. + if (g_agi->getFeatures() & GF_CLIPCOORDS) + g_agi->clipViewCoordinates(&vt); } cmd(position_f) { vt.xPos = vt.xPos2 = _v[p1]; vt.yPos = vt.yPos2 = _v[p2]; + + // WORKAROUND: Part of the fix for bug #1659209 "AGI: Space Trek sprite duplication" + // with an accompanying identical workaround in position-command (i.e. command 0x25). + // See that workaround's comment for more in-depth information. + if (g_agi->getFeatures() & GF_CLIPCOORDS) + g_agi->clipViewCoordinates(&vt); } cmd(get_posn) { diff --git a/engines/agi/view.cpp b/engines/agi/view.cpp index 48e3ca5e3f..2eb11c9b91 100644 --- a/engines/agi/view.cpp +++ b/engines/agi/view.cpp @@ -254,6 +254,15 @@ void AgiEngine::setCel(VtEntry *v, int n) { lSetCel(v, n); /* If position isn't appropriate, update it accordingly */ + clipViewCoordinates(v); +} + +/** + * Restrict view table entry's position so it stays wholly inside the screen. + * Also take horizon into account when clipping if not set to ignore it. + * @param v pointer to view table entry + */ +void AgiEngine::clipViewCoordinates(VtEntry *v) { if (v->xPos + v->xSize > _WIDTH) { v->flags |= UPDATE_POS; v->xPos = _WIDTH - v->xSize; |