1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "kyra/engine/kyra_lok.h"
24 #include "kyra/graphics/screen.h"
25 #include "kyra/graphics/animator_lok.h"
26 #include "kyra/engine/sprites.h"
27
28 namespace Kyra {
29
Animator_LoK(KyraEngine_LoK * vm,OSystem * system)30 Animator_LoK::Animator_LoK(KyraEngine_LoK *vm, OSystem *system) {
31 _vm = vm;
32 _screen = vm->screen();
33 _initOk = false;
34 _system = system;
35 _screenObjects = _actors = _items = _sprites = _objectQueue = 0;
36 _noDrawShapesFlag = 0;
37
38 _actorBkgBackUp[0] = new uint8[_screen->getRectSize(8, 69)];
39 memset(_actorBkgBackUp[0], 0, _screen->getRectSize(8, 69));
40 _actorBkgBackUp[1] = new uint8[_screen->getRectSize(8, 69)];
41 memset(_actorBkgBackUp[1], 0, _screen->getRectSize(8, 69));
42 }
43
~Animator_LoK()44 Animator_LoK::~Animator_LoK() {
45 close();
46 delete[] _actorBkgBackUp[0];
47 delete[] _actorBkgBackUp[1];
48 }
49
init(int actors_,int items_,int sprites_)50 void Animator_LoK::init(int actors_, int items_, int sprites_) {
51 _screenObjects = new AnimObject[actors_ + items_ + sprites_];
52 assert(_screenObjects);
53 memset(_screenObjects, 0, sizeof(AnimObject) * (actors_ + items_ + sprites_));
54 _actors = _screenObjects;
55 _sprites = &_screenObjects[actors_];
56 _items = &_screenObjects[actors_ + items_];
57 _brandonDrawFrame = 113;
58
59 _initOk = true;
60 }
61
close()62 void Animator_LoK::close() {
63 if (_initOk) {
64 _initOk = false;
65 delete[] _screenObjects;
66 _screenObjects = _actors = _items = _sprites = _objectQueue = 0;
67 }
68 }
69
initAnimStateList()70 void Animator_LoK::initAnimStateList() {
71 AnimObject *animStates = _screenObjects;
72 animStates[0].index = 0;
73 animStates[0].active = 1;
74 animStates[0].flags = 0x800;
75 animStates[0].background = _actorBkgBackUp[0];
76 animStates[0].rectSize = _screen->getRectSize(4, 48);
77 animStates[0].width = 4;
78 animStates[0].height = 48;
79 animStates[0].width2 = 4;
80 animStates[0].height2 = 3;
81
82 for (int i = 1; i <= 4; ++i) {
83 animStates[i].index = i;
84 animStates[i].active = 0;
85 animStates[i].flags = 0x800;
86 animStates[i].background = _actorBkgBackUp[1];
87 animStates[i].rectSize = _screen->getRectSize(4, 64);
88 animStates[i].width = 4;
89 animStates[i].height = 48;
90 animStates[i].width2 = 4;
91 animStates[i].height2 = 3;
92 }
93
94 for (int i = 5; i < 16; ++i) {
95 animStates[i].index = i;
96 animStates[i].active = 0;
97 animStates[i].flags = 0;
98 }
99
100 for (int i = 16; i < 28; ++i) {
101 animStates[i].index = i;
102 animStates[i].flags = 0;
103 animStates[i].background = _vm->_shapes[345 + i];
104 animStates[i].rectSize = _screen->getRectSize(3, 24);
105 animStates[i].width = 3;
106 animStates[i].height = 16;
107 animStates[i].width2 = 0;
108 animStates[i].height2 = 0;
109 }
110 }
111
preserveAllBackgrounds()112 void Animator_LoK::preserveAllBackgrounds() {
113 uint8 curPage = _screen->_curPage;
114 _screen->_curPage = 2;
115
116 AnimObject *curObject = _objectQueue;
117 while (curObject) {
118 if (curObject->active && !curObject->disable) {
119 preserveOrRestoreBackground(curObject, false);
120 curObject->bkgdChangeFlag = 0;
121 }
122 curObject = curObject->nextAnimObject;
123 }
124 _screen->_curPage = curPage;
125 }
126
flagAllObjectsForBkgdChange()127 void Animator_LoK::flagAllObjectsForBkgdChange() {
128 AnimObject *curObject = _objectQueue;
129 while (curObject) {
130 curObject->bkgdChangeFlag = 1;
131 curObject = curObject->nextAnimObject;
132 }
133 }
134
flagAllObjectsForRefresh()135 void Animator_LoK::flagAllObjectsForRefresh() {
136 AnimObject *curObject = _objectQueue;
137 while (curObject) {
138 curObject->refreshFlag = 1;
139 curObject = curObject->nextAnimObject;
140 }
141 }
142
restoreAllObjectBackgrounds()143 void Animator_LoK::restoreAllObjectBackgrounds() {
144 AnimObject *curObject = _objectQueue;
145 _screen->_curPage = 2;
146
147 while (curObject) {
148 if (curObject->active && !curObject->disable) {
149 preserveOrRestoreBackground(curObject, true);
150 curObject->x2 = curObject->x1;
151 curObject->y2 = curObject->y1;
152 }
153 curObject = curObject->nextAnimObject;
154 }
155
156 _screen->_curPage = 0;
157 }
158
preserveAnyChangedBackgrounds()159 void Animator_LoK::preserveAnyChangedBackgrounds() {
160 AnimObject *curObject = _objectQueue;
161 _screen->_curPage = 2;
162
163 while (curObject) {
164 if (curObject->active && !curObject->disable && curObject->bkgdChangeFlag) {
165 preserveOrRestoreBackground(curObject, false);
166 curObject->bkgdChangeFlag = 0;
167 }
168 curObject = curObject->nextAnimObject;
169 }
170
171 _screen->_curPage = 0;
172 }
173
preserveOrRestoreBackground(AnimObject * obj,bool restore)174 void Animator_LoK::preserveOrRestoreBackground(AnimObject *obj, bool restore) {
175 int x = 0, y = 0, width = obj->width, height = obj->height;
176
177 if (restore) {
178 x = obj->x2 >> 3;
179 y = obj->y2;
180 } else {
181 x = obj->x1 >> 3;
182 y = obj->y1;
183 }
184
185 if (x < 0)
186 x = 0;
187 if (y < 0)
188 y = 0;
189
190 int temp;
191
192 temp = x + width;
193 if (temp >= 39)
194 x = 39 - width;
195 temp = y + height;
196 if (temp >= 136)
197 y = 136 - height;
198
199 if (restore)
200 _screen->copyBlockToPage(_screen->_curPage, x << 3, y, width << 3, height, obj->background);
201 else
202 _screen->copyRegionToBuffer(_screen->_curPage, x << 3, y, width << 3, height, obj->background);
203 }
204
prepDrawAllObjects()205 void Animator_LoK::prepDrawAllObjects() {
206 AnimObject *curObject = _objectQueue;
207 int drawPage = 2;
208 int flagUnk1 = 0, flagUnk2 = 0, flagUnk3 = 0;
209 if (_noDrawShapesFlag)
210 return;
211 if (_vm->_brandonStatusBit & 0x20)
212 flagUnk1 = 0x200;
213 if (_vm->_brandonStatusBit & 0x40)
214 flagUnk2 = 0x4000;
215
216 while (curObject) {
217 if (curObject->active) {
218 int xpos = curObject->x1;
219 int ypos = curObject->y1;
220
221 int drawLayer = 0;
222 if (!(curObject->flags & 0x800))
223 drawLayer = 7;
224 else if (curObject->disable)
225 drawLayer = 0;
226 else
227 drawLayer = _vm->_sprites->getDrawLayer(curObject->drawY);
228
229 // talking head functionallity
230 if (_vm->_talkingCharNum != -1 && (_vm->_currentCharacter->currentAnimFrame != 88 || curObject->index != 0)) {
231 const int16 baseAnimFrameTable1[] = { 0x11, 0x35, 0x59, 0x00, 0x00, 0x00 };
232 const int16 baseAnimFrameTable2[] = { 0x15, 0x39, 0x5D, 0x00, 0x00, 0x00 };
233 const int8 xOffsetTable1[] = { 2, 4, 0, 5, 2, 0, 0, 0 };
234 const int8 xOffsetTable2[] = { 6, 4, 8, 3, 6, 0, 0, 0 };
235 const int8 yOffsetTable1[] = { 0, 8, 1, 1, 0, 0, 0, 0 };
236 const int8 yOffsetTable2[] = { 0, 8, 1, 1, 0, 0, 0, 0 };
237 if (curObject->index == 0 || curObject->index <= 4) {
238 int shapesIndex = 0;
239 if (curObject->index == _vm->_charSayUnk3) {
240 shapesIndex = _vm->_currHeadShape + baseAnimFrameTable1[curObject->index];
241 } else {
242 shapesIndex = baseAnimFrameTable2[curObject->index];
243 int temp2 = 0;
244 if (curObject->index == 2) {
245 if (_vm->_characterList[2].sceneId == 77 || _vm->_characterList[2].sceneId == 86)
246 temp2 = 1;
247 else
248 temp2 = 0;
249 } else {
250 temp2 = 1;
251 }
252
253 if (!temp2)
254 shapesIndex = -1;
255 }
256
257 xpos = curObject->x1;
258 ypos = curObject->y1;
259
260 int tempX = 0, tempY = 0;
261 if (curObject->flags & 0x1) {
262 tempX = (xOffsetTable1[curObject->index] * _brandonScaleX) >> 8;
263 tempY = yOffsetTable1[curObject->index];
264 } else {
265 tempX = (xOffsetTable2[curObject->index] * _brandonScaleX) >> 8;
266 tempY = yOffsetTable2[curObject->index];
267 }
268 tempY = (tempY * _brandonScaleY) >> 8;
269 xpos += tempX;
270 ypos += tempY;
271
272 if (_vm->_scaleMode && _brandonScaleX != 256)
273 ++xpos;
274
275 if (curObject->index == 0 && shapesIndex != -1) {
276 if (!(_vm->_brandonStatusBit & 2)) {
277 flagUnk3 = 0x100;
278 if ((flagUnk1 & 0x200) || (flagUnk2 & 0x4000))
279 flagUnk3 = 0;
280
281 int tempFlags = 0;
282 if (flagUnk3 & 0x100) {
283 tempFlags = curObject->flags & 1;
284 tempFlags |= 0x800 | flagUnk1 | 0x100;
285 }
286
287 if (!(flagUnk3 & 0x100) && (flagUnk2 & 0x4000)) {
288 tempFlags = curObject->flags & 1;
289 tempFlags |= 0x900 | flagUnk1 | 0x4000;
290 _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY);
291 } else {
292 if (!(flagUnk2 & 0x4000)) {
293 tempFlags = curObject->flags & 1;
294 tempFlags |= 0x900 | flagUnk1;
295 }
296
297 _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY);
298 }
299 }
300 } else {
301 if (shapesIndex != -1) {
302 int tempFlags = 0;
303 if (curObject->flags & 1)
304 tempFlags = 1;
305 _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 0x800, drawLayer);
306 }
307 }
308 }
309 }
310
311 xpos = curObject->x1;
312 ypos = curObject->y1;
313
314 curObject->flags |= 0x800;
315 if (curObject->index == 0) {
316 flagUnk3 = 0x100;
317
318 if (flagUnk1 & 0x200 || flagUnk2 & 0x4000)
319 flagUnk3 = 0;
320
321 if (_vm->_brandonStatusBit & 2)
322 curObject->flags &= 0xFFFFFFFE;
323
324 if (!_vm->_scaleMode) {
325 if (flagUnk3 & 0x100)
326 _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x100, (uint8 *)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer);
327 else if (flagUnk2 & 0x4000)
328 _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4000, int(_vm->_brandonInvFlag), drawLayer);
329 else
330 _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1, drawLayer);
331 } else {
332 if (flagUnk3 & 0x100)
333 _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8 *)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY);
334 else if (flagUnk2 & 0x4000)
335 _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4004, int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY);
336 else
337 _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4, drawLayer, _brandonScaleX, _brandonScaleY);
338 }
339 } else {
340 if (curObject->index >= 16 && curObject->index <= 27)
341 _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | 4, drawLayer, (int)_vm->_scaleTable[curObject->drawY], (int)_vm->_scaleTable[curObject->drawY]);
342 else
343 _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags, drawLayer);
344 }
345 }
346 curObject = curObject->nextAnimObject;
347 }
348 }
349
copyChangedObjectsForward(int refreshFlag)350 void Animator_LoK::copyChangedObjectsForward(int refreshFlag) {
351 for (AnimObject *curObject = _objectQueue; curObject; curObject = curObject->nextAnimObject) {
352 if (curObject->active) {
353 if (curObject->refreshFlag || refreshFlag) {
354 int xpos = 0, ypos = 0, width = 0, height = 0;
355 xpos = (curObject->x1 >> 3) - (curObject->width2 >> 3) - 1;
356 ypos = curObject->y1 - curObject->height2;
357 width = curObject->width + (curObject->width2 >> 3) + 2;
358 height = curObject->height + curObject->height2 * 2;
359
360 if (xpos < 1)
361 xpos = 1;
362 else if (xpos > 39)
363 continue;
364
365 if (xpos + width > 39)
366 width = 39 - xpos;
367
368 if (ypos < 8)
369 ypos = 8;
370 else if (ypos > 136)
371 continue;
372
373 if (ypos + height > 136)
374 height = 136 - ypos;
375
376 _screen->copyRegion(xpos << 3, ypos, xpos << 3, ypos, width << 3, height, 2, 0);
377 curObject->refreshFlag = 0;
378 }
379 }
380 }
381
382 _screen->updateScreen();
383 }
384
updateAllObjectShapes()385 void Animator_LoK::updateAllObjectShapes() {
386 restoreAllObjectBackgrounds();
387 preserveAnyChangedBackgrounds();
388 prepDrawAllObjects();
389 copyChangedObjectsForward(0);
390 }
391
animRemoveGameItem(int index)392 void Animator_LoK::animRemoveGameItem(int index) {
393 restoreAllObjectBackgrounds();
394
395 AnimObject *animObj = &_items[index];
396 animObj->sceneAnimPtr = 0;
397 animObj->animFrameNumber = -1;
398 animObj->refreshFlag = 1;
399 animObj->bkgdChangeFlag = 1;
400 updateAllObjectShapes();
401 animObj->active = 0;
402
403 objectRemoveQueue(_objectQueue, animObj);
404 }
405
animAddGameItem(int index,uint16 sceneId)406 void Animator_LoK::animAddGameItem(int index, uint16 sceneId) {
407 restoreAllObjectBackgrounds();
408 assert(sceneId < _vm->_roomTableSize);
409 Room *currentRoom = &_vm->_roomTable[sceneId];
410 AnimObject *animObj = &_items[index];
411 animObj->active = 1;
412 animObj->refreshFlag = 1;
413 animObj->bkgdChangeFlag = 1;
414 animObj->drawY = currentRoom->itemsYPos[index];
415 animObj->sceneAnimPtr = _vm->_shapes[216 + currentRoom->itemsTable[index]];
416 animObj->animFrameNumber = -1;
417 animObj->x1 = currentRoom->itemsXPos[index];
418 animObj->y1 = currentRoom->itemsYPos[index];
419 animObj->x1 -= fetchAnimWidth(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]) >> 1;
420 animObj->y1 -= fetchAnimHeight(animObj->sceneAnimPtr, _vm->_scaleTable[animObj->drawY]);
421 animObj->x2 = animObj->x1;
422 animObj->y2 = animObj->y1;
423 animObj->width2 = 0;
424 animObj->height2 = 0;
425 _objectQueue = objectQueue(_objectQueue, animObj);
426 preserveAnyChangedBackgrounds();
427 animObj->refreshFlag = 1;
428 animObj->bkgdChangeFlag = 1;
429 }
430
animAddNPC(int character)431 void Animator_LoK::animAddNPC(int character) {
432 restoreAllObjectBackgrounds();
433 AnimObject *animObj = &_actors[character];
434 const Character *ch = &_vm->_characterList[character];
435
436 animObj->active = 1;
437 animObj->refreshFlag = 1;
438 animObj->bkgdChangeFlag = 1;
439 animObj->drawY = ch->y1;
440 animObj->sceneAnimPtr = _vm->_shapes[ch->currentAnimFrame];
441 animObj->x1 = animObj->x2 = ch->x1 + _vm->_defaultShapeTable[ch->currentAnimFrame - 7].xOffset;
442 animObj->y1 = animObj->y2 = ch->y1 + _vm->_defaultShapeTable[ch->currentAnimFrame - 7].yOffset;
443
444 if (ch->facing >= 1 && ch->facing <= 3)
445 animObj->flags |= 1;
446 else if (ch->facing >= 5 && ch->facing <= 7)
447 animObj->flags &= 0xFFFFFFFE;
448
449 _objectQueue = objectQueue(_objectQueue, animObj);
450 preserveAnyChangedBackgrounds();
451 animObj->refreshFlag = 1;
452 animObj->bkgdChangeFlag = 1;
453 }
454
objectRemoveQueue(AnimObject * queue,AnimObject * rem)455 Animator_LoK::AnimObject *Animator_LoK::objectRemoveQueue(AnimObject *queue, AnimObject *rem) {
456 AnimObject *cur = queue;
457 AnimObject *prev = queue;
458
459 while (cur != rem && cur) {
460 AnimObject *temp = cur->nextAnimObject;
461 if (!temp)
462 break;
463 prev = cur;
464 cur = temp;
465 }
466
467 if (cur == queue) {
468 if (!cur)
469 return 0;
470 return cur->nextAnimObject;
471 }
472
473 if (!cur->nextAnimObject) {
474 if (cur == rem) {
475 if (!prev)
476 return 0;
477 else
478 prev->nextAnimObject = 0;
479 }
480 } else {
481 if (cur == rem)
482 prev->nextAnimObject = rem->nextAnimObject;
483 }
484
485 return queue;
486 }
487
objectAddHead(AnimObject * queue,AnimObject * head)488 Animator_LoK::AnimObject *Animator_LoK::objectAddHead(AnimObject *queue, AnimObject *head) {
489 head->nextAnimObject = queue;
490 return head;
491 }
492
objectQueue(AnimObject * queue,AnimObject * add)493 Animator_LoK::AnimObject *Animator_LoK::objectQueue(AnimObject *queue, AnimObject *add) {
494 if (!queue || add->drawY <= queue->drawY) {
495 add->nextAnimObject = queue;
496 return add;
497 }
498 AnimObject *cur = queue;
499 AnimObject *prev = queue;
500 while (add->drawY > cur->drawY) {
501 AnimObject *temp = cur->nextAnimObject;
502 if (!temp)
503 break;
504 prev = cur;
505 cur = temp;
506 }
507
508 if (add->drawY <= cur->drawY) {
509 prev->nextAnimObject = add;
510 add->nextAnimObject = cur;
511 } else {
512 cur->nextAnimObject = add;
513 add->nextAnimObject = 0;
514 }
515 return queue;
516 }
517
addObjectToQueue(AnimObject * object)518 void Animator_LoK::addObjectToQueue(AnimObject *object) {
519 if (!_objectQueue)
520 _objectQueue = objectAddHead(0, object);
521 else
522 _objectQueue = objectQueue(_objectQueue, object);
523 }
524
refreshObject(AnimObject * object)525 void Animator_LoK::refreshObject(AnimObject *object) {
526 _objectQueue = objectRemoveQueue(_objectQueue, object);
527 if (_objectQueue)
528 _objectQueue = objectQueue(_objectQueue, object);
529 else
530 _objectQueue = objectAddHead(0, object);
531 }
532
makeBrandonFaceMouse()533 void Animator_LoK::makeBrandonFaceMouse() {
534 Common::Point mouse = _vm->getMousePos();
535 if (mouse.x >= _vm->_currentCharacter->x1)
536 _vm->_currentCharacter->facing = 3;
537 else
538 _vm->_currentCharacter->facing = 5;
539 animRefreshNPC(0);
540 updateAllObjectShapes();
541 }
542
fetchAnimWidth(const uint8 * shape,int16 mult)543 int16 Animator_LoK::fetchAnimWidth(const uint8 *shape, int16 mult) {
544 if (_vm->gameFlags().useAltShapeHeader)
545 shape += 2;
546 return (((int16)READ_LE_UINT16((shape + 3))) * mult) >> 8;
547 }
548
fetchAnimHeight(const uint8 * shape,int16 mult)549 int16 Animator_LoK::fetchAnimHeight(const uint8 *shape, int16 mult) {
550 if (_vm->gameFlags().useAltShapeHeader)
551 shape += 2;
552 return (int16)(((int8)*(shape + 2)) * mult) >> 8;
553 }
554
setBrandonAnimSeqSize(int width,int height)555 void Animator_LoK::setBrandonAnimSeqSize(int width, int height) {
556 restoreAllObjectBackgrounds();
557 _brandonAnimSeqSizeWidth = _actors[0].width;
558 _brandonAnimSeqSizeHeight = _actors[0].height;
559 _actors[0].width = width + 1;
560 _actors[0].height = height;
561 preserveAllBackgrounds();
562 }
563
resetBrandonAnimSeqSize()564 void Animator_LoK::resetBrandonAnimSeqSize() {
565 restoreAllObjectBackgrounds();
566 _actors[0].width = _brandonAnimSeqSizeWidth;
567 _actors[0].height = _brandonAnimSeqSizeHeight;
568 preserveAllBackgrounds();
569 }
570
animRefreshNPC(int character)571 void Animator_LoK::animRefreshNPC(int character) {
572 AnimObject *animObj = &_actors[character];
573 Character *ch = &_vm->characterList()[character];
574
575 animObj->refreshFlag = 1;
576 animObj->bkgdChangeFlag = 1;
577 int facing = ch->facing;
578 if (facing >= 1 && facing <= 3)
579 animObj->flags |= 1;
580 else if (facing >= 5 && facing <= 7)
581 animObj->flags &= 0xFFFFFFFE;
582
583 animObj->drawY = ch->y1;
584 animObj->sceneAnimPtr = _vm->shapes()[ch->currentAnimFrame];
585 animObj->animFrameNumber = ch->currentAnimFrame;
586 if (character == 0) {
587 if (_vm->brandonStatus() & 10) {
588 animObj->animFrameNumber = 88;
589 ch->currentAnimFrame = 88;
590 }
591 if (_vm->brandonStatus() & 2) {
592 animObj->animFrameNumber = _brandonDrawFrame;
593 ch->currentAnimFrame = _brandonDrawFrame;
594 animObj->sceneAnimPtr = _vm->shapes()[_brandonDrawFrame];
595 if (_vm->_brandonStatusBit0x02Flag) {
596 ++_brandonDrawFrame;
597 // TODO: check this
598 if (_brandonDrawFrame >= 122) {
599 _brandonDrawFrame = 113;
600 _vm->_brandonStatusBit0x02Flag = 0;
601 }
602 }
603 }
604 }
605
606 int xOffset = _vm->_defaultShapeTable[ch->currentAnimFrame - 7].xOffset;
607 int yOffset = _vm->_defaultShapeTable[ch->currentAnimFrame - 7].yOffset;
608
609 if (_vm->_scaleMode) {
610 animObj->x1 = ch->x1;
611 animObj->y1 = ch->y1;
612
613 int newScale = _vm->_scaleTable[ch->y1];
614 _brandonScaleX = newScale;
615 _brandonScaleY = newScale;
616
617 animObj->x1 += (_brandonScaleX * xOffset) >> 8;
618 animObj->y1 += (_brandonScaleY * yOffset) >> 8;
619 } else {
620 animObj->x1 = ch->x1 + xOffset;
621 animObj->y1 = ch->y1 + yOffset;
622 }
623 animObj->width2 = 4;
624 animObj->height2 = 3;
625
626 refreshObject(animObj);
627 }
628
setCharacterDefaultFrame(int character)629 void Animator_LoK::setCharacterDefaultFrame(int character) {
630 static const uint16 initFrameTable[] = {
631 7, 41, 77, 0, 0
632 };
633 assert(character < ARRAYSIZE(initFrameTable));
634 Character *edit = &_vm->characterList()[character];
635 edit->sceneId = 0xFFFF;
636 edit->facing = 0;
637 edit->currentAnimFrame = initFrameTable[character];
638 // edit->unk6 = 1;
639 }
640
setCharactersHeight()641 void Animator_LoK::setCharactersHeight() {
642 static const int8 initHeightTable[] = {
643 48, 40, 48, 47, 56,
644 44, 42, 47, 38, 35,
645 40
646 };
647 for (int i = 0; i < 11; ++i)
648 _vm->characterList()[i].height = initHeightTable[i];
649 }
650
651 } // End of namespace Kyra
652