diff options
author | Filippos Karapetis | 2009-10-09 17:41:59 +0000 |
---|---|---|
committer | Filippos Karapetis | 2009-10-09 17:41:59 +0000 |
commit | 14f8d50a62f400bd79459c202d14938c37285ac6 (patch) | |
tree | 4097f6045b6ffc53130947b211a09c62551ea643 /engines | |
parent | a38d6451ba2c9ee192747bb4e9d28269798f74b1 (diff) | |
download | scummvm-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')
-rw-r--r-- | engines/sci/engine/kmovement.cpp | 54 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 37 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 18 | ||||
-rw-r--r-- | engines/sci/sci.h | 6 |
4 files changed, 61 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; diff --git a/engines/sci/sci.h b/engines/sci/sci.h index ffcef329f1..915782aabc 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -95,6 +95,12 @@ enum SciVersion { SCI_VERSION_3 // LSL7, RAMA, Lighthouse }; +enum MoveCountType { + kMoveCountUninitialized, + kIgnoreMoveCount, + kIncrementMoveCount +}; + class SciEngine : public Engine { friend class Console; public: |