[Scummvm-cvs-logs] SF.net SVN: scummvm:[52512] scummvm/trunk/engines/sci/engine
m_kiewitz at users.sourceforge.net
m_kiewitz at users.sourceforge.net
Sat Sep 4 09:29:27 CEST 2010
Revision: 52512
http://scummvm.svn.sourceforge.net/scummvm/?rev=52512&view=rev
Author: m_kiewitz
Date: 2010-09-04 07:29:27 +0000 (Sat, 04 Sep 2010)
Log Message:
-----------
SCI: properly reversed kDoAvoider
getAngle()-code is missing though. Still fixes lsl2early hang on airport (bug #3037036), fixes kq4early unicorn doing moonwalk (kq4late still works as well)
Modified Paths:
--------------
scummvm/trunk/engines/sci/engine/kernel_tables.h
scummvm/trunk/engines/sci/engine/kmovement.cpp
Modified: scummvm/trunk/engines/sci/engine/kernel_tables.h
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel_tables.h 2010-09-03 22:51:27 UTC (rev 52511)
+++ scummvm/trunk/engines/sci/engine/kernel_tables.h 2010-09-04 07:29:27 UTC (rev 52512)
@@ -329,7 +329,7 @@
{ MAP_CALL(DisposeScript), SIG_EVERYWHERE, "i(i*)", NULL, kDisposeScript_workarounds },
{ MAP_CALL(DisposeWindow), SIG_EVERYWHERE, "i(i)", NULL, NULL },
{ MAP_CALL(DoAudio), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop
- { MAP_CALL(DoAvoider), SIG_EVERYWHERE, "o", NULL, NULL },
+ { MAP_CALL(DoAvoider), SIG_EVERYWHERE, "o(i)", NULL, NULL },
{ MAP_CALL(DoBresen), SIG_EVERYWHERE, "o", NULL, NULL },
{ MAP_CALL(DoSound), SIG_EVERYWHERE, "i(.*)", kDoSound_subops, NULL },
{ MAP_CALL(DoSync), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop
Modified: scummvm/trunk/engines/sci/engine/kmovement.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kmovement.cpp 2010-09-03 22:51:27 UTC (rev 52511)
+++ scummvm/trunk/engines/sci/engine/kmovement.cpp 2010-09-04 07:29:27 UTC (rev 52512)
@@ -401,6 +401,120 @@
reg_t kDoAvoider(EngineState *s, int argc, reg_t *argv) {
SegManager *segMan = s->_segMan;
reg_t avoider = argv[0];
+ int16 timesStep = argc > 1 ? argv[1].toUint16() : 1;
+
+ if (!s->_segMan->isHeapObject(avoider)) {
+ error("DoAvoider() where avoider %04x:%04x is not an object", PRINT_REG(avoider));
+ return SIGNAL_REG;
+ }
+
+ reg_t client = readSelector(segMan, avoider, SELECTOR(client));
+ reg_t mover = readSelector(segMan, client, SELECTOR(mover));
+ if (mover.isNull())
+ return SIGNAL_REG;
+
+ // call mover::doit
+ invokeSelector(s, mover, SELECTOR(doit), argc, argv);
+
+ // Read mover again
+ mover = readSelector(segMan, client, SELECTOR(mover));
+ if (mover.isNull())
+ return SIGNAL_REG;
+
+ int16 clientX = readSelectorValue(segMan, client, SELECTOR(x));
+ int16 clientY = readSelectorValue(segMan, client, SELECTOR(y));
+ int16 moverX = readSelectorValue(segMan, mover, SELECTOR(x));
+ int16 moverY = readSelectorValue(segMan, mover, SELECTOR(y));
+ int16 avoiderHeading = readSelectorValue(segMan, avoider, SELECTOR(heading));
+
+ // call client::isBlocked
+ invokeSelector(s, client, SELECTOR(isBlocked), argc, argv);
+
+ if (s->r_acc.isNull()) {
+ // not blocked
+ if (avoiderHeading == -1)
+ return SIGNAL_REG;
+ avoiderHeading = -1;
+
+ // TODO: reverse this
+ uint16 angle = getAngle(moverX - clientX, moverY - clientY);
+
+ reg_t clientLooper = readSelector(segMan, client, SELECTOR(looper));
+ if (clientLooper.isNull()) {
+ kDirLoopWorker(client, angle, s, argc, argv);
+ } else {
+ // call looper::doit
+ reg_t params[2] = { make_reg(0, angle), client };
+ invokeSelector(s, clientLooper, SELECTOR(doit), argc, argv, 2, params);
+ }
+ s->r_acc = SIGNAL_REG;
+
+ } else {
+ // is blocked
+ if (avoiderHeading == -1)
+ avoiderHeading = g_sci->getRNG().getRandomBit() ? 45 : -45;
+ int16 clientHeading = readSelectorValue(segMan, client, SELECTOR(heading));
+ clientHeading = (clientHeading / 45) * 45;
+
+ int16 clientXstep = readSelectorValue(segMan, client, SELECTOR(xStep)) * timesStep;
+ int16 clientYstep = readSelectorValue(segMan, client, SELECTOR(yStep)) * timesStep;
+ int16 newHeading = clientHeading;
+
+ while (1) {
+ int16 newX = clientX;
+ int16 newY = clientY;
+ switch (newHeading) {
+ case 45:
+ case 90:
+ case 135:
+ newX += clientXstep;
+ break;
+ case 225:
+ case 270:
+ case 315:
+ newX -= clientXstep;
+ }
+
+ switch (newHeading) {
+ case 0:
+ case 45:
+ case 315:
+ newY -= clientYstep;
+ break;
+ case 135:
+ case 180:
+ case 225:
+ newY += clientYstep;
+ }
+ writeSelectorValue(segMan, client, SELECTOR(x), newX);
+ writeSelectorValue(segMan, client, SELECTOR(y), newY);
+
+ // call client::canBeHere
+ invokeSelector(s, client, SELECTOR(canBeHere), argc, argv);
+
+ if (!s->r_acc.isNull()) {
+ s->r_acc = make_reg(0, newHeading);
+ break; // break out
+ }
+
+ clientHeading += avoiderHeading;
+ if (newHeading >= 360)
+ newHeading -= 360;
+ if (newHeading < 0)
+ newHeading += 360;
+ if (newHeading == clientHeading) {
+ // tried everything
+ writeSelectorValue(segMan, client, SELECTOR(x), clientX);
+ writeSelectorValue(segMan, client, SELECTOR(y), clientY);
+ s->r_acc = SIGNAL_REG;
+ break; // break out
+ }
+ }
+ }
+ writeSelectorValue(segMan, avoider, SELECTOR(heading), avoiderHeading);
+ return s->r_acc;
+
+#if 0
reg_t client, looper, mover;
int angle;
int dx, dy;
@@ -508,6 +622,7 @@
}
return s->r_acc;
+#endif
}
} // End of namespace Sci
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list