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 
24 #include "queen/graphics.h"
25 
26 #include "queen/bankman.h"
27 #include "queen/display.h"
28 #include "queen/grid.h"
29 #include "queen/logic.h"
30 #include "queen/queen.h"
31 #include "queen/resource.h"
32 #include "queen/sound.h"
33 
34 #include "common/debug.h"
35 #include "common/textconsole.h"
36 
37 namespace Queen {
38 
curPos(int16 xx,int16 yy)39 void BobSlot::curPos(int16 xx, int16 yy) {
40 	active = true;
41 	x = xx;
42 	y = yy;
43 }
44 
move(int16 dstx,int16 dsty,int16 spd)45 void BobSlot::move(int16 dstx, int16 dsty, int16 spd) {
46 	active = true;
47 	moving = true;
48 
49 	endx = dstx;
50 	endy = dsty;
51 
52 	speed = (spd < 1) ? 1 : spd;
53 
54 	int16 deltax = endx - x;
55 	if (deltax < 0) {
56 		dx   = -deltax;
57 		xdir = -1;
58 	} else {
59 		dx   = deltax;
60 		xdir = 1;
61 	}
62 	int16 deltay = endy - y;
63 	if (deltay < 0) {
64 		dy   = -deltay;
65 		ydir = -1;
66 	} else {
67 		dy   = deltay;
68 		ydir = 1;
69 	}
70 
71 	if (dx > dy) {
72 		total = dy / 2;
73 		xmajor = true;
74 	} else {
75 		total = dx / 2;
76 		xmajor = false;
77 	}
78 
79 	// move one step along line to avoid glitching
80 	moveOneStep();
81 }
82 
moveOneStep()83 void BobSlot::moveOneStep() {
84 	if (xmajor) {
85 		if (x == endx) {
86 			y = endy;
87 			moving = false;
88 		} else {
89 			x += xdir;
90 			total += dy;
91 			if (total > dx) {
92 				y += ydir;
93 				total -= dx;
94 			}
95 		}
96 	} else {
97 		if (y == endy) {
98 			x = endx;
99 			moving = false;
100 		} else {
101 			y += ydir;
102 			total += dx;
103 			if (total > dy) {
104 				x += xdir;
105 				total -= dy;
106 			}
107 		}
108 	}
109 }
110 
animOneStep()111 void BobSlot::animOneStep() {
112 	if (anim.string.buffer != NULL) {
113 		--anim.speed;
114 		if (anim.speed <= 0) {
115 			// jump to next entry
116 			++anim.string.curPos;
117 			uint16 nextFrame = anim.string.curPos->frame;
118 			if (nextFrame == 0) {
119 				anim.string.curPos = anim.string.buffer;
120 				frameNum = anim.string.curPos->frame;
121 			} else {
122 				frameNum = nextFrame;
123 			}
124 			anim.speed = anim.string.curPos->speed / 4;
125 		}
126 	} else {
127 		// normal looping animation
128 		--anim.speed;
129 		if (anim.speed == 0) {
130 			anim.speed = anim.speedBak;
131 
132 			int16 nextFrame = frameNum + frameDir;
133 			if (nextFrame > anim.normal.lastFrame || nextFrame < anim.normal.firstFrame) {
134 				if (anim.normal.rebound) {
135 					frameDir *= -1;
136 				} else {
137 					frameNum = anim.normal.firstFrame - 1;
138 				}
139 			}
140 			frameNum += frameDir;
141 		}
142 	}
143 }
144 
animString(const AnimFrame * animBuf)145 void BobSlot::animString(const AnimFrame *animBuf) {
146 	active = true;
147 	animating = true;
148 	anim.string.buffer = animBuf;
149 	anim.string.curPos = animBuf;
150 	frameNum = animBuf->frame;
151 	anim.speed = animBuf->speed / 4;
152 }
153 
animNormal(uint16 firstFrame,uint16 lastFrame,uint16 spd,bool rebound,bool flip)154 void BobSlot::animNormal(uint16 firstFrame, uint16 lastFrame, uint16 spd, bool rebound, bool flip) {
155 	active = true;
156 	animating = true;
157 	frameNum = firstFrame;
158 	anim.speed = spd;
159 	anim.speedBak = spd;
160 	anim.string.buffer = NULL;
161 	anim.normal.firstFrame = firstFrame;
162 	anim.normal.lastFrame = lastFrame;
163 	anim.normal.rebound = rebound;
164 	frameDir = 1;
165 	xflip = flip;
166 }
167 
scaleWalkSpeed(uint16 ms)168 void BobSlot::scaleWalkSpeed(uint16 ms) {
169 	if (!xmajor) {
170 		ms /= 2;
171 	}
172 	speed = scale * ms / 100;
173 	if (speed == 0) {
174 		speed = 1;
175 	}
176 }
177 
clear(const Box * defaultBox)178 void BobSlot::clear(const Box *defaultBox) {
179 	active = false;
180 	xflip = false;
181 	animating = false;
182 	anim.string.buffer = NULL;
183 	moving = false;
184 	scale = 100;
185 	box = *defaultBox;
186 }
187 
compareBobDrawOrder(const void * a,const void * b)188 static int compareBobDrawOrder(const void *a, const void *b) {
189 	const BobSlot *bob1 = *(const BobSlot * const *)a;
190 	const BobSlot *bob2 = *(const BobSlot * const *)b;
191 	int d = bob1->y - bob2->y;
192 	// As the qsort() function may reorder "equal" elements,
193 	// we use the bob slot number when needed. This is required
194 	// during the introduction, to hide a crate behind the clock.
195 	if (d == 0) {
196 		d = bob1 - bob2;
197 	}
198 	return d;
199 }
200 
Graphics(QueenEngine * vm)201 Graphics::Graphics(QueenEngine *vm)
202 	: _cameraBob(0), _vm(vm),
203 	_defaultBox(-1, -1, -1, -1),
204 	_gameScreenBox(0, 0, GAME_SCREEN_WIDTH - 1, ROOM_ZONE_HEIGHT - 1),
205 	_fullScreenBox(0, 0, GAME_SCREEN_WIDTH - 1, GAME_SCREEN_HEIGHT - 1) {
206 	memset(_bobs, 0, sizeof(_bobs));
207 	memset(_sortedBobs, 0, sizeof(_sortedBobs));
208 	_sortedBobsCount = 0;
209 	_shrinkBuffer.data = new uint8[ BOB_SHRINK_BUF_SIZE ];
210 }
211 
~Graphics()212 Graphics::~Graphics() {
213 	delete[] _shrinkBuffer.data;
214 }
215 
unpackControlBank()216 void Graphics::unpackControlBank() {
217 	if (_vm->resource()->getPlatform() == Common::kPlatformDOS) {
218 		_vm->bankMan()->load("CONTROL.BBK",17);
219 
220 		// unpack mouse pointer frame
221 		_vm->bankMan()->unpack(1, 1, 17);
222 
223 		// unpack arrows frames and change hotspot to be always on top
224 		_vm->bankMan()->unpack(3, 3, 17);
225 		_vm->bankMan()->fetchFrame(3)->yhotspot += 200;
226 		_vm->bankMan()->unpack(4, 4, 17);
227 		_vm->bankMan()->fetchFrame(4)->yhotspot += 200;
228 
229 		_vm->bankMan()->close(17);
230 	}
231 }
232 
setupArrows()233 void Graphics::setupArrows() {
234 	if (_vm->resource()->getPlatform() == Common::kPlatformDOS) {
235 		int scrollX = _vm->display()->horizontalScroll();
236 		BobSlot *arrow;
237 		arrow = bob(ARROW_BOB_UP);
238 		arrow->curPos(303 + 8 + scrollX, 150 + 1 + 200);
239 		arrow->frameNum = 3;
240 		arrow = bob(ARROW_BOB_DOWN);
241 		arrow->curPos(303 + scrollX, 175 + 200);
242 		arrow->frameNum = 4;
243 	}
244 }
245 
setupMouseCursor()246 void Graphics::setupMouseCursor() {
247 	if (_vm->resource()->getPlatform() == Common::kPlatformAmiga) {
248 		static const uint8 defaultAmigaCursor[4 * 15] = {
249 			0x00, 0x00, 0xFF, 0xC0,
250 			0x7F, 0x80, 0x80, 0x40,
251 			0x7F, 0x00, 0x80, 0x80,
252 			0x7E, 0x00, 0x81, 0x00,
253 			0x7F, 0x00, 0x80, 0x80,
254 			0x7F, 0x80, 0x80, 0x40,
255 			0x7F, 0xC0, 0x80, 0x20,
256 			0x6F, 0xE0, 0x90, 0x10,
257 			0x47, 0xF0, 0xA8, 0x08,
258 			0x03, 0xF8, 0xC4, 0x04,
259 			0x01, 0xFC, 0x02, 0x02,
260 			0x00, 0xF8, 0x01, 0x04,
261 			0x00, 0x70, 0x00, 0x88,
262 			0x00, 0x20, 0x00, 0x50,
263 			0x00, 0x00, 0x00, 0x20
264 		};
265 		uint8 cursorData[16 * 15];
266 		memset(cursorData, 0, sizeof(cursorData));
267 		const uint8 *src = defaultAmigaCursor;
268 		int i = 0;
269 		for (int h = 0; h < 15; ++h) {
270 			for (int b = 0; b < 16; ++b) {
271 				const uint16 mask = (1 << (15 - b));
272 				uint8 color = 0;
273 				if (READ_BE_UINT16(src + 0) & mask) {
274 					color |= 2;
275 				}
276 				if (READ_BE_UINT16(src + 2) & mask) {
277 					color |= 1;
278 				}
279 				if (color != 0) {
280 					cursorData[i] = 0x90 + color - 1;
281 				}
282 				++i;
283 			}
284 			src += 4;
285 		}
286 		_vm->display()->setMouseCursor(cursorData, 16, 15);
287 	} else {
288 		BobFrame *bf = _vm->bankMan()->fetchFrame(1);
289 		_vm->display()->setMouseCursor(bf->data, bf->width, bf->height);
290 	}
291 }
292 
drawBob(const BobSlot * bs,const BobFrame * bf,const Box * bbox,int16 x,int16 y)293 void Graphics::drawBob(const BobSlot *bs, const BobFrame *bf, const Box *bbox, int16 x, int16 y) {
294 	debug(9, "Graphics::drawBob(%d, %d, %d)", bs->frameNum, x, y);
295 
296 	uint16 w, h;
297 	if (bs->scale < 100) {
298 		shrinkFrame(bf, bs->scale);
299 		bf = &_shrinkBuffer;
300 	}
301 	w = bf->width;
302 	h = bf->height;
303 
304 	const Box *box = (bs->box == _defaultBox) ? bbox : &bs->box;
305 
306 	if (w != 0 && h != 0 && box->intersects(x, y, w, h)) {
307 		uint8 *src = bf->data;
308 		uint16 x_skip = 0;
309 		uint16 y_skip = 0;
310 		uint16 w_new = w;
311 		uint16 h_new = h;
312 
313 		// compute bounding box intersection with frame
314 		if (x < box->x1) {
315 			x_skip = box->x1 - x;
316 			w_new -= x_skip;
317 			x = box->x1;
318 		}
319 
320 		if (y < box->y1) {
321 			y_skip = box->y1 - y;
322 			h_new -= y_skip;
323 			y = box->y1;
324 		}
325 
326 		if (x + w_new > box->x2 + 1) {
327 			w_new = box->x2 - x + 1;
328 		}
329 
330 		if (y + h_new > box->y2 + 1) {
331 			h_new = box->y2 - y + 1;
332 		}
333 
334 		src += w * y_skip;
335 		if (!bs->xflip) {
336 			src += x_skip;
337 		} else {
338 			src += w - w_new - x_skip;
339 			x += w_new - 1;
340 		}
341 		_vm->display()->drawBobSprite(src, x, y, w_new, h_new, w, bs->xflip);
342 	}
343 }
344 
drawInventoryItem(uint32 frameNum,uint16 x,uint16 y)345 void Graphics::drawInventoryItem(uint32 frameNum, uint16 x, uint16 y) {
346 	if (frameNum != 0) {
347 		BobFrame *bf = _vm->bankMan()->fetchFrame(frameNum);
348 		_vm->display()->drawInventoryItem(bf->data, x, y, bf->width, bf->height);
349 	} else {
350 		_vm->display()->drawInventoryItem(NULL, x, y, 32, 32);
351 	}
352 }
353 
pasteBob(uint16 objNum,uint16 image)354 void Graphics::pasteBob(uint16 objNum, uint16 image) {
355 	GraphicData *pgd = _vm->logic()->graphicData(objNum);
356 	_vm->bankMan()->unpack(pgd->firstFrame, image, 15);
357 	BobFrame *bf = _vm->bankMan()->fetchFrame(image);
358 	_vm->display()->drawBobPasteDown(bf->data, pgd->x, pgd->y, bf->width, bf->height);
359 	_vm->bankMan()->eraseFrame(image);
360 }
361 
shrinkFrame(const BobFrame * bf,uint16 percentage)362 void Graphics::shrinkFrame(const BobFrame *bf, uint16 percentage) {
363 	// computing new size, rounding to upper value
364 	uint16 new_w = (bf->width  * percentage + 50) / 100;
365 	uint16 new_h = (bf->height * percentage + 50) / 100;
366 	assert(new_w * new_h < BOB_SHRINK_BUF_SIZE);
367 
368 	if (new_w != 0 && new_h != 0) {
369 		_shrinkBuffer.width  = new_w;
370 		_shrinkBuffer.height = new_h;
371 
372 		uint16 x, y;
373 		uint16 sh[GAME_SCREEN_WIDTH];
374 		for (x = 0; x < MAX(new_h, new_w); ++x) {
375 			sh[x] = x * 100 / percentage;
376 		}
377 		uint8* dst = _shrinkBuffer.data;
378 		for (y = 0; y < new_h; ++y) {
379 			uint8 *p = bf->data + sh[y] * bf->width;
380 			for (x = 0; x < new_w; ++x) {
381 				*dst++ = *(p + sh[x]);
382 			}
383 		}
384 	}
385 }
386 
sortBobs()387 void Graphics::sortBobs() {
388 	_sortedBobsCount = 0;
389 
390 	// animate/move the bobs
391 	for (int32 i = 0; i < ARRAYSIZE(_bobs); ++i) {
392 		BobSlot *pbs = &_bobs[i];
393 		if (pbs->active) {
394 			_sortedBobs[_sortedBobsCount] = pbs;
395 			++_sortedBobsCount;
396 
397 			if (pbs->animating) {
398 				pbs->animOneStep();
399 				if (pbs->frameNum > 500) { // SFX frame
400 					_vm->sound()->playSfx(_vm->logic()->currentRoomSfx());
401 					pbs->frameNum -= 500;
402 				}
403 			}
404 			if (pbs->moving) {
405 				int16 j;
406 				for (j = 0; pbs->moving && j < pbs->speed; ++j) {
407 					pbs->moveOneStep();
408 				}
409 			}
410 		}
411 	}
412 	qsort(_sortedBobs, _sortedBobsCount, sizeof(BobSlot *), compareBobDrawOrder);
413 }
414 
drawBobs()415 void Graphics::drawBobs() {
416 	const Box *bobBox = _vm->display()->fullscreen() ? &_fullScreenBox : &_gameScreenBox;
417 	for (int i = 0; i < _sortedBobsCount; ++i) {
418 		BobSlot *pbs = _sortedBobs[i];
419 		if (pbs->active) {
420 
421 			BobFrame *pbf = _vm->bankMan()->fetchFrame(pbs->frameNum);
422 			uint16 xh, yh, x, y;
423 
424 			xh = pbf->xhotspot;
425 			yh = pbf->yhotspot;
426 
427 			if (pbs->xflip) {
428 				xh = pbf->width - xh;
429 			}
430 
431 			// adjusts hot spots when object is scaled
432 			if (pbs->scale != 100) {
433 				xh = (xh * pbs->scale) / 100;
434 				yh = (yh * pbs->scale) / 100;
435 			}
436 
437 			// adjusts position to hot-spot and screen scroll
438 			x = pbs->x - xh - _vm->display()->horizontalScroll();
439 			y = pbs->y - yh;
440 
441 			drawBob(pbs, pbf, bobBox, x, y);
442 		}
443 	}
444 }
445 
clearBobs()446 void Graphics::clearBobs() {
447 	for (int32 i = 0; i < ARRAYSIZE(_bobs); ++i) {
448 		_bobs[i].clear(&_defaultBox);
449 	}
450 }
451 
stopBobs()452 void Graphics::stopBobs() {
453 	for (int32 i = 0; i < ARRAYSIZE(_bobs); ++i) {
454 		_bobs[i].moving = false;
455 	}
456 }
457 
bob(int index)458 BobSlot *Graphics::bob(int index) {
459 	assert(index >= 0 && index < MAX_BOBS_NUMBER);
460 	return &_bobs[index];
461 }
462 
setBobText(const BobSlot * pbs,const char * text,int textX,int textY,int color,int flags)463 void Graphics::setBobText(const BobSlot *pbs, const char *text, int textX, int textY, int color, int flags) {
464 
465 	if (text[0] == '\0')
466 		return;
467 
468 	// Duplicate string and append zero if needed
469 
470 	char textCopy[MAX_STRING_SIZE];
471 
472 	int length = strlen(text);
473 	memcpy(textCopy, text, length);
474 
475 	if (textCopy[length - 1] >= 'A')
476 		textCopy[length++] = '.';
477 
478 	textCopy[length] = '\0';
479 
480 	// Split text into lines
481 
482 	char lines[8][MAX_STRING_SIZE];
483 	int lineCount = 0;
484 	int lineLength = 0;
485 	int i;
486 
487 	// Hebrew strings are written from right to left and should be cut
488 	// to lines in reverse
489 	if (_vm->resource()->getLanguage() == Common::HE_ISR) {
490 		for (i = length - 1; i >= 0; i--) {
491 			lineLength++;
492 
493 			if ((lineLength > 20 && textCopy[i] == ' ') || i == 0) {
494 				memcpy(lines[lineCount], textCopy + i, lineLength);
495 				lines[lineCount][lineLength] = '\0';
496 				lineCount++;
497 				lineLength = 0;
498 			}
499 		}
500 	} else {
501 		for (i = 0; i < length; i++) {
502 			lineLength++;
503 
504 			if ((lineLength > 20 && textCopy[i] == ' ') || i == (length-1)) {
505 				memcpy(lines[lineCount], textCopy + i + 1 - lineLength, lineLength);
506 				lines[lineCount][lineLength] = '\0';
507 				lineCount++;
508 				lineLength = 0;
509 			}
510 		}
511 	}
512 
513 	// Find width of widest line
514 
515 	int maxLineWidth = 0;
516 
517 	for (i = 0; i < lineCount; i++) {
518 		int width = _vm->display()->textWidth(lines[i]);
519 		if (maxLineWidth < width)
520 			maxLineWidth = width;
521 	}
522 
523 	// Calc text position
524 
525 	short x, y, width;
526 
527 	if (flags) {
528 		if (flags == 2)
529 			x = 160 - maxLineWidth / 2;
530 		else
531 			x = textX;
532 
533 		y = textY;
534 
535 		width = 0;
536 	} else {
537 		x = pbs->x;
538 		y = pbs->y;
539 
540 		BobFrame *pbf = _vm->bankMan()->fetchFrame(pbs->frameNum);
541 
542 		width  = (pbf->width  * pbs->scale) / 100;
543 		short height = (pbf->height * pbs->scale) / 100;
544 
545 		y = y - height - 16 - lineCount * 9;
546 	}
547 
548 	x -= _vm->display()->horizontalScroll();
549 
550 	if (y < 0) {
551 		y = 0;
552 
553 		if (x < 160)
554 			x += width / 2;
555 		else
556 			x -= width / 2 + maxLineWidth;
557 	} else if (!flags)
558 		x -= maxLineWidth / 2;
559 
560 	if (x < 0)
561 		x = 4;
562 	else if ((x + maxLineWidth) > 320)
563 		x = 320 - maxLineWidth - 4;
564 
565 	// remap some colors for the Amiga
566 	if (_vm->resource()->getPlatform() == Common::kPlatformAmiga) {
567 		if (color == 5) {
568 			color = (_vm->logic()->currentRoom() == 9) ? 15 : 11;
569 		} else if (color == 10 && _vm->logic()->currentRoom() == 100) {
570 			color = 11;
571 		}
572 	}
573 
574 	_vm->display()->textCurrentColor(color);
575 
576 	for (i = 0; i < lineCount; i++) {
577 		int lineX = x + (maxLineWidth - _vm->display()->textWidth(lines[i])) / 2;
578 
579 		debug(7, "Setting text '%s' at (%i, %i)", lines[i], lineX, y + 9 * i);
580 		_vm->display()->setText(lineX, y + 9 * i, lines[i]);
581 	}
582 }
583 
handleParallax(uint16 roomNum)584 void Graphics::handleParallax(uint16 roomNum) {
585 	uint16 screenScroll = _vm->display()->horizontalScroll();
586 	switch (roomNum) {
587 	case ROOM_AMAZON_HIDEOUT:
588 		_bobs[8].x = 250 - screenScroll / 2;
589 		break;
590 	case ROOM_TEMPLE_MAZE_5:
591 		_bobs[5].x = 410 - screenScroll / 2;
592 		_bobs[6].x = 790 - screenScroll / 2;
593 		break;
594 	case ROOM_TEMPLE_OUTSIDE:
595 		_bobs[5].x = 320 - screenScroll / 2;
596 		break;
597 	case ROOM_TEMPLE_TREE:
598 		_bobs[5].x = 280 - screenScroll / 2;
599 		break;
600 	case ROOM_VALLEY_CARCASS:
601 		_bobs[5].x = 600 - screenScroll / 2;
602 		break;
603 	case ROOM_UNUSED_INTRO_1:
604 		_bobs[5].x = 340 - screenScroll / 2;
605 		_bobs[6].x = 50 - screenScroll / 2;
606 		_bobs[7].x = 79 - screenScroll / 2;
607 		break;
608 	case ROOM_CAR_CHASE:
609 		_vm->bam()->updateCarAnimation();
610 		break;
611 	case ROOM_FINAL_FIGHT:
612 		_vm->bam()->updateFightAnimation();
613 		break;
614 	case ROOM_INTRO_RITA_JOE_HEADS:
615 		_cameraBob = -1;
616 		if (screenScroll < 80) {
617 			_vm->display()->horizontalScroll(screenScroll + 4);
618 			// Joe's body and head
619 			_bobs[ 1].x += 4;
620 			_bobs[20].x += 4;
621 			// Rita's body and head
622 			_bobs[ 2].x -= 2;
623 			_bobs[21].x -= 2;
624 		}
625 		break;
626 	case ROOM_INTRO_EXPLOSION:
627 		_bobs[21].x += 2;
628 		_bobs[21].y += 2;
629 		break;
630 	}
631 }
632 
setupNewRoom(const char * room,uint16 roomNum,int16 * furniture,uint16 furnitureCount)633 void Graphics::setupNewRoom(const char *room, uint16 roomNum, int16 *furniture, uint16 furnitureCount) {
634 	// reset sprites table
635 	clearBobs();
636 
637 	// load/setup objects associated to this room
638 	char filename[20];
639 	sprintf(filename, "%s.BBK", room);
640 	_vm->bankMan()->load(filename, 15);
641 
642 	_numFrames = FRAMES_JOE + 1;
643 	setupRoomFurniture(furniture, furnitureCount);
644 	setupRoomObjects();
645 
646 	if (roomNum >= 90) {
647 		putCameraOnBob(0);
648 	}
649 }
650 
setBobCutawayAnim(uint16 bobNum,bool xflip,const AnimFrame * af,uint8 frameCount)651 void Graphics::setBobCutawayAnim(uint16 bobNum, bool xflip, const AnimFrame *af, uint8 frameCount) {
652 	assert(bobNum < 21 && frameCount < 30);
653 	memcpy(_cutAnim[bobNum], af, sizeof(AnimFrame) * frameCount);
654 	_bobs[bobNum].xflip = xflip;
655 	_bobs[bobNum].animString(_cutAnim[bobNum]);
656 }
657 
fillAnimBuffer(const char * anim,AnimFrame * af)658 void Graphics::fillAnimBuffer(const char *anim, AnimFrame *af) {
659 	for (;;) {
660 		// anim frame format is "%3hu,%3hu," (frame number, frame speed)
661 		af->frame = atoi(anim);
662 		anim += 4;
663 		af->speed = atoi(anim);
664 		anim += 4;
665 		if (af->frame == 0)
666 			break;
667 		++af;
668 	}
669 }
670 
countAnimFrames(const char * anim)671 uint16 Graphics::countAnimFrames(const char *anim) {
672 	AnimFrame afbuf[30];
673 	fillAnimBuffer(anim, afbuf);
674 
675 	bool frames[256];
676 	memset(frames, 0, sizeof(frames));
677 	uint16 count = 0;
678 	AnimFrame *af = afbuf;
679 	for ( ; af->frame != 0; ++af) {
680 		uint16 frameNum = af->frame;
681 		if (frameNum > 500) {
682 			frameNum -= 500;
683 		}
684 		if (!frames[frameNum]) {
685 			frames[frameNum] = true;
686 			++count;
687 		}
688 	}
689 	return count;
690 }
691 
setupObjectAnim(const GraphicData * gd,uint16 firstImage,uint16 bobNum,bool visible)692 void Graphics::setupObjectAnim(const GraphicData *gd, uint16 firstImage, uint16 bobNum, bool visible) {
693 	int16 tempFrames[20];
694 	memset(tempFrames, 0, sizeof(tempFrames));
695 	uint16 numTempFrames = 0;
696 	uint16 i, j;
697 	for (i = 1; i <= _vm->logic()->graphicAnimCount(); ++i) {
698 		const GraphicAnim *pga = _vm->logic()->graphicAnim(i);
699 		if (pga->keyFrame == gd->firstFrame) {
700 			int16 frame = pga->frame;
701 			if (frame > 500) { // SFX
702 				frame -= 500;
703 			}
704 			bool foundMatchingFrame = false;
705 			for (j = 0; j < numTempFrames; ++j) {
706 				if (tempFrames[j] == frame) {
707 					foundMatchingFrame = true;
708 					break;
709 				}
710 			}
711 			if (!foundMatchingFrame) {
712 				assert(numTempFrames < 20);
713 				tempFrames[numTempFrames] = frame;
714 				++numTempFrames;
715 			}
716 		}
717 	}
718 
719 	// sort found frames ascending
720 	bool swap = true;
721 	while (swap) {
722 		swap = false;
723 		for (i = 0; i < numTempFrames - 1; ++i) {
724 			if (tempFrames[i] > tempFrames[i + 1]) {
725 				SWAP(tempFrames[i], tempFrames[i + 1]);
726 				swap = true;
727 			}
728 		}
729 	}
730 
731 	// queen.c l.962-980 / l.1269-1294
732 	for (i = 0; i < gd->lastFrame; ++i) {
733 		_vm->bankMan()->unpack(ABS(tempFrames[i]), firstImage + i, 15);
734 	}
735 	BobSlot *pbs = bob(bobNum);
736 	pbs->animating = false;
737 	if (visible) {
738 		pbs->curPos(gd->x, gd->y);
739 		if (tempFrames[0] < 0) {
740 			pbs->xflip = true;
741 		}
742 		AnimFrame *paf = _newAnim[bobNum];
743 		for (i = 1; i <= _vm->logic()->graphicAnimCount(); ++i) {
744 			const GraphicAnim *pga = _vm->logic()->graphicAnim(i);
745 			if (pga->keyFrame == gd->firstFrame) {
746 				uint16 frameNr = 0;
747 				for (j = 1; j <= gd->lastFrame; ++j) {
748 					if (pga->frame > 500) {
749 						if (pga->frame - 500 == tempFrames[j - 1]) {
750 							frameNr = j + firstImage - 1 + 500;
751 						}
752 					} else if (pga->frame == tempFrames[j - 1]) {
753 						frameNr = j + firstImage - 1;
754 					}
755 				}
756 				paf->frame = frameNr;
757 				paf->speed = pga->speed;
758 				++paf;
759 			}
760 		}
761 		paf->frame = 0;
762 		paf->speed = 0;
763 		pbs->animString(_newAnim[bobNum]);
764 	}
765 }
766 
setupPersonAnim(const ActorData * ad,const char * anim,uint16 curImage)767 uint16 Graphics::setupPersonAnim(const ActorData *ad, const char *anim, uint16 curImage) {
768 	debug(9, "Graphics::setupPersonAnim(%s, %d)", anim, curImage);
769 	_personFrames[ad->bobNum] = curImage + 1;
770 
771 	AnimFrame *animFrames = _newAnim[ad->bobNum];
772 	fillAnimBuffer(anim, animFrames);
773 	uint16 frameCount[256];
774 	memset(frameCount, 0, sizeof(frameCount));
775 	AnimFrame *af = animFrames;
776 	for ( ; af->frame != 0; ++af) {
777 		uint16 frameNum = af->frame;
778 		if (frameNum > 500) {
779 			frameNum -= 500;
780 		}
781 		if (!frameCount[frameNum]) {
782 			frameCount[frameNum] = 1;
783 		}
784 	}
785 	uint16 i, n = 1;
786 	for (i = 1; i < 256; ++i) {
787 		if (frameCount[i]) {
788 			frameCount[i] = n;
789 			++n;
790 		}
791 	}
792 	af = animFrames;
793 	for ( ; af->frame != 0; ++af) {
794 		if (af->frame > 500) {
795 			af->frame = curImage + frameCount[af->frame - 500] + 500;
796 		} else {
797 			af->frame = curImage + frameCount[af->frame];
798 		}
799 	}
800 
801 	// unpack necessary frames
802 	for (i = 1; i < 256; ++i) {
803 		if (frameCount[i]) {
804 			++curImage;
805 			_vm->bankMan()->unpack(i, curImage, ad->bankNum);
806 		}
807 	}
808 
809 	// start animation
810 	bob(ad->bobNum)->animString(animFrames);
811 	return curImage;
812 }
813 
resetPersonAnim(uint16 bobNum)814 void Graphics::resetPersonAnim(uint16 bobNum) {
815 	if (_newAnim[bobNum][0].frame != 0) {
816 		bob(bobNum)->animString(_newAnim[bobNum]);
817 	}
818 }
819 
erasePersonAnim(uint16 bobNum)820 void Graphics::erasePersonAnim(uint16 bobNum) {
821 	_newAnim[bobNum][0].frame = 0;
822 	BobSlot *pbs = bob(bobNum);
823 	pbs->animating = false;
824 	pbs->anim.string.buffer = NULL;
825 }
826 
eraseAllAnims()827 void Graphics::eraseAllAnims() {
828 	for (int i = 1; i <= 16; ++i) {
829 		_newAnim[i][0].frame = 0;
830 	}
831 }
832 
refreshObject(uint16 obj)833 uint16 Graphics::refreshObject(uint16 obj) {
834 	debug(6, "Graphics::refreshObject(%X)", obj);
835 	uint16 curImage = _numFrames;
836 
837 	ObjectData *pod = _vm->logic()->objectData(obj);
838 	if (pod->image == 0) {
839 		return curImage;
840 	}
841 
842 	// check the object is in the current room
843 	if (pod->room != _vm->logic()->currentRoom()) {
844 		return curImage;
845 	}
846 
847 	// find bob for the object
848 	uint16 curBob = _vm->logic()->findBob(obj);
849 	BobSlot *pbs = bob(curBob);
850 
851 	if (pod->image == -3 || pod->image == -4) {
852 		// a person object
853 		if (pod->name <= 0) {
854 			pbs->clear(&_defaultBox);
855 		} else {
856 			// find person number
857 			uint16 pNum = _vm->logic()->findPersonNumber(obj, _vm->logic()->currentRoom());
858 			curImage = _personFrames[pNum] - 1;
859 			if (_personFrames[pNum] == 0) {
860 				_personFrames[pNum] = curImage = _numFrames;
861 			}
862 			curImage = setupPerson(obj - _vm->logic()->currentRoomData(), curImage);
863 		}
864 		return curImage;
865 	}
866 
867 	// find frame used for object
868 	curImage = _vm->logic()->findFrame(obj);
869 
870 	if (pod->name < 0 || pod->image < 0) {
871 		// object is hidden or disabled
872 		pbs->clear(&_defaultBox);
873 		return curImage;
874 	}
875 
876 	int image = pod->image;
877 	if (image > 5000) {
878 		image -= 5000;
879 	}
880 
881 	GraphicData *pgd = _vm->logic()->graphicData(image);
882 	bool rebound = false;
883 	int16 lastFrame = pgd->lastFrame;
884 	if (lastFrame < 0) {
885 		lastFrame = -lastFrame;
886 		rebound = true;
887 	}
888 	if (pgd->firstFrame < 0) {
889 		setupObjectAnim(pgd, curImage, curBob, pod->name != 0);
890 		curImage += pgd->lastFrame - 1;
891 	} else if (lastFrame != 0) {
892 		// turn on an animated bob
893 		pbs->animating = false;
894 		uint16 firstImage = curImage;
895 		--curImage;
896 		uint16 j;
897 		for (j = pgd->firstFrame; j <= lastFrame; ++j) {
898 			++curImage;
899 			_vm->bankMan()->unpack(j, curImage, 15);
900 		}
901 		pbs->curPos(pgd->x, pgd->y);
902 		pbs->frameNum = firstImage;
903 		if (pgd->speed > 0) {
904 			pbs->animNormal(firstImage, curImage, pgd->speed / 4, rebound, false);
905 		}
906 	} else {
907 		_vm->bankMan()->unpack(pgd->firstFrame, curImage, 15);
908 		pbs->curPos(pgd->x, pgd->y);
909 		pbs->frameNum = curImage;
910 	}
911 
912 	return curImage;
913 }
914 
setupRoomFurniture(int16 * furniture,uint16 furnitureCount)915 void Graphics::setupRoomFurniture(int16 *furniture, uint16 furnitureCount) {
916 	uint16 i;
917 	uint16 curImage = FRAMES_JOE;
918 
919 	// unpack the static bobs
920 	_numFurnitureStatic = 0;
921 	for	(i = 1; i <= furnitureCount; ++i) {
922 		int16 obj = furniture[i];
923 		if (obj > 0 && obj <= 5000) {
924 			GraphicData *pgd = _vm->logic()->graphicData(obj);
925 			if (pgd->lastFrame == 0) {
926 				++_numFurnitureStatic;
927 				++curImage;
928 				_vm->bankMan()->unpack(pgd->firstFrame, curImage, 15);
929 				++_numFrames;
930 				BobSlot *pbs = bob(19 + _numFurnitureStatic);
931 				pbs->curPos(pgd->x, pgd->y);
932 				pbs->frameNum = curImage;
933 			}
934 		}
935 	}
936 
937 	// unpack the animated bobs
938 	_numFurnitureAnimated = 0;
939 	_numFurnitureAnimatedLen = 0;
940 	uint16 curBob = 0;
941 	for  (i = 1; i <= furnitureCount; ++i) {
942 		int16 obj = furniture[i];
943 		if (obj > 0 && obj <= 5000) {
944 			GraphicData *pgd = _vm->logic()->graphicData(obj);
945 
946 			bool rebound = false;
947 			int16 lastFrame = pgd->lastFrame;
948 			if (lastFrame < 0) {
949 				rebound = true;
950 				lastFrame = -lastFrame;
951 			}
952 
953 			if (lastFrame > 0) {
954 				_numFurnitureAnimatedLen += lastFrame - pgd->firstFrame + 1;
955 				++_numFurnitureAnimated;
956 				uint16 image = curImage + 1;
957 				int k;
958 				for (k = pgd->firstFrame; k <= lastFrame; ++k) {
959 					++curImage;
960 					_vm->bankMan()->unpack(k, curImage, 15);
961 					++_numFrames;
962 				}
963 				BobSlot *pbs = bob(5 + curBob);
964 				pbs->animNormal(image, curImage, pgd->speed / 4, rebound, false);
965 				pbs->curPos(pgd->x, pgd->y);
966 				++curBob;
967 			}
968 		}
969 	}
970 
971 	// unpack the paste downs
972 	for  (i = 1; i <= furnitureCount; ++i) {
973 		if (furniture[i] > 5000) {
974 			pasteBob(furniture[i] - 5000, curImage + 1);
975 		}
976 	}
977 }
978 
setupRoomObjects()979 void Graphics::setupRoomObjects() {
980 	uint16 i;
981 	// furniture frames are reserved in ::setupRoomFurniture(), we append objects
982 	// frames after the furniture ones.
983 	uint16 curImage = FRAMES_JOE + _numFurnitureStatic + _numFurnitureAnimatedLen;
984 	uint16 firstRoomObj = _vm->logic()->currentRoomData() + 1;
985 	uint16 lastRoomObj = _vm->logic()->roomData(_vm->logic()->currentRoom() + 1);
986 	uint16 numObjectStatic = 0;
987 	uint16 numObjectAnimated = 0;
988 	uint16 curBob;
989 
990 	// invalidates all Bobs for persons (except Joe's one)
991 	for (i = 1; i <= 3; ++i) {
992 		_bobs[i].active = false;
993 	}
994 
995 	// static/animated Bobs
996 	for (i = firstRoomObj; i <= lastRoomObj; ++i) {
997 		ObjectData *pod = _vm->logic()->objectData(i);
998 		// setup blanks bobs for turned off objects (in case
999 		// you turn them on again)
1000 		if (pod->image == -1) {
1001 			// static OFF Bob
1002 			curBob = 20 + _numFurnitureStatic + numObjectStatic;
1003 			++numObjectStatic;
1004 			// create a blank frame for the OFF object
1005 			++_numFrames;
1006 			++curImage;
1007 		} else if (pod->image == -2) {
1008 			// animated OFF Bob
1009 			curBob = 5 + _numFurnitureAnimated + numObjectAnimated;
1010 			++numObjectAnimated;
1011 		} else if (pod->image > 0 && pod->image < 5000) {
1012 			GraphicData *pgd = _vm->logic()->graphicData(pod->image);
1013 			int16 lastFrame = pgd->lastFrame;
1014 			bool rebound = false;
1015 			if (lastFrame < 0) {
1016 				lastFrame = -lastFrame;
1017 				rebound = true;
1018 			}
1019 			if (pgd->firstFrame < 0) {
1020 				curBob = 5 + _numFurnitureAnimated;
1021 				setupObjectAnim(pgd, curImage + 1, curBob + numObjectAnimated, pod->name > 0);
1022 				curImage += pgd->lastFrame;
1023 				++numObjectAnimated;
1024 			} else if (lastFrame != 0) {
1025 				// animated objects
1026 				uint16 j;
1027 				uint16 firstFrame = curImage + 1;
1028 				for (j = pgd->firstFrame; j <= lastFrame; ++j) {
1029 					++curImage;
1030 					_vm->bankMan()->unpack(j, curImage, 15);
1031 					++_numFrames;
1032 				}
1033 				curBob = 5 + _numFurnitureAnimated + numObjectAnimated;
1034 				if (pod->name > 0) {
1035 					BobSlot *pbs = bob(curBob);
1036 					pbs->curPos(pgd->x, pgd->y);
1037 					pbs->frameNum = firstFrame;
1038 					if (pgd->speed > 0) {
1039 						pbs->animNormal(firstFrame, curImage, pgd->speed / 4, rebound, false);
1040 					}
1041 				}
1042 				++numObjectAnimated;
1043 			} else {
1044 				// static objects
1045 				curBob = 20 + _numFurnitureStatic + numObjectStatic;
1046 				++curImage;
1047 				bob(curBob)->clear(&_defaultBox);
1048 				_vm->bankMan()->unpack(pgd->firstFrame, curImage, 15);
1049 				++_numFrames;
1050 				if (pod->name > 0) {
1051 					BobSlot *pbs = bob(curBob);
1052 					pbs->curPos(pgd->x, pgd->y);
1053 					pbs->frameNum = curImage;
1054 				}
1055 				++numObjectStatic;
1056 			}
1057 		}
1058 	}
1059 
1060 	// persons Bobs
1061 	for (i = firstRoomObj; i <= lastRoomObj; ++i) {
1062 		ObjectData *pod = _vm->logic()->objectData(i);
1063 		if (pod->image == -3 || pod->image == -4) {
1064 			debug(6, "Graphics::setupRoomObjects() - Setting up person %X, name=%X", i, pod->name);
1065 			uint16 noun = i - _vm->logic()->currentRoomData();
1066 			if (pod->name > 0) {
1067 				curImage = setupPerson(noun, curImage);
1068 			} else {
1069 				curImage = allocPerson(noun, curImage);
1070 			}
1071 		}
1072 	}
1073 
1074 	// paste downs list
1075 	++curImage;
1076 	_numFrames = curImage;
1077 	for (i = firstRoomObj; i <= lastRoomObj; ++i) {
1078 		ObjectData *pod = _vm->logic()->objectData(i);
1079 		if (pod->name > 0 && pod->image > 5000) {
1080 			pasteBob(pod->image - 5000, curImage);
1081 		}
1082 	}
1083 }
1084 
setupPerson(uint16 noun,uint16 curImage)1085 uint16 Graphics::setupPerson(uint16 noun, uint16 curImage) {
1086 	if (noun == 0) {
1087 		warning("Trying to setup person 0");
1088 		return curImage;
1089 	}
1090 
1091 	Person p;
1092 	if (!_vm->logic()->initPerson(noun, "", true, &p)) {
1093 		return curImage;
1094 	}
1095 
1096 	const ActorData *pad = p.actor;
1097 	uint16 scale = 100;
1098 	uint16 a = _vm->grid()->findAreaForPos(GS_ROOM, pad->x, pad->y);
1099 	if (a != 0) {
1100 		// person is not standing in the area box, scale it accordingly
1101 		scale = _vm->grid()->area(_vm->logic()->currentRoom(), a)->calcScale(pad->y);
1102 	}
1103 
1104 	_vm->bankMan()->unpack(pad->bobFrameStanding, p.bobFrame, p.actor->bankNum);
1105 	uint16 obj = _vm->logic()->currentRoomData() + noun;
1106 	BobSlot *pbs = bob(pad->bobNum);
1107 	pbs->curPos(pad->x, pad->y);
1108 	pbs->scale = scale;
1109 	pbs->frameNum = p.bobFrame;
1110 	pbs->xflip = (_vm->logic()->objectData(obj)->image == -3); // person is facing left
1111 
1112 	debug(6, "Graphics::setupPerson(%d, %d) - bob = %d name = %s", noun, curImage, pad->bobNum, p.name);
1113 
1114 	if (p.anim != NULL) {
1115 		curImage = setupPersonAnim(pad, p.anim, curImage);
1116 	} else {
1117 		erasePersonAnim(pad->bobNum);
1118 	}
1119 	return curImage;
1120 }
1121 
allocPerson(uint16 noun,uint16 curImage)1122 uint16 Graphics::allocPerson(uint16 noun, uint16 curImage) {
1123 	Person p;
1124 	if (_vm->logic()->initPerson(noun, "", false, &p) && p.anim != NULL) {
1125 		curImage += countAnimFrames(p.anim);
1126 		_personFrames[p.actor->bobNum] = curImage + 1;
1127 	}
1128 	return curImage;
1129 }
1130 
update(uint16 room)1131 void Graphics::update(uint16 room) {
1132 	sortBobs();
1133 	if (_cameraBob >= 0) {
1134 		_vm->display()->horizontalScrollUpdate(_bobs[_cameraBob].x);
1135 	}
1136 	handleParallax(room);
1137 	_vm->display()->prepareUpdate();
1138 	drawBobs();
1139 }
1140 
1141 
BamScene(QueenEngine * vm)1142 BamScene::BamScene(QueenEngine *vm)
1143 	: _flag(F_STOP), _screenShaked(false), _fightData(_fight1Data), _vm(vm) {
1144 	if (_vm->resource()->getPlatform() == Common::kPlatformAmiga) {
1145 		_fightData = _fight4Data;
1146 	}
1147 }
1148 
playSfx()1149 void BamScene::playSfx() {
1150 	_vm->sound()->playSfx(_vm->logic()->currentRoomSfx());
1151 	_lastSoundIndex = _index;
1152 }
1153 
prepareAnimation()1154 void BamScene::prepareAnimation() {
1155 	_vm->graphics()->clearBob(BOB_OBJ1);
1156 	_obj1 = _vm->graphics()->bob(BOB_OBJ1);
1157 	_obj1->active = true;
1158 
1159 	_vm->graphics()->clearBob(BOB_OBJ2);
1160 	_obj2 = _vm->graphics()->bob(BOB_OBJ2);
1161 	_obj2->active = true;
1162 
1163 	_vm->graphics()->clearBob(BOB_FX);
1164 	_objfx = _vm->graphics()->bob(BOB_FX);
1165 	_objfx->active = true;
1166 
1167 	_index = 0;
1168 	_lastSoundIndex = 0;
1169 }
1170 
updateCarAnimation()1171 void BamScene::updateCarAnimation() {
1172 	if (_flag != F_STOP) {
1173 		const BamDataBlock *bdb = &_carData[_index];
1174 
1175 		// Truck
1176 		_obj1->curPos(bdb->obj1.x, bdb->obj1.y);
1177 		_obj1->frameNum = 40 + bdb->obj1.frame;
1178 
1179 		// Rico
1180 		_obj2->curPos(bdb->obj2.x, bdb->obj2.y);
1181 		_obj2->frameNum = 30 + bdb->obj2.frame;
1182 
1183 		// FX
1184 		_objfx->curPos(bdb->fx.x, bdb->fx.y);
1185 		_objfx->frameNum = 41 + bdb->fx.frame;
1186 
1187 		if (bdb->sfx < 0) {
1188 			_vm->sound()->playSong(-bdb->sfx);
1189 		}
1190 
1191 		if (bdb->sfx == 99) {
1192 			_lastSoundIndex = _index = 0;
1193 		} else {
1194 			++_index;
1195 		}
1196 
1197 		if (bdb->sfx == 2) {
1198 			playSfx();
1199 		}
1200 	}
1201 }
1202 
updateFightAnimation()1203 void BamScene::updateFightAnimation() {
1204 	static const BamDataBlock *const fightDataBlocks[] = {
1205 		_fight1Data,
1206 		_fight2Data,
1207 		_fight3Data
1208 	};
1209 	if (_flag != F_STOP) {
1210 		const BamDataBlock *bdb = &_fightData[_index];
1211 
1212 		// Frank
1213 		_obj1->curPos(bdb->obj1.x, bdb->obj1.y);
1214 		_obj1->frameNum = 40 + ABS(bdb->obj1.frame);
1215 		_obj1->xflip = (bdb->obj1.frame < 0);
1216 
1217 		// Robot
1218 		_obj2->curPos(bdb->obj2.x, bdb->obj2.y);
1219 		_obj2->frameNum = 40 + ABS(bdb->obj2.frame);
1220 		_obj2->xflip = (bdb->obj2.frame < 0);
1221 
1222 		// FX
1223 		_objfx->curPos(bdb->fx.x, bdb->fx.y);
1224 		_objfx->frameNum = 40 + ABS(bdb->fx.frame);
1225 		_objfx->xflip = (bdb->fx.frame < 0);
1226 
1227 		if (bdb->sfx < 0) {
1228 			_vm->sound()->playSong(-bdb->sfx);
1229 		}
1230 
1231 		++_index;
1232 		switch (bdb->sfx) {
1233 		case 0: // nothing, so reset shaked screen if necessary
1234 			if (_screenShaked) {
1235 				_vm->display()->shake(true);
1236 				_screenShaked = false;
1237 			}
1238 			break;
1239 		case 1: // shake screen
1240 			_vm->display()->shake(false);
1241 			_screenShaked = true;
1242 			break;
1243 		case 2: // play background sfx
1244 			playSfx();
1245 			break;
1246 		case 3: // play background sfx and shake screen
1247 			playSfx();
1248 			_vm->display()->shake(false);
1249 			_screenShaked = true;
1250 			break;
1251 		case 99: // end of BAM data
1252 			_lastSoundIndex = _index = 0;
1253 			if (_vm->resource()->getPlatform() == Common::kPlatformDOS) {
1254 				_fightData = fightDataBlocks[_vm->randomizer.getRandomNumber(2)];
1255 			}
1256 			if (_flag == F_REQ_STOP) {
1257 				_flag = F_STOP;
1258 			}
1259 			break;
1260 		}
1261 	}
1262 }
1263 
saveState(byte * & ptr)1264 void BamScene::saveState(byte *&ptr) {
1265 	WRITE_BE_UINT16(ptr, _flag); ptr += 2;
1266 }
1267 
loadState(uint32 ver,byte * & ptr)1268 void BamScene::loadState(uint32 ver, byte *&ptr) {
1269 	_flag = READ_BE_UINT16(ptr); ptr += 2;
1270 }
1271 
1272 const BamScene::BamDataBlock BamScene::_carData[] = {
1273 	{ { 310, 105, 1 }, { 314, 106, 17 }, { 366, 101,  1 },  0 },
1274 	{ { 303, 105, 1 }, { 307, 106, 17 }, { 214,   0, 10 },  0 },
1275 	{ { 297, 104, 1 }, { 301, 105, 17 }, { 214,   0, 10 },  0 },
1276 	{ { 294, 103, 1 }, { 298, 104, 17 }, { 214,   0, 10 },  0 },
1277 	{ { 291, 102, 1 }, { 295, 103, 18 }, { 214,   0, 10 },  0 },
1278 	{ { 287, 101, 1 }, { 291, 102, 18 }, { 266,  51, 10 },  2 },
1279 	{ { 283, 100, 1 }, { 287, 101, 19 }, { 279,  47, 11 },  0 },
1280 	{ { 279,  99, 1 }, { 283, 100, 20 }, { 294,  46, 12 },  0 },
1281 	{ { 274,  98, 1 }, { 278,  99, 20 }, { 305,  44, 13 },  0 },
1282 	{ { 269,  98, 1 }, { 273,  99, 20 }, { 320,  42, 14 },  0 },
1283 	{ { 264,  98, 1 }, { 268,  99, 17 }, { 214,   0, 10 },  0 },
1284 	{ { 261,  98, 1 }, { 265,  99, 17 }, { 214,   0, 10 },  0 },
1285 	{ { 259,  98, 1 }, { 263,  99, 17 }, { 214,   0, 10 },  0 },
1286 	{ { 258,  98, 1 }, { 262,  99, 17 }, { 214,   0, 10 },  0 },
1287 	{ { 257,  98, 2 }, { 260,  99, 17 }, { 214,   0, 10 },  0 },
1288 	{ { 255,  99, 3 }, { 258, 100, 17 }, { 214,   0, 10 },  0 },
1289 	{ { 258,  99, 4 }, { 257, 100, 17 }, { 214,   0, 10 },  0 },
1290 	{ { 264, 102, 4 }, { 263, 103, 17 }, { 214,   0, 10 },  0 },
1291 	{ { 272, 105, 5 }, { 274, 106, 17 }, { 214,   0, 10 },  0 },
1292 	{ { 276, 107, 5 }, { 277, 108, 17 }, { 214,   0, 10 },  0 },
1293 	{ { 283, 108, 5 }, { 284, 109, 17 }, { 214,   0, 10 },  0 },
1294 	{ { 288, 109, 5 }, { 288, 110, 17 }, { 214,   0, 10 },  0 },
1295 	{ { 293, 110, 5 }, { 293, 111, 18 }, { 266,  59, 10 },  2 },
1296 	{ { 298, 110, 5 }, { 299, 111, 18 }, { 277,  56, 11 },  0 },
1297 	{ { 303, 110, 5 }, { 304, 111, 19 }, { 285,  55, 12 },  0 },
1298 	{ { 308, 110, 4 }, { 307, 111, 20 }, { 296,  54, 13 },  0 },
1299 	{ { 309, 110, 3 }, { 312, 111, 20 }, { 304,  53, 14 },  0 },
1300 	{ { 310, 110, 3 }, { 313, 111, 20 }, { 214,   0, 10 },  0 },
1301 	{ { 311, 110, 3 }, { 314, 111, 17 }, { 214,   0, 10 },  0 },
1302 	{ { 309, 110, 2 }, { 312, 111, 17 }, { 214,   0, 10 },  0 },
1303 	{ { 304, 111, 2 }, { 307, 112, 17 }, { 214,   0, 10 },  0 },
1304 	{ { 300, 110, 2 }, { 303, 111, 17 }, { 214,   0, 10 },  0 },
1305 	{ { 296, 109, 2 }, { 299, 110, 17 }, { 214,   0, 10 },  0 },
1306 	{ { 292, 108, 1 }, { 296, 109, 17 }, { 214,   0, 10 },  0 },
1307 	{ { 285, 107, 2 }, { 289, 108, 17 }, { 214,   0, 10 },  0 },
1308 	{ { 282, 107, 3 }, { 285, 108, 17 }, { 214,   0, 10 },  0 },
1309 	{ { 278, 107, 4 }, { 277, 108, 18 }, { 214,   0, 10 },  0 },
1310 	{ { 279, 108, 4 }, { 278, 109, 18 }, { 252,  57, 10 },  2 },
1311 	{ { 281, 108, 5 }, { 283, 109, 18 }, { 265,  55, 11 },  0 },
1312 	{ { 284, 109, 5 }, { 285, 110, 19 }, { 277,  55, 12 },  0 },
1313 	{ { 287, 110, 5 }, { 288, 111, 20 }, { 288,  54, 13 },  0 },
1314 	{ { 289, 111, 5 }, { 290, 112, 20 }, { 299,  54, 14 },  0 },
1315 	{ { 291, 112, 4 }, { 290, 113, 20 }, { 214,   0, 10 },  0 },
1316 	{ { 293, 113, 3 }, { 295, 114, 17 }, { 214,   0, 10 },  0 },
1317 	{ { 296, 114, 2 }, { 299, 115, 17 }, { 214,   0, 10 },  0 },
1318 	{ { 295, 115, 2 }, { 298, 116, 17 }, { 214,   0, 10 },  0 },
1319 	{ { 293, 116, 1 }, { 297, 117, 17 }, { 214,   0, 10 },  0 },
1320 	{ { 289, 116, 1 }, { 292, 117, 17 }, { 214,   0, 10 },  0 },
1321 	{ { 285, 115, 1 }, { 289, 116, 17 }, { 214,   0, 10 },  0 },
1322 	{ { 281, 114, 1 }, { 284, 115, 17 }, { 214,   0, 10 },  0 },
1323 	{ { 277, 113, 1 }, { 280, 114, 17 }, { 214,   0, 10 },  0 },
1324 	{ { 274, 112, 1 }, { 277, 113, 17 }, { 214,   0, 10 },  0 },
1325 	{ { 271, 111, 1 }, { 274, 112, 17 }, { 214,   0, 10 },  0 },
1326 	{ { 267, 110, 1 }, { 270, 111, 17 }, { 214,   0, 10 },  0 },
1327 	{ { 263, 109, 1 }, { 266, 110, 17 }, { 214,   0, 10 },  0 },
1328 	{ { 260, 108, 1 }, { 263, 109, 17 }, { 214,   0, 10 },  0 },
1329 	{ { 254, 108, 2 }, { 256, 109, 17 }, { 214,   0, 10 },  0 },
1330 	{ { 252, 107, 3 }, { 254, 108, 17 }, { 214,   0, 10 },  0 },
1331 	{ { 253, 108, 3 }, { 255, 109, 17 }, { 214,   0, 10 },  0 },
1332 	{ { 255, 109, 3 }, { 257, 110, 18 }, { 231,  59, 10 },  2 },
1333 	{ { 258, 111, 3 }, { 260, 112, 18 }, { 242,  57, 11 },  0 },
1334 	{ { 263, 112, 4 }, { 262, 113, 19 }, { 256,  57, 12 },  0 },
1335 	{ { 270, 111, 4 }, { 269, 112, 20 }, { 267,  57, 13 },  0 },
1336 	{ { 274, 112, 5 }, { 276, 113, 20 }, { 281,  56, 14 },  0 },
1337 	{ { 280, 111, 6 }, { 282, 112, 19 }, { 214,   0, 10 },  0 },
1338 	{ { 284, 109, 6 }, { 285, 110, 17 }, { 214,   0, 10 },  0 },
1339 	{ { 289, 108, 6 }, { 291, 109, 17 }, { 214,   0, 10 },  0 },
1340 	{ { 294, 107, 6 }, { 296, 108, 17 }, { 214,   0, 10 },  0 },
1341 	{ { 294, 107, 5 }, { 296, 108, 18 }, { 272,  57, 10 },  2 },
1342 	{ { 295, 107, 5 }, { 297, 108, 18 }, { 282,  57, 11 },  0 },
1343 	{ { 296, 108, 5 }, { 298, 109, 19 }, { 295,  57, 12 },  0 },
1344 	{ { 300, 108, 4 }, { 299, 109, 20 }, { 303,  57, 13 },  0 },
1345 	{ { 303, 108, 3 }, { 306, 109, 20 }, { 313,  57, 14 },  0 },
1346 	{ { 307, 109, 2 }, { 311, 110, 17 }, { 214,   0, 10 },  0 },
1347 	{ { 310, 110, 1 }, { 314, 111, 17 }, { 214,   0, 10 }, 99 }
1348 };
1349 
1350 const BamScene::BamDataBlock BamScene::_fight1Data[] = {
1351 	{ {  75,  96,  1 }, { 187, 96, -23 }, {  58,  37, 46 },  0 },
1352 	{ {  75,  96,  2 }, { 187, 96, -23 }, {  58,  37, 46 },  0 },
1353 	{ {  75,  96,  3 }, { 187, 96, -23 }, {  58,  37, 46 },  0 },
1354 	{ {  75,  96,  4 }, { 187, 96, -23 }, {  58,  37, 46 },  0 },
1355 	{ {  75,  96,  1 }, { 187, 96, -23 }, {  58,  37, 46 },  0 },
1356 	{ {  75,  96,  2 }, { 187, 96, -23 }, {  58,  37, 46 },  0 },
1357 	{ {  75,  96,  3 }, { 187, 96, -23 }, {  58,  37, 46 },  0 },
1358 	{ {  75,  96,  4 }, { 187, 96, -24 }, {  58,  37, 46 },  0 },
1359 	{ {  79,  96,  1 }, { 187, 96, -24 }, {  58,  37, 46 },  0 },
1360 	{ {  85,  96,  2 }, { 187, 96, -24 }, {  58,  37, 46 },  0 },
1361 	{ {  94,  96,  3 }, { 187, 96, -24 }, {  58,  37, 46 },  0 },
1362 	{ { 100,  96,  4 }, { 187, 96, -24 }, {  58,  37, 46 },  0 },
1363 	{ { 113,  96,  1 }, { 187, 96, -25 }, {  58,  37, 46 },  0 },
1364 	{ { 121,  96,  1 }, { 187, 96, -25 }, {  58,  37, 46 },  0 },
1365 	{ { 136,  96, 16 }, { 187, 96, -26 }, {  58,  37, 46 },  0 },
1366 	{ { 151,  93,  6 }, { 187, 96, -27 }, {  58,  37, 46 },  0 },
1367 	{ { 159,  83, 16 }, { 187, 96, -28 }, {  58,  37, 46 },  0 },
1368 	{ { 170,  73, 16 }, { 187, 96, -29 }, { 182,  96, 48 },  3 },
1369 	{ { 176,  69, 13 }, { 187, 96, -31 }, { 182,  94, 49 },  1 },
1370 	{ { 168,  66, 13 }, { 187, 98, -32 }, { 182,  92, 50 },  0 },
1371 	{ { 155,  75, 13 }, { 187, 96, -32 }, { 182,  88, 51 },  3 },
1372 	{ { 145,  86, 13 }, { 187, 98, -32 }, { 182,  85, 52 },  0 },
1373 	{ { 127, 104, 13 }, { 187, 98, -32 }, { 182,  25, 52 },  1 },
1374 	{ { 122, 108, 13 }, { 187, 98, -32 }, { 182,  25, 52 },  1 },
1375 	{ { 120, 104, 14 }, { 187, 96, -34 }, { 107, 145, 42 },  2 },
1376 	{ { 111, 103, 13 }, { 187, 96, -23 }, { 107, 144, 43 },  0 },
1377 	{ { 102, 105, 13 }, { 187, 96, -23 }, { 107, 142, 43 },  0 },
1378 	{ {  97, 107, 13 }, { 187, 96, -23 }, { 107, 139, 44 },  0 },
1379 	{ {  92, 101, 14 }, { 187, 96, -23 }, { 107,  34, 47 },  3 },
1380 	{ {  90, 105, 14 }, { 187, 96, -23 }, { 107,  34, 47 },  0 },
1381 	{ {  88, 104, 14 }, { 187, 96, -23 }, { 107,  34, 47 },  0 },
1382 	{ {  87, 105, 14 }, { 187, 96, -23 }, { 107,  34, 47 },  0 },
1383 	{ {  86, 105, 14 }, { 187, 96, -23 }, { 107,  34, 47 },  0 },
1384 	{ {  86, 105, 14 }, { 187, 96, -23 }, { 107,  34, 47 },  0 },
1385 	{ {  86, 105, 15 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1386 	{ {  85,  98, 16 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1387 	{ {  92,  96,  1 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1388 	{ {  92,  96,  1 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1389 	{ {  89,  96,  4 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1390 	{ {  86,  96,  3 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1391 	{ {  83,  96,  2 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1392 	{ {  81,  96,  1 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1393 	{ {  78,  96,  4 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1394 	{ {  75,  96,  3 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1395 	{ {  75,  96,  1 }, { 187, 96, -23 }, {   0,   0,  0 },  0 },
1396 	{ {  75,  96,  1 }, { 187, 96, -23 }, {   0,   0,  0 }, 99 }
1397 };
1398 
1399 const BamScene::BamDataBlock BamScene::_fight2Data[] = {
1400 	{ {  75, 96,  1 }, { 187, 96, -23 }, { 150,  45, 35 },  0 },
1401 	{ {  78, 96,  2 }, { 187, 96, -23 }, { 150,  45, 35 },  0 },
1402 	{ {  81, 96,  3 }, { 189, 96, -18 }, { 150,  45, 35 },  0 },
1403 	{ {  84, 96,  4 }, { 183, 96, -19 }, { 150,  45, 35 },  0 },
1404 	{ {  87, 96,  1 }, { 181, 96, -20 }, { 150,  45, 35 },  0 },
1405 	{ {  90, 96,  2 }, { 177, 96, -21 }, { 150,  45, 35 },  0 },
1406 	{ {  93, 96,  3 }, { 171, 96, -22 }, { 150,  45, 35 },  0 },
1407 	{ {  96, 96,  4 }, { 169, 96, -17 }, { 150,  45, 35 },  0 },
1408 	{ {  99, 96,  1 }, { 165, 96, -18 }, { 150,  45, 35 },  0 },
1409 	{ { 102, 96,  2 }, { 159, 96, -19 }, { 150,  45, 35 },  0 },
1410 	{ { 105, 96,  3 }, { 157, 96, -20 }, { 150,  45, 35 },  0 },
1411 	{ { 108, 96,  4 }, { 153, 96, -21 }, { 150,  45, 35 },  0 },
1412 	{ { 111, 96,  1 }, { 147, 96, -22 }, { 150,  45, 35 },  0 },
1413 	{ { 114, 96,  2 }, { 147, 96, -23 }, { 150,  45, 35 },  0 },
1414 	{ { 117, 96,  3 }, { 147, 96, -23 }, { 150,  45, 35 },  0 },
1415 	{ { 120, 96,  4 }, { 147, 96, -24 }, { 150,  45, 35 },  0 },
1416 	{ { 123, 96,  1 }, { 147, 96, -25 }, { 150,  45, 35 },  0 },
1417 	{ { 125, 96,  2 }, { 147, 96, -25 }, { 150,  45, 35 },  0 },
1418 	{ { 127, 96, 12 }, { 147, 96, -69 }, { 122,  94, 36 },  3 },
1419 	{ { 127, 95, 11 }, { 147, 96, -70 }, { 122,  94, 41 },  0 },
1420 	{ { 127, 96, 12 }, { 147, 96, -71 }, { 122, 100, 36 },  3 },
1421 	{ { 127, 97, 11 }, { 147, 96, -69 }, { 122, 100, 41 },  0 },
1422 	{ { 127, 96, 12 }, { 147, 96, -70 }, { 127, 103, 36 },  3 },
1423 	{ { 127, 95, 11 }, { 147, 96, -71 }, { 127, 103, 41 },  0 },
1424 	{ { 127, 94, 12 }, { 147, 96, -69 }, { 123,  94, 36 },  3 },
1425 	{ { 127, 95, 11 }, { 147, 96, -70 }, { 123,  94, 41 },  0 },
1426 	{ { 127, 96, 12 }, { 147, 96, -71 }, { 120,  99, 36 },  3 },
1427 	{ { 127, 96, 12 }, { 147, 96, -71 }, { 115,  98, 41 },  0 },
1428 	{ { 117, 93, 11 }, { 147, 96, -25 }, { 115, 134, 42 },  0 },
1429 	{ { 110, 92, 11 }, { 147, 96, -25 }, { 114, 133, 42 },  0 },
1430 	{ { 102, 93, 11 }, { 147, 96, -25 }, { 114, 131, 43 },  0 },
1431 	{ {  92, 93, 11 }, { 147, 96, -25 }, { 114, 130, 43 },  0 },
1432 	{ {  82, 94, 11 }, { 147, 96, -25 }, { 114, 128, 44 },  0 },
1433 	{ {  76, 95, 11 }, { 147, 96, -25 }, { 114, 127, 44 },  0 },
1434 	{ {  70, 96, 11 }, { 147, 96, -25 }, { 114, 126, 45 },  0 },
1435 	{ {  75, 96,  5 }, { 147, 96, -25 }, { 114, 125, 46 },  1 },
1436 	{ {  75, 96,  6 }, { 147, 96, -25 }, { 114,  43, 46 },  0 },
1437 	{ {  75, 96,  6 }, { 147, 96, -25 }, { 114,  43, 46 },  0 },
1438 	{ {  75, 96,  5 }, { 147, 96, -25 }, { 114,  43, 46 },  0 },
1439 	{ {  75, 96,  7 }, { 147, 96, -25 }, { 114,  43, 46 },  0 },
1440 	{ {  75, 96, 68 }, { 147, 96, -25 }, { 114,  43, 46 },  0 },
1441 	{ {  75, 96, 68 }, { 147, 96, -25 }, {  89, 104, 36 },  2 },
1442 	{ {  75, 96, 68 }, { 147, 96, -25 }, {  94, 103, 62 },  0 },
1443 	{ {  75, 96, 68 }, { 147, 96, -25 }, { 122, 103, 63 },  0 },
1444 	{ {  75, 96, 68 }, { 147, 96, -25 }, { 141, 103, 64 },  0 },
1445 	{ {  75, 96, 68 }, { 147, 96, -30 }, { 150, 103, 65 },  3 },
1446 	{ {  75, 96, 68 }, { 156, 96, -30 }, { 160, 103, 66 },  0 },
1447 	{ {  75, 96,  7 }, { 164, 96, -30 }, { 169, 103, 67 },  0 },
1448 	{ {  75, 96,  5 }, { 169, 96, -30 }, { 177, 103, 48 },  3 },
1449 	{ {  75, 96,  5 }, { 173, 96, -30 }, { 185, 103, 49 },  0 },
1450 	{ {  75, 96,  6 }, { 178, 96, -30 }, { 198, 103, 50 },  0 },
1451 	{ {  75, 96,  6 }, { 181, 96, -30 }, { 207, 103, 51 },  1 },
1452 	{ {  75, 96,  5 }, { 184, 96, -30 }, { 221, 103, 52 },  0 },
1453 	{ {  75, 96,  5 }, { 186, 96, -30 }, { 224,  53, 53 },  0 },
1454 	{ {  75, 96,  5 }, { 187, 96, -23 }, { 224,  53, 53 }, 99 }
1455 };
1456 
1457 const BamScene::BamDataBlock BamScene::_fight3Data[] = {
1458 	{ {  75, 96,  1 }, { 187,  96, -23 }, { 150,  45, 35 },  0 },
1459 	{ {  77, 96,  2 }, { 187,  96, -22 }, { 150,  45, 35 },  0 },
1460 	{ {  80, 96,  3 }, { 185,  96, -17 }, { 150,  45, 35 },  0 },
1461 	{ {  83, 96,  4 }, { 181,  96, -18 }, { 150,  45, 35 },  0 },
1462 	{ {  86, 96,  1 }, { 175,  96, -19 }, { 150,  45, 35 },  0 },
1463 	{ {  88, 96,  2 }, { 173,  96, -20 }, { 150,  45, 35 },  0 },
1464 	{ {  91, 96,  3 }, { 169,  96, -21 }, { 150,  45, 35 },  0 },
1465 	{ {  94, 96,  4 }, { 163,  96, -22 }, { 150,  45, 35 },  0 },
1466 	{ {  97, 96,  1 }, { 161,  96, -17 }, { 150,  45, 35 },  0 },
1467 	{ {  99, 96,  2 }, { 157,  96, -18 }, { 150,  45, 35 },  0 },
1468 	{ { 102, 96,  3 }, { 151,  96, -19 }, { 150,  45, 35 },  0 },
1469 	{ { 105, 96,  4 }, { 149,  96, -20 }, { 150,  45, 35 },  0 },
1470 	{ { 108, 96,  1 }, { 145,  96, -21 }, { 150,  45, 35 },  0 },
1471 	{ { 110, 96,  2 }, { 145,  96, -25 }, { 150,  45, 35 },  0 },
1472 	{ { 113, 96,  3 }, { 145,  96, -26 }, { 132,  96, 36 },  2 },
1473 	{ { 117, 96,  7 }, { 145,  96, -27 }, { 122,  97, 36 },  0 },
1474 	{ { 117, 96,  7 }, { 145,  96, -28 }, { 117,  97, 37 },  0 },
1475 	{ { 116, 96, 12 }, { 145,  96, -24 }, { 110,  96, 38 },  3 },
1476 	{ { 109, 96, 12 }, { 145,  96, -24 }, { 103,  95, 39 },  0 },
1477 	{ { 105, 96, 12 }, { 145,  96, -24 }, {  95,  90, 40 },  1 },
1478 	{ {  96, 96, 11 }, { 145,  96, -24 }, {  86,  80, 41 },  0 },
1479 	{ {  92, 96, 11 }, { 145,  96, -24 }, {  86,  80, 41 },  0 },
1480 	{ {  93, 96,  5 }, { 145,  96, -24 }, {  86,  38, 41 },  0 },
1481 	{ {  91, 96,  5 }, { 145,  96, -24 }, {  86,  38, 41 },  0 },
1482 	{ {  89, 96,  5 }, { 145,  96, -24 }, {  86,  38, 41 },  0 },
1483 	{ {  88, 96,  5 }, { 145,  96, -24 }, {  86,  38, 41 },  0 },
1484 	{ {  87, 96,  6 }, { 145,  96, -24 }, {  86,  38, 41 },  0 },
1485 	{ {  87, 96,  6 }, { 145,  96, -23 }, {  86,  38, 41 },  0 },
1486 	{ {  87, 96,  6 }, { 145,  96, -23 }, {  86,  38, 41 },  0 },
1487 	{ {  87, 96,  5 }, { 145,  96, -23 }, {  86,  38, 41 },  0 },
1488 	{ {  87, 96,  5 }, { 145,  96, -23 }, {  86,  38, 41 },  0 },
1489 	{ {  87, 96,  6 }, { 145,  96, -23 }, {  86,  38, 41 },  0 },
1490 	{ {  87, 96,  6 }, { 145,  96, -23 }, {  86,  38, 41 },  0 },
1491 	{ {  87, 96,  5 }, { 145,  96, -23 }, {  86,  38, 41 },  0 },
1492 	{ {  87, 96,  5 }, { 145,  96, -23 }, {  86,  38, 41 },  0 },
1493 	{ {  87, 96,  6 }, { 145,  96, -23 }, {  86,  38, 41 },  0 },
1494 	{ {  87, 96,  6 }, { 145,  96, -26 }, {  86,  38, 41 },  0 },
1495 	{ {  87, 96,  6 }, { 145,  96, -27 }, { 132,  97, 36 },  2 },
1496 	{ {  87, 96,  5 }, { 145,  96, -28 }, { 118,  97, 36 },  0 },
1497 	{ {  87, 96,  7 }, { 145,  96, -24 }, { 107,  97, 36 },  0 },
1498 	{ {  87, 96,  8 }, { 145,  96, -24 }, { 101,  97, 36 },  0 },
1499 	{ {  87, 96,  9 }, { 145,  96, -23 }, { 102,  97, 66 },  3 },
1500 	{ {  87, 96, 10 }, { 145,  96, -23 }, { 120,  97, 67 },  0 },
1501 	{ {  87, 96, 10 }, { 145,  96, -30 }, { 139,  97, 67 },  1 },
1502 	{ {  87, 96,  7 }, { 146,  96, -30 }, { 144,  97, 62 },  2 },
1503 	{ {  86, 96,  4 }, { 160,  96, -30 }, { 144,  97, 48 },  1 },
1504 	{ {  83, 96,  3 }, { 170,  96, -31 }, { 154,  93, 49 },  0 },
1505 	{ {  80, 96,  2 }, { 174,  96, -31 }, { 161,  89, 50 },  0 },
1506 	{ {  78, 96,  1 }, { 178,  99, -31 }, { 169,  85, 51 },  0 },
1507 	{ {  75, 96,  4 }, { 183, 104, -31 }, { 175,  79, 52 },  0 },
1508 	{ {  75, 96,  1 }, { 185,  99, -32 }, { 180, 144, 42 },  3 },
1509 	{ {  75, 96,  1 }, { 185, 106, -31 }, { 181, 141, 42 },  0 },
1510 	{ {  75, 96,  5 }, { 185, 104, -31 }, { 181, 138, 43 },  0 },
1511 	{ {  75, 96,  5 }, { 188, 106, -31 }, { 182, 135, 43 },  0 },
1512 	{ {  75, 96,  6 }, { 191,  99, -32 }, { 183, 131, 44 },  3 },
1513 	{ {  75, 96,  6 }, { 191,  99, -32 }, { 183, 127, 45 },  0 },
1514 	{ {  75, 96,  5 }, { 191,  99, -32 }, { 184, 121, 46 },  0 },
1515 	{ {  75, 96,  5 }, { 191,  99, -32 }, { 183, 115, 46 },  0 },
1516 	{ {  75, 96,  6 }, { 191,  99, -32 }, { 183,  41, 47 },  0 },
1517 	{ {  75, 96,  6 }, { 191,  99, -32 }, { 183,  41, 47 },  0 },
1518 	{ {  75, 96,  6 }, { 191,  99, -32 }, { 183,  41, 47 },  0 },
1519 	{ {  75, 96,  5 }, { 191,  99, -32 }, { 183,  41, 47 },  0 },
1520 	{ {  75, 96,  5 }, { 191,  99, -32 }, { 183,  41, 47 },  0 },
1521 	{ {  75, 96,  5 }, { 191,  99, -32 }, { 183,  41, 47 },  0 },
1522 	{ {  75, 96,  5 }, { 191,  99, -32 }, { 183,  41, 47 },  0 },
1523 	{ {  75, 96,  5 }, { 191,  99, -32 }, { 183,  41, 47 },  0 },
1524 	{ {  75, 96,  6 }, { 191,  99, -32 }, { 183,  41, 47 },  0 },
1525 	{ {  75, 96,  6 }, { 191,  99, -32 }, { 183,  41, 47 },  0 },
1526 	{ {  75, 96,  5 }, { 195,  98, -33 }, { 183,  41, 47 },  0 },
1527 	{ {  75, 96,  6 }, { 191,  96, -34 }, { 183,  41, 47 },  0 },
1528 	{ {  75, 96,  6 }, { 193,  96, -25 }, { 183,  41, 47 },  0 },
1529 	{ {  75, 96,  5 }, { 193,  96, -24 }, { 183,  41, 47 },  0 },
1530 	{ {  75, 96,  5 }, { 193,  96, -24 }, { 183,  41, 47 },  0 },
1531 	{ {  75, 96,  5 }, { 193,  96, -24 }, { 183,  41, 47 },  0 },
1532 	{ {  75, 96,  6 }, { 191,  96, -18 }, { 183,  41, 47 },  0 },
1533 	{ {  75, 96,  6 }, { 190,  96, -19 }, { 183,  41, 47 },  0 },
1534 	{ {  75, 96,  6 }, { 187,  96, -20 }, { 183,  41, 47 },  0 },
1535 	{ {  75, 96,  1 }, { 187,  96, -23 }, { 183,  41, 47 },  0 },
1536 	{ {  75, 96,  1 }, { 187,  96, -23 }, { 183,  41, 47 }, 99 }
1537 };
1538 
1539 const BamScene::BamDataBlock BamScene::_fight4Data[] = {
1540 	{ {  75, 96,  1 }, { 187,  96, -23 }, { 150,  45, 35 },  0 },
1541 	{ {  75, 96,  1 }, { 187,  96, -23 }, { 150,  45, 35 },  0 },
1542 	{ {  75, 96,  1 }, { 187,  96, -23 }, { 150,  45, 35 },  0 },
1543 	{ {  75, 96,  5 }, { 187,  96, -23 }, { 150,  45, 35 },  0 },
1544 	{ {  75, 96,  5 }, { 187,  96, -23 }, { 150,  45, 35 },  0 },
1545 	{ {  75, 96,  6 }, { 187,  96, -24 }, { 150,  45, 35 },  0 },
1546 	{ {  75, 96,  6 }, { 187,  96, -24 }, { 150,  45, 35 },  0 },
1547 	{ {  75, 96,  7 }, { 187,  96, -24 }, { 150,  45, 35 },  0 },
1548 	{ {  75, 96,  8 }, { 187,  96, -25 }, {  79, 101, 59 },  0 },
1549 	{ {  75, 96,  9 }, { 187,  96, -25 }, {  95, 104, 66 },  0 },
1550 	{ {  75, 96, 10 }, { 187,  96, -25 }, { 129, 104, 65 },  0 },
1551 	{ {  75, 96, 10 }, { 187,  96, -25 }, { 160, 104, 64 },  0 },
1552 	{ {  75, 96,  6 }, { 187,  96, -25 }, { 179, 104, 63 },  0 },
1553 	{ {  75, 96,  6 }, { 187,  96, -23 }, { 188, 104, 62 },  0 },
1554 	{ {  75, 96,  6 }, { 187,  96, -29 }, { 191, 104, 36 },  0 },
1555 	{ {  75, 96,  6 }, { 187,  96, -29 }, { 195, 104, 37 },  0 },
1556 	{ {  75, 96,  6 }, { 187,  96, -31 }, { 202, 104, 38 },  0 },
1557 	{ {  75, 96,  5 }, { 187,  96, -32 }, { 210, 104, 39 },  0 },
1558 	{ {  75, 96,  5 }, { 187,  98, -32 }, { 216, 104, 40 },  0 },
1559 	{ {  75, 96,  5 }, { 187,  96, -32 }, { 223, 104, 42 },  0 },
1560 	{ {  75, 96,  5 }, { 187,  98, -32 }, { 223, 104, 42 },  0 },
1561 	{ {  75, 96,  5 }, { 187,  97, -33 }, { 223, 104, 42 },  0 },
1562 	{ {  75, 96,  5 }, { 187,  96, -34 }, { 223, 104, 42 },  0 },
1563 	{ {  75, 96,  5 }, { 187,  96, -23 }, { 223, 104, 42 },  0 },
1564 	{ {  75, 96,  5 }, { 187,  96, -23 }, { 223, 104, 42 },  0 },
1565 	{ {  75, 96,  6 }, { 187,  96, -23 }, { 223, 104, 42 },  0 },
1566 	{ {  75, 96,  6 }, { 187,  96, -24 }, { 223, 104, 42 },  0 },
1567 	{ {  75, 96,  6 }, { 187,  96, -24 }, { 223, 104, 42 },  0 },
1568 	{ {  75, 96,  5 }, { 187,  96, -25 }, { 223, 104, 42 },  0 },
1569 	{ {  75, 96,  5 }, { 187,  96, -25 }, { 223, 104, 42 },  0 },
1570 	{ {  75, 96,  5 }, { 187,  96, -26 }, { 175,  98, 36 },  0 },
1571 	{ {  75, 96,  5 }, { 187,  96, -26 }, { 152,  98, 36 },  0 },
1572 	{ {  75, 96,  6 }, { 187,  96, -27 }, { 124,  98, 37 },  0 },
1573 	{ {  75, 96,  6 }, { 187,  96, -28 }, { 105,  98, 38 },  0 },
1574 	{ {  75, 96, 11 }, { 187,  96, -23 }, {  77,  98, 39 },  0 },
1575 	{ {  75, 96, 13 }, { 187,  96, -23 }, {  63,  98, 40 },  0 },
1576 	{ {  75, 96, 14 }, { 187,  96, -23 }, {  51,  98, 41 },  0 },
1577 	{ {  75, 98, 14 }, { 187,  96, -23 }, {  51,  98, 42 },  0 },
1578 	{ {  75, 94, 14 }, { 187,  96, -23 }, {   0,   0,  0 },  0 },
1579 	{ {  75, 98, 14 }, { 187,  96, -23 }, {   0,   0,  0 },  0 },
1580 	{ {  75, 96, 15 }, { 187,  96, -23 }, {   0,   0,  0 },  0 },
1581 	{ {  75, 96,  1 }, { 187,  96, -23 }, {   0,   0,  0 },  0 },
1582 	{ {  75, 96,  1 }, { 187,  96, -23 }, {   0,   0,  0 },  0 },
1583 	{ {  75, 96,  1 }, { 187,  96, -23 }, {   0,   0,  0 },  0 },
1584 	{ {  75, 96,  1 }, { 187,  96, -23 }, {   0,   0,  0 },  0 },
1585 	{ {  75, 96,  1 }, { 187,  96, -23 }, {   0,   0,  0 },  0 },
1586 	{ {  75, 96,  1 }, { 187,  96, -23 }, {   0,   0,  0 },  0 },
1587 	{ {  75, 96,  1 }, { 187,  96, -23 }, {   0,   0,  0 },  0 },
1588 	{ {  75, 96,  1 }, { 187,  96, -23 }, {   0,   0,  0 }, 99 }
1589 };
1590 
1591 } // End of namespace Queen
1592