aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorFilippos Karapetis2009-10-09 17:41:59 +0000
committerFilippos Karapetis2009-10-09 17:41:59 +0000
commit14f8d50a62f400bd79459c202d14938c37285ac6 (patch)
tree4097f6045b6ffc53130947b211a09c62551ea643 /engines/sci/engine
parenta38d6451ba2c9ee192747bb4e9d28269798f74b1 (diff)
downloadscummvm-rg350-14f8d50a62f400bd79459c202d14938c37285ac6.tar.gz
scummvm-rg350-14f8d50a62f400bd79459c202d14938c37285ac6.tar.bz2
scummvm-rg350-14f8d50a62f400bd79459c202d14938c37285ac6.zip
Moved actor movement detection in state.cpp, together with the other detections and rewrote it to work in a similar fashion to the other detections
svn-id: r44836
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/kmovement.cpp54
-rw-r--r--engines/sci/engine/state.cpp37
-rw-r--r--engines/sci/engine/state.h18
3 files changed, 55 insertions, 54 deletions
diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp
index dfdb02dd22..e71f4501a5 100644
--- a/engines/sci/engine/kmovement.cpp
+++ b/engines/sci/engine/kmovement.cpp
@@ -234,55 +234,6 @@ reg_t kInitBresen(EngineState *s, int argc, reg_t *argv) {
#define MOVING_ON_X (((axis == _K_BRESEN_AXIS_X)&&bi1) || dx)
#define MOVING_ON_Y (((axis == _K_BRESEN_AXIS_Y)&&bi1) || dy)
-enum Movecnt {
- IGNORE_MOVECNT,
- INCREMENT_MOVECNT,
- UNINITIALIZED
-};
-
-static Movecnt handle_movecnt = UNINITIALIZED; // FIXME: Avoid non-const global vars
-
-static int checksum_bytes(byte *data, int size) {
- int result = 0;
- int i;
-
- for (i = 0; i < size; i++) {
- result += *data;
- data++;
- }
-
- return result;
-}
-
-static void bresenham_autodetect(EngineState *s) {
- reg_t motionClass = s->_segMan->findObjectByName("Motion");
-
- if (!motionClass.isNull()) {
- Object *obj = s->_segMan->getObject(motionClass);
- reg_t fptr;
- byte *buf;
-
- if (obj == NULL) {
- warning("bresenham_autodetect failed");
- handle_movecnt = INCREMENT_MOVECNT; // Most games do this, so best guess
- return;
- }
-
- if (lookup_selector(s->_segMan, motionClass, s->_kernel->_selectorCache.doit, NULL, &fptr) != kSelectorMethod) {
- warning("bresenham_autodetect failed");
- handle_movecnt = INCREMENT_MOVECNT; // Most games do this, so best guess
- return;
- }
-
- buf = s->_segMan->getScript(fptr.segment)->_buf + fptr.offset;
- handle_movecnt = (getSciVersion() <= SCI_VERSION_01 || checksum_bytes(buf, 8) == 0x216) ? INCREMENT_MOVECNT : IGNORE_MOVECNT;
- printf("b-moveCnt action based on checksum: %s\n", handle_movecnt == IGNORE_MOVECNT ? "ignore" : "increment");
- } else {
- warning("bresenham_autodetect failed");
- handle_movecnt = INCREMENT_MOVECNT; // Most games do this, so best guess
- }
-}
-
reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
SegManager *segMan = s->_segMan;
reg_t mover = argv[0];
@@ -298,9 +249,6 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
if (getSciVersion() > SCI_VERSION_01)
signal &= ~_K_VIEW_SIG_FLAG_HIT_OBSTACLE;
- if (handle_movecnt == UNINITIALIZED)
- bresenham_autodetect(s);
-
PUT_SEL32(client, signal, make_reg(0, signal)); // This is a NOP for SCI0
oldx = x;
oldy = y;
@@ -317,7 +265,7 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
//printf("movecnt %d, move speed %d\n", movcnt, max_movcnt);
- if (handle_movecnt) {
+ if (s->handleMoveCount()) {
if (max_movcnt > movcnt) {
++movcnt;
PUT_SEL32V(mover, b_movCnt, movcnt); // Needed for HQ1/Ogre?
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 85cf099a2c..13930d8a27 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -111,6 +111,7 @@ EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc,
_doSoundType = SCI_VERSION_AUTODETECT;
_lofsType = SCI_VERSION_AUTODETECT;
_gfxFunctionsType = SCI_VERSION_AUTODETECT;
+ _moveCountType = kMoveCountUninitialized;
}
EngineState::~EngineState() {
@@ -633,4 +634,40 @@ SciVersion EngineState::detectGfxFunctionsType() {
return _gfxFunctionsType;
}
+MoveCountType EngineState::detectMoveCountType() {
+ if (_moveCountType == kMoveCountUninitialized) {
+ // SCI0/SCI01 games always increment move count
+ if (getSciVersion() <= SCI_VERSION_01) {
+ _moveCountType = kIncrementMoveCount;
+ return _moveCountType;
+ }
+
+ reg_t motionClass = _segMan->findObjectByName("Motion");
+ bool found = false;
+
+ if (!motionClass.isNull()) {
+ Object *obj = _segMan->getObject(motionClass);
+ reg_t fptr;
+
+ if (obj && lookup_selector(_segMan, motionClass, _kernel->_selectorCache.doit, NULL, &fptr) == kSelectorMethod) {
+ byte *buf = _segMan->getScript(fptr.segment)->_buf + fptr.offset;
+ int checksum = 0;
+ for (int i = 0; i < 8; i++)
+ checksum += *(buf++);
+ _moveCountType = (checksum == 0x216) ? kIncrementMoveCount : kIgnoreMoveCount;
+ found = true;
+ }
+ }
+
+ if (!found) {
+ warning("Move count autodetection failed");
+ _moveCountType = kIncrementMoveCount; // Most games do this, so best guess
+ }
+
+ debugC(1, kDebugLevelVM, "Detected move count handling: %s", (_moveCountType == kIncrementMoveCount) ? "increment" : "ignore");
+ }
+
+ return _moveCountType;
+}
+
} // End of namespace Sci
diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h
index fdce259ca8..7fae7e2316 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -288,12 +288,27 @@ public:
/**
* Autodetects the graphics functions used
- * @return Lofs type, SCI_VERSION_0_EARLY / SCI_VERSION_0_LATE
+ * @return Graphics functions type, SCI_VERSION_0_EARLY / SCI_VERSION_0_LATE
*/
SciVersion detectGfxFunctionsType();
+ /**
+ * Applies to all versions before 0.000.502
+ * Old SCI versions used to interpret the third DrawPic() parameter inversely,
+ * with the opposite default value (obviously).
+ * Also, they used 15 priority zones from 42 to 200 instead of 14 priority
+ * zones from 42 to 190.
+ */
bool usesOldGfxFunctions() { return detectGfxFunctionsType() == SCI_VERSION_0_EARLY; }
+ /**
+ * Autodetects the Bresenham routine used in the actor movement functions
+ * @return Move count type, kIncrementMoveCnt / kIgnoreMoveCnt
+ */
+ MoveCountType detectMoveCountType();
+
+ bool handleMoveCount() { return detectMoveCountType() == kIncrementMoveCount; }
+
/* Debugger data: */
Breakpoint *bp_list; /**< List of breakpoints */
int have_bp; /**< Bit mask specifying which types of breakpoints are used in bp_list */
@@ -316,6 +331,7 @@ public:
Common::String getLanguageString(const char *str, kLanguage lang) const;
private:
SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType;
+ MoveCountType _moveCountType;
kLanguage charToLanguage(const char c) const;
int methodChecksum(reg_t objAddress, Selector sel, int offset, uint size) const;
uint16 firstRetOffset(reg_t objectAddress) const;