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
This commit is contained in:
parent
a38d6451ba
commit
14f8d50a62
4 changed files with 61 additions and 54 deletions
|
@ -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_X (((axis == _K_BRESEN_AXIS_X)&&bi1) || dx)
|
||||||
#define MOVING_ON_Y (((axis == _K_BRESEN_AXIS_Y)&&bi1) || dy)
|
#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) {
|
reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
|
||||||
SegManager *segMan = s->_segMan;
|
SegManager *segMan = s->_segMan;
|
||||||
reg_t mover = argv[0];
|
reg_t mover = argv[0];
|
||||||
|
@ -298,9 +249,6 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
|
||||||
if (getSciVersion() > SCI_VERSION_01)
|
if (getSciVersion() > SCI_VERSION_01)
|
||||||
signal &= ~_K_VIEW_SIG_FLAG_HIT_OBSTACLE;
|
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
|
PUT_SEL32(client, signal, make_reg(0, signal)); // This is a NOP for SCI0
|
||||||
oldx = x;
|
oldx = x;
|
||||||
oldy = y;
|
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);
|
//printf("movecnt %d, move speed %d\n", movcnt, max_movcnt);
|
||||||
|
|
||||||
if (handle_movecnt) {
|
if (s->handleMoveCount()) {
|
||||||
if (max_movcnt > movcnt) {
|
if (max_movcnt > movcnt) {
|
||||||
++movcnt;
|
++movcnt;
|
||||||
PUT_SEL32V(mover, b_movCnt, movcnt); // Needed for HQ1/Ogre?
|
PUT_SEL32V(mover, b_movCnt, movcnt); // Needed for HQ1/Ogre?
|
||||||
|
|
|
@ -111,6 +111,7 @@ EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc,
|
||||||
_doSoundType = SCI_VERSION_AUTODETECT;
|
_doSoundType = SCI_VERSION_AUTODETECT;
|
||||||
_lofsType = SCI_VERSION_AUTODETECT;
|
_lofsType = SCI_VERSION_AUTODETECT;
|
||||||
_gfxFunctionsType = SCI_VERSION_AUTODETECT;
|
_gfxFunctionsType = SCI_VERSION_AUTODETECT;
|
||||||
|
_moveCountType = kMoveCountUninitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
EngineState::~EngineState() {
|
EngineState::~EngineState() {
|
||||||
|
@ -633,4 +634,40 @@ SciVersion EngineState::detectGfxFunctionsType() {
|
||||||
return _gfxFunctionsType;
|
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
|
} // End of namespace Sci
|
||||||
|
|
|
@ -288,12 +288,27 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Autodetects the graphics functions used
|
* 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();
|
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; }
|
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: */
|
/* Debugger data: */
|
||||||
Breakpoint *bp_list; /**< List of breakpoints */
|
Breakpoint *bp_list; /**< List of breakpoints */
|
||||||
int have_bp; /**< Bit mask specifying which types of breakpoints are used in bp_list */
|
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;
|
Common::String getLanguageString(const char *str, kLanguage lang) const;
|
||||||
private:
|
private:
|
||||||
SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType;
|
SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType;
|
||||||
|
MoveCountType _moveCountType;
|
||||||
kLanguage charToLanguage(const char c) const;
|
kLanguage charToLanguage(const char c) const;
|
||||||
int methodChecksum(reg_t objAddress, Selector sel, int offset, uint size) const;
|
int methodChecksum(reg_t objAddress, Selector sel, int offset, uint size) const;
|
||||||
uint16 firstRetOffset(reg_t objectAddress) const;
|
uint16 firstRetOffset(reg_t objectAddress) const;
|
||||||
|
|
|
@ -95,6 +95,12 @@ enum SciVersion {
|
||||||
SCI_VERSION_3 // LSL7, RAMA, Lighthouse
|
SCI_VERSION_3 // LSL7, RAMA, Lighthouse
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MoveCountType {
|
||||||
|
kMoveCountUninitialized,
|
||||||
|
kIgnoreMoveCount,
|
||||||
|
kIncrementMoveCount
|
||||||
|
};
|
||||||
|
|
||||||
class SciEngine : public Engine {
|
class SciEngine : public Engine {
|
||||||
friend class Console;
|
friend class Console;
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue