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