aboutsummaryrefslogtreecommitdiff
path: root/queen/graphics.cpp
diff options
context:
space:
mode:
authorGregory Montoir2004-01-08 22:46:42 +0000
committerGregory Montoir2004-01-08 22:46:42 +0000
commit1b1ce1faf71f1e7fca9cf030e08bffd343a2bf79 (patch)
tree1ffb8d13a258d8626d0b99fd122b49d276c344fa /queen/graphics.cpp
parent65bfcb71fe7910e16b5e4e0e6665fa3b9e77510e (diff)
downloadscummvm-rg350-1b1ce1faf71f1e7fca9cf030e08bffd343a2bf79.tar.gz
scummvm-rg350-1b1ce1faf71f1e7fca9cf030e08bffd343a2bf79.tar.bz2
scummvm-rg350-1b1ce1faf71f1e7fca9cf030e08bffd343a2bf79.zip
moved the remaining 'graphics' stuff from Logic to Graphics
svn-id: r12266
Diffstat (limited to 'queen/graphics.cpp')
-rw-r--r--queen/graphics.cpp644
1 files changed, 489 insertions, 155 deletions
diff --git a/queen/graphics.cpp b/queen/graphics.cpp
index 3f29442bae..71cce80d91 100644
--- a/queen/graphics.cpp
+++ b/queen/graphics.cpp
@@ -24,6 +24,7 @@
#include "queen/bankman.h"
#include "queen/display.h"
+#include "queen/grid.h"
#include "queen/logic.h"
#include "queen/queen.h"
#include "queen/resource.h"
@@ -501,8 +502,118 @@ void Graphics::bobCustomParallax(uint16 roomNum) {
}
-void Graphics::textCurrentColor(uint8 color) {
- _curTextColor = color;
+void Graphics::bobSetText(
+ BobSlot *pbs,
+ const char *text,
+ int textX, int textY,
+ int color, int flags) {
+ // function MAKE_SPEAK_BOB, lines 335-457 in talk.c
+
+ if (text[0] == '\0')
+ return;
+
+ // debug(0, "makeSpeakBob('%s', (%i,%i), %i, %i, %i, %i);",
+ // text, bob->x, bob->y, textX, textY, color, flags);
+
+ // Duplicate string and append zero if needed
+
+ char textCopy[MAX_STRING_SIZE];
+
+ int length = strlen(text);
+ memcpy(textCopy, text, length);
+
+ if (textCopy[length - 1] >= 'A')
+ textCopy[length++] = '.';
+
+ textCopy[length] = '\0';
+
+ // Split text into lines
+
+ char lines[8][MAX_STRING_SIZE];
+ int lineCount = 0;
+ int wordCount = 0;
+ int lineLength = 0;
+ int i;
+
+ for (i = 0; i < length; i++) {
+ if (textCopy[i] == ' ')
+ wordCount++;
+
+ lineLength++;
+
+ if ((lineLength > 20 && textCopy[i] == ' ') || i == (length-1)) {
+ memcpy(lines[lineCount], textCopy + i + 1 - lineLength, lineLength);
+ lines[lineCount][lineLength] = '\0';
+ lineCount++;
+ lineLength = 0;
+ }
+ }
+
+
+ // Plan: write each line to Screen 2, put black outline around lines and
+ // pick them up as a BOB.
+
+
+ // Find width of widest line
+
+ int maxLineWidth = 0;
+
+ for (i = 0; i < lineCount; i++) {
+ int width = textWidth(lines[i]);
+ if (maxLineWidth < width)
+ maxLineWidth = width;
+ }
+
+ // Calc text position
+
+ short x, y, width, height;
+
+ if (flags) {
+ if (flags == 2)
+ x = 160 - maxLineWidth / 2;
+ else
+ x = textX;
+
+ y = textY;
+
+ width = 0;
+ } else {
+ x = pbs->x;
+ y = pbs->y;
+
+ BobFrame *pbf = _vm->bankMan()->fetchFrame(pbs->frameNum);
+
+ width = (pbf->width * pbs->scale) / 100;
+ height = (pbf->height * pbs->scale) / 100;
+
+ y = y - height - 16 - lineCount * 9;
+ }
+
+ x -= _vm->display()->horizontalScroll();
+
+ if (y < 0) {
+ y = 0;
+
+ if (x < 160)
+ x += width / 2;
+ else
+ x -= width / 2 + maxLineWidth;
+ } else if (!flags)
+ x -= maxLineWidth / 2;
+
+ if (x < 0)
+ x = 4;
+ else if ((x + maxLineWidth) > 320)
+ x = 320 - maxLineWidth - 4;
+
+ textCurrentColor(color);
+
+ for (i = 0; i < lineCount; i++) {
+ int lineX = x + (maxLineWidth - textWidth(lines[i])) / 2;
+
+ //debug(0, "Setting text '%s' at (%i, %i)", lines[i], lineX, y + 9 * i);
+ textSet(lineX, y + 9 * i, lines[i]);
+ }
}
@@ -550,6 +661,30 @@ uint16 Graphics::textWidth(const char* text) const {
}
+int Graphics::textCenterX(const char *text) const {
+ return 160 - textWidth(text) / 2;
+}
+
+
+void Graphics::setupNewRoom(const char *room, uint16 roomNum, int16 *furniture, uint16 furnitureCount) {
+ // reset sprites table (bounding box...)
+ bobClearAll();
+
+ // load/setup objects associated to this room
+ char filename[20];
+ sprintf(filename, "%s.BBK", room);
+ _vm->bankMan()->load(filename, 15);
+
+ _numFrames = 37 + FRAMES_JOE_XTRA;
+ setupRoomFurniture(furniture, furnitureCount);
+ setupRoomObjects();
+
+ if (roomNum >= 90) {
+ putCameraOnBob(0);
+ }
+}
+
+
void Graphics::fillAnimBuffer(const char *anim, AnimFrame *af) {
while (true) {
sscanf(anim, "%3hu,%3hu", &af->frame, &af->speed);
@@ -661,6 +796,8 @@ void Graphics::setupObjectAnim(const GraphicData *gd, uint16 firstImage, uint16
uint16 Graphics::setupPersonAnim(const ActorData *ad, const char *anim, uint16 curImage) {
debug(9, "Graphics::setupPersonAnim(%s, %d)", anim, curImage);
+ _personFrames[ad->bobNum] = curImage + 1;
+
AnimFrame *animFrames = _newAnim[ad->bobNum];
fillAnimBuffer(anim, animFrames);
uint16 frameCount[256];
@@ -727,6 +864,356 @@ void Graphics::eraseAllAnims() {
}
+uint16 Graphics::refreshObject(uint16 obj) {
+ debug(6, "Graphics::refreshObject(%X)", obj);
+ uint16 curImage = _numFrames;
+
+ ObjectData *pod = _vm->logic()->objectData(obj);
+ if (pod->image == 0) {
+ return curImage;
+ }
+
+ // check the object is in the current room
+ if (pod->room != _vm->logic()->currentRoom()) {
+ return curImage;
+ }
+
+ // find bob for the object
+ uint16 curBob = _vm->logic()->findBob(obj);
+ BobSlot *pbs = bob(curBob);
+
+ if (pod->image == -3 || pod->image == -4) {
+ // a person object
+ if (pod->name <= 0) {
+ bobClear(curBob);
+ } else {
+ // find person number
+ uint16 pNum = _vm->logic()->findPersonNumber(obj);
+ curImage = _personFrames[pNum] - 1;
+ if (_personFrames[pNum] == 0) {
+ _personFrames[pNum] = curImage = _numFrames;
+ }
+ curImage = setupPerson(obj - _vm->logic()->currentRoomData(), curImage);
+ }
+ return curImage;
+ }
+
+ // find frame used for object
+ curImage = _vm->logic()->findFrame(obj);
+
+ if (pod->name < 0 || pod->image < 0) {
+ // object is hidden or disabled
+ bobClear(curBob);
+ return curImage;
+ }
+
+ int image = pod->image;
+ if (image > 5000) {
+ image -= 5000;
+ }
+
+ GraphicData *pgd = _vm->logic()->graphicData(image);
+ bool rebound = false;
+ int16 lastFrame = pgd->lastFrame;
+ if (lastFrame < 0) {
+ lastFrame = -lastFrame;
+ rebound = true;
+ }
+ if (pgd->firstFrame < 0) {
+ setupObjectAnim(pgd, curImage, curBob, pod->name != 0);
+ curImage += pgd->lastFrame - 1;
+ } else if (lastFrame != 0) {
+ // turn on an animated bob
+ _vm->bankMan()->unpack(pgd->firstFrame, 2, 15);
+ pbs->animating = false;
+ uint16 firstImage = curImage;
+ --curImage;
+ uint16 j;
+ for (j = pgd->firstFrame; j <= lastFrame; ++j) {
+ ++curImage;
+ _vm->bankMan()->unpack(j, curImage, 15);
+ }
+ pbs->curPos(pgd->x, pgd->y);
+ pbs->frameNum = firstImage;
+ if (pgd->speed > 0) {
+ pbs->animNormal(firstImage, curImage, pgd->speed / 4, rebound, false);
+ }
+ } else {
+ // frame 2 is used as a buffer frame to prevent BOB flickering
+ _vm->bankMan()->unpack(pgd->firstFrame, 2, 15);
+ _vm->bankMan()->unpack(pgd->firstFrame, curImage, 15);
+ pbs->curPos(pgd->x, pgd->y);
+ pbs->frameNum = curImage;
+ }
+
+ return curImage;
+}
+
+
+void Graphics::setupRoomFurniture(int16 *furniture, uint16 furnitureCount) {
+ uint16 i;
+ uint16 curImage = 36 + FRAMES_JOE_XTRA;
+
+ // unpack the furniture from bank 15
+ // there are 3 kinds :
+ // - static (bobs), gamestate range = ]0;5000]
+ // - animated (bobs), gamestate range = ]0;5000]
+ // - static (paste downs), gamestate range = [5000; [
+
+ // unpack the static bobs
+ _numFurnitureStatic = 0;
+ for (i = 1; i <= furnitureCount; ++i) {
+ int16 obj = furniture[i];
+ if (obj > 0 && obj <= 5000) {
+ GraphicData *pgd = _vm->logic()->graphicData(obj);
+ if (pgd->lastFrame == 0) {
+ ++_numFurnitureStatic;
+ ++curImage;
+ _vm->bankMan()->unpack(pgd->firstFrame, curImage, 15);
+ ++_numFrames;
+ BobSlot *pbs = bob(19 + _numFurnitureStatic);
+ pbs->curPos(pgd->x, pgd->y);
+ pbs->frameNum = curImage;
+ }
+ }
+ }
+
+ // unpack the animated bobs
+ _numFurnitureAnimated = 0;
+ _numFurnitureAnimatedLen = 0;
+ uint16 curBob = 0;
+ for (i = 1; i <= furnitureCount; ++i) {
+ int16 obj = furniture[i];
+ if (obj > 0 && obj <= 5000) {
+ GraphicData *pgd = _vm->logic()->graphicData(obj);
+
+ bool rebound = false;
+ int16 lastFrame = pgd->lastFrame;
+ if (lastFrame < 0) {
+ rebound = true;
+ lastFrame = -lastFrame;
+ }
+
+ if (lastFrame > 0) {
+ _numFurnitureAnimatedLen += lastFrame - pgd->firstFrame + 1;
+ ++_numFurnitureAnimated;
+ uint16 image = curImage + 1;
+ int k;
+ for (k = pgd->firstFrame; k <= lastFrame; ++k) {
+ ++curImage;
+ _vm->bankMan()->unpack(k, curImage, 15);
+ ++_numFrames;
+ }
+ BobSlot *pbs = bob(5 + curBob);
+ pbs->animNormal(image, curImage, pgd->speed / 4, rebound, false);
+ pbs->curPos(pgd->x, pgd->y);
+ ++curBob;
+ }
+ }
+ }
+
+ // unpack the paste downs
+ for (i = 1; i <= furnitureCount; ++i) {
+ if (furniture[i] > 5000) {;
+ bobPaste(furniture[i] - 5000, curImage + 1);
+ }
+ }
+}
+
+
+void Graphics::setupRoomObjects() {
+ uint16 i;
+ // furniture frames are reserved in ::setupRoomFurniture(), we append objects
+ // frames after the furniture ones.
+ uint16 curImage = 36 + FRAMES_JOE_XTRA + _numFurnitureStatic + _numFurnitureAnimatedLen;
+ uint16 firstRoomObj = _vm->logic()->currentRoomData() + 1;
+ uint16 lastRoomObj = _vm->logic()->roomData(_vm->logic()->currentRoom() + 1);
+ uint16 numObjectStatic = 0;
+ uint16 numObjectAnimated = 0;
+ uint16 curBob;
+
+ // invalidates all Bobs for persons (except Joe's one)
+ for (i = 1; i <= 3; ++i) {
+ _bobs[i].active = false;
+ }
+
+ // static/animated Bobs
+ for (i = firstRoomObj; i <= lastRoomObj; ++i) {
+ ObjectData *pod = _vm->logic()->objectData(i);
+ // setup blanks bobs for turned off objects (in case
+ // you turn them on again)
+ if (pod->image == -1) {
+ // static OFF Bob
+ curBob = 20 + _numFurnitureStatic + numObjectStatic;
+ ++numObjectStatic;
+ // create a blank frame for the OFF object
+ ++_numFrames;
+ ++curImage;
+ } else if(pod->image == -2) {
+ // animated OFF Bob
+ curBob = 5 + _numFurnitureAnimated + numObjectAnimated;
+ ++numObjectAnimated;
+ } else if(pod->image > 0 && pod->image < 5000) {
+ GraphicData *pgd = _vm->logic()->graphicData(pod->image);
+ int16 lastFrame = pgd->lastFrame;
+ bool rebound = false;
+ if (lastFrame < 0) {
+ lastFrame = -lastFrame;
+ rebound = true;
+ }
+ if (pgd->firstFrame < 0) {
+ // XXX if(TEMPA[1]<0) bobs[CURRBOB].xflip=1;
+ curBob = 5 + _numFurnitureAnimated;
+ setupObjectAnim(pgd, curImage + 1, curBob + numObjectAnimated, pod->name > 0);
+ curImage += pgd->lastFrame;
+ ++numObjectAnimated;
+ } else if (lastFrame != 0) {
+ // animated objects
+ uint16 j;
+ uint16 firstFrame = curImage + 1;
+ for (j = pgd->firstFrame; j <= lastFrame; ++j) {
+ ++curImage;
+ _vm->bankMan()->unpack(j, curImage, 15);
+ ++_numFrames;
+ }
+ curBob = 5 + _numFurnitureAnimated + numObjectAnimated;
+ if (pod->name > 0) {
+ BobSlot *pbs = bob(curBob);
+ pbs->curPos(pgd->x, pgd->y);
+ pbs->frameNum = firstFrame;
+ if (pgd->speed > 0) {
+ pbs->animNormal(firstFrame, curImage, pgd->speed / 4, rebound, false);
+ }
+ }
+ ++numObjectAnimated;
+ } else {
+ // static objects
+ curBob = 20 + _numFurnitureStatic + numObjectStatic;
+ ++curImage;
+ bobClear(curBob);
+
+ // XXX if((COMPANEL==2) && (FULLSCREEN==1)) bobs[CURRBOB].y2=199;
+
+ _vm->bankMan()->unpack(pgd->firstFrame, curImage, 15);
+ ++_numFrames;
+ if (pod->name > 0) {
+ BobSlot *pbs = bob(curBob);
+ pbs->curPos(pgd->x, pgd->y);
+ pbs->frameNum = curImage;
+ }
+ ++numObjectStatic;
+ }
+ }
+ }
+
+ // persons Bobs
+ for (i = firstRoomObj; i <= lastRoomObj; ++i) {
+ ObjectData *pod = _vm->logic()->objectData(i);
+ if (pod->image == -3 || pod->image == -4) {
+ debug(6, "Graphics::setupRoomObjects() - Setting up person %X, name=%X", i, pod->name);
+ uint16 noun = i - _vm->logic()->currentRoomData();
+ if (pod->name > 0) {
+ curImage = setupPerson(noun, curImage);
+ } else {
+ curImage = allocPerson(noun, curImage);
+ }
+ }
+ }
+
+ // paste downs list
+ ++curImage;
+ _numFrames = curImage;
+ for (i = firstRoomObj; i <= lastRoomObj; ++i) {
+ ObjectData *pod = _vm->logic()->objectData(i);
+ if (pod->name > 0 && pod->image > 5000) {
+ bobPaste(pod->image - 5000, curImage);
+ }
+ }
+}
+
+
+uint16 Graphics::setupPerson(uint16 noun, uint16 curImage) {
+ if (noun == 0) {
+ warning("Trying to setup person 0");
+ return curImage;
+ }
+
+ Person p;
+ _vm->logic()->initPerson(noun, "", true, &p);
+
+ const ActorData *pad = p.actor;
+ uint16 scale = 100;
+ uint16 a = _vm->grid()->findAreaForPos(GS_ROOM, pad->x, pad->y);
+ if (a != 0) {
+ // person is not standing in the area box, scale it accordingly
+ scale = _vm->grid()->area(_vm->logic()->currentRoom(), a)->calcScale(pad->y);
+ }
+
+ _vm->bankMan()->unpack(pad->bobFrameStanding, p.bobFrame, p.actor->bankNum);
+ uint16 obj = _vm->logic()->currentRoomData() + noun;
+ BobSlot *pbs = bob(pad->bobNum);
+ pbs->curPos(pad->x, pad->y);
+ pbs->scale = scale;
+ pbs->frameNum = p.bobFrame;
+ pbs->xflip = (_vm->logic()->objectData(obj)->image == -3); // person is facing left
+
+ debug(6, "Graphics::setupPerson(%d, %d) - bob = %d name = %s", noun, curImage, pad->bobNum, p.name);
+
+ if (p.anim != NULL) {
+ curImage = setupPersonAnim(pad, p.anim, curImage);
+ } else {
+ erasePersonAnim(pad->bobNum);
+ }
+ return curImage;
+}
+
+
+uint16 Graphics::allocPerson(uint16 noun, uint16 curImage) {
+ Person p;
+ _vm->logic()->initPerson(noun, "", false, &p);
+ if (p.anim != NULL) {
+ curImage += countAnimFrames(p.anim);
+ _personFrames[p.actor->bobNum] = curImage + 1;
+ }
+ return curImage;
+}
+
+
+void Graphics::update(uint16 room) {
+ bobSortAll();
+ if (_cameraBob >= 0) {
+ _vm->display()->horizontalScrollUpdate(_bobs[_cameraBob].x);
+ }
+ bobCustomParallax(room);
+ _vm->display()->prepareUpdate();
+ bobDrawAll();
+ textDrawAll();
+}
+
+
+
+BamScene::BamScene(QueenEngine *vm)
+ : _flag(F_STOP), _screenShaked(false), _fightData(_fight1Data), _vm(vm) {
+}
+
+
+void BamScene::prepareAnimation() {
+ _obj1 = _vm->graphics()->bob(BOB_OBJ1);
+ _vm->graphics()->bobClear(BOB_OBJ1);
+ _obj1->active = true;
+
+ _obj2 = _vm->graphics()->bob(BOB_OBJ2);
+ _vm->graphics()->bobClear(BOB_OBJ2);
+ _obj2->active = true;
+
+ _objfx = _vm->graphics()->bob(BOB_FX);
+ _vm->graphics()->bobClear(BOB_FX);
+ _objfx->active = true;
+
+ _index = 0;
+}
+
+
void BamScene::updateCarAnimation() {
if (_flag != F_STOP) {
const BamDataBlock *bdb = &_carData[_index];
@@ -821,159 +1308,6 @@ void BamScene::updateFightAnimation() {
}
-void Graphics::update(uint16 room) {
- bobSortAll();
- if (_cameraBob >= 0) {
- _vm->display()->horizontalScrollUpdate(_bobs[_cameraBob].x);
- }
- bobCustomParallax(room);
- _vm->display()->prepareUpdate();
- bobDrawAll();
- textDrawAll();
-}
-
-void Graphics::bobSetText(
- BobSlot *pbs,
- const char *text,
- int textX, int textY,
- int color, int flags) {
- // function MAKE_SPEAK_BOB, lines 335-457 in talk.c
-
- if (text[0] == '\0')
- return;
-
- // debug(0, "makeSpeakBob('%s', (%i,%i), %i, %i, %i, %i);",
- // text, bob->x, bob->y, textX, textY, color, flags);
-
- // Duplicate string and append zero if needed
-
- char textCopy[MAX_STRING_SIZE];
-
- int length = strlen(text);
- memcpy(textCopy, text, length);
-
- if (textCopy[length - 1] >= 'A')
- textCopy[length++] = '.';
-
- textCopy[length] = '\0';
-
- // Split text into lines
-
- char lines[8][MAX_STRING_SIZE];
- int lineCount = 0;
- int wordCount = 0;
- int lineLength = 0;
- int i;
-
- for (i = 0; i < length; i++) {
- if (textCopy[i] == ' ')
- wordCount++;
-
- lineLength++;
-
- if ((lineLength > 20 && textCopy[i] == ' ') || i == (length-1)) {
- memcpy(lines[lineCount], textCopy + i + 1 - lineLength, lineLength);
- lines[lineCount][lineLength] = '\0';
- lineCount++;
- lineLength = 0;
- }
- }
-
-
- // Plan: write each line to Screen 2, put black outline around lines and
- // pick them up as a BOB.
-
-
- // Find width of widest line
-
- int maxLineWidth = 0;
-
- for (i = 0; i < lineCount; i++) {
- int width = textWidth(lines[i]);
- if (maxLineWidth < width)
- maxLineWidth = width;
- }
-
- // Calc text position
-
- short x, y, width, height;
-
- if (flags) {
- if (flags == 2)
- x = 160 - maxLineWidth / 2;
- else
- x = textX;
-
- y = textY;
-
- width = 0;
- } else {
- x = pbs->x;
- y = pbs->y;
-
- BobFrame *pbf = _vm->bankMan()->fetchFrame(pbs->frameNum);
-
- width = (pbf->width * pbs->scale) / 100;
- height = (pbf->height * pbs->scale) / 100;
-
- y = y - height - 16 - lineCount * 9;
- }
-
- x -= _vm->display()->horizontalScroll();
-
- if (y < 0) {
- y = 0;
-
- if (x < 160)
- x += width / 2;
- else
- x -= width / 2 + maxLineWidth;
- } else if (!flags)
- x -= maxLineWidth / 2;
-
- if (x < 0)
- x = 4;
- else if ((x + maxLineWidth) > 320)
- x = 320 - maxLineWidth - 4;
-
- textCurrentColor(color);
-
- for (i = 0; i < lineCount; i++) {
- int lineX = x + (maxLineWidth - textWidth(lines[i])) / 2;
-
- //debug(0, "Setting text '%s' at (%i, %i)", lines[i], lineX, y + 9 * i);
- textSet(lineX, y + 9 * i, lines[i]);
- }
-}
-
-int Graphics::textCenterX(const char *text) const {
- return 160 - textWidth(text) / 2;
-}
-
-
-
-BamScene::BamScene(QueenEngine *vm)
- : _flag(F_STOP), _screenShaked(false), _fightData(_fight1Data), _vm(vm) {
-}
-
-
-void BamScene::prepareAnimation() {
- _obj1 = _vm->graphics()->bob(BOB_OBJ1);
- _vm->graphics()->bobClear(BOB_OBJ1);
- _obj1->active = true;
-
- _obj2 = _vm->graphics()->bob(BOB_OBJ2);
- _vm->graphics()->bobClear(BOB_OBJ2);
- _obj2->active = true;
-
- _objfx = _vm->graphics()->bob(BOB_FX);
- _vm->graphics()->bobClear(BOB_FX);
- _objfx->active = true;
-
- _index = 0;
-}
-
-
const BamScene::BamDataBlock BamScene::_carData[] = {
{ { 310, 105, 1 }, { 314, 106, 17 }, { 366, 101, 1 }, 0 },
{ { 303, 105, 1 }, { 307, 106, 17 }, { 214, 0, 10 }, 0 },