Conditions seem to be reversed, frankly.
[scummvm-innocent.git] / engines / innocent / actor.cpp
blobbdbe3554b0fb2e1606d7bc5775c1b248cc3643c7
1 #include "innocent/actor.h"
3 #include "common/rect.h"
5 #include "innocent/innocent.h"
6 #include "innocent/logic.h"
7 #include "innocent/util.h"
9 namespace Innocent {
12 Actor::Actor(const CodePointer &code) : Animation(code, Common::Point()) {
13 byte *header = code.code();
14 _base = header - code.offset();
15 snprintf(_debugInfo, 50, "actor at %s", +code);
16 readHeader(header);
17 _dir63 = 0;
18 _frame = 0;
19 _room = 0xffff;
20 _debug = false;
22 Engine::instance().logic()->addAnimation(this);
24 init_opcodes<37>();
27 void Actor::setAnimation(const CodePointer &anim) {
28 debugC(3, kDebugLevelScript, "setting animation code of %s to %s", _debugInfo, +anim);
29 _base = anim.code();
30 _baseOffset = anim.offset();
31 _offset = 0;
32 _debugInvalid = false;
35 void Actor::whenYouHideUpCall(const CodePointer &code) {
36 _callBacks.push(code);
39 bool Actor::isVisible() const {
40 return _room == Log.currentRoom();
43 void Actor::setRoom(uint16 r, uint16 frame, uint16 next_frame) {
44 _room = r;
45 _frame = frame;
46 unless (next_frame)
47 next_frame = frame;
48 _nextFrame = next_frame;
49 callBacks();
52 Animation::Status Actor::tick() {
53 if (isVisible()) {
54 Animation::Status s;
55 if (_debug) gDebugLevel += 3;
56 s = Animation::tick();
57 if (_debug) gDebugLevel -= 3;
58 return s;
59 } else
60 return kOk;
63 void Actor::toggleDebug() {
64 _debug = !_debug;
67 void Actor::readHeader(const byte *code) {
68 _interval = code[kOffsetInterval];
69 _ticksLeft = READ_LE_UINT16(code + kOffsetTicksLeft);
70 _zIndex = 0;
71 _position = Common::Point(READ_LE_UINT16(code + kOffsetLeft), READ_LE_UINT16(code + kOffsetTop));
72 uint16 baseOff = READ_LE_UINT16(code + kOffsetCode);
73 _base += baseOff;
74 _offset = READ_LE_UINT16(code + kOffsetOffset);
75 uint16 sprite = READ_LE_UINT16(code + kOffsetMainSprite);
76 _room = READ_LE_UINT16(code + kOffsetRoom);
78 debugC(3, kDebugLevelFiles, "loading %s: interv %d ticks %d z%d pos%d:%d code %d offset %d sprite %d room %d", _debugInfo, _interval, _ticksLeft, _zIndex, _position.x, _position.y, baseOff, _offset, sprite, _room);
80 if (sprite != 0xffff)
81 setMainSprite(sprite);
84 void Actor::callBacks() {
85 if (!isVisible())
86 while (!_callBacks.empty())
87 _callBacks.pop().run();
90 template <int opcode>
91 Animation::Status Actor::opcodeHandler(){
92 return Animation::opcodeHandler<opcode>();
95 template<int N>
96 void Actor::init_opcodes() {
97 _handlers[N] = &Innocent::Actor::opcodeHandler<N>;
98 init_opcodes<N-1>();
101 template<>
102 void Actor::init_opcodes<-1>() {}
104 Animation::Status Actor::op(byte opcode) {
105 return (this->*_handlers[opcode])();
108 #define OPCODE(n) template<> Animation::Status Actor::opcodeHandler<n>()
110 OPCODE(0x14) {
111 uint16 off = shift();
113 debugC(3, kDebugLevelAnimation, "actor opcode 0x14: jump to 0x%04x if I'm speaking STUB", off);
115 // also, some check for non-protagonists
117 return kOk;
120 OPCODE(0x15) {
121 debugC(1, kDebugLevelAnimation, "actor opcode 0x15: look at cursor direction if its mode is 'See' STUB");
123 return kOk;
126 OPCODE(0x16) {
127 byte val = embeddedByte();
128 uint16 off = shift();
130 debugC(1, kDebugLevelAnimation, "actor opcode 0x16: if look direction is %d then jump to 0x%04x STUB", val, off);
132 return kOk;
135 OPCODE(0x17) {
136 byte val = embeddedByte();
137 uint16 off = shift();
139 debugC(3, kDebugLevelAnimation, "actor opcode 0x17: if facing (currently %d) is %d then change code to 0x%04x", _dir63, val, off);
141 if (val == _dir63) {
142 _base = _base - _baseOffset + off;
143 _baseOffset = off;
144 _offset = 0;
147 return kOk;
150 OPCODE(0x18) {
151 uint16 val = shift();
153 debugC(1, kDebugLevelAnimation, "actor opcode 0x18: set next animator to %d STUB", val);
155 return kOk;
158 OPCODE(0x23) {
159 byte dir = embeddedByte();
161 debugC(3, kDebugLevelAnimation, "actor opcode 0x23: face %d", dir);
163 _dir63 = dir;
165 return kOk;
168 OPCODE(0x24) {
169 byte dir = embeddedByte();
171 debugC(1, kDebugLevelAnimation, "actor opcode 0x23: set dir65 to %d STUB", dir);
173 return kOk;
176 } // end of namespace