diff options
author | Gregory Montoir | 2004-01-08 22:46:42 +0000 |
---|---|---|
committer | Gregory Montoir | 2004-01-08 22:46:42 +0000 |
commit | 1b1ce1faf71f1e7fca9cf030e08bffd343a2bf79 (patch) | |
tree | 1ffb8d13a258d8626d0b99fd122b49d276c344fa /queen/graphics.cpp | |
parent | 65bfcb71fe7910e16b5e4e0e6665fa3b9e77510e (diff) | |
download | scummvm-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.cpp | 644 |
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 }, |