diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/parallaction/exec_ns.cpp | 39 | ||||
-rw-r--r-- | engines/parallaction/graphics.cpp | 164 | ||||
-rw-r--r-- | engines/parallaction/graphics.h | 33 | ||||
-rw-r--r-- | engines/parallaction/parallaction.cpp | 44 | ||||
-rw-r--r-- | engines/parallaction/parallaction.h | 10 |
5 files changed, 245 insertions, 45 deletions
diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index 52e132a56e..1545dc9d07 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -478,49 +478,24 @@ void Parallaction::runCommands(CommandList& list, Zone *z) { } - +// +// ZONE TYPE: EXAMINE +// // displays character head commenting an examined object // -// works on the frontbuffer -// void Parallaction::displayCharacterComment(ExamineData *data) { if (data->_description == NULL) return; - // NOTE: saving visible screen before displaying comment allows - // to restore the exact situation after the comment is deleted. - // This means animations are restored in the exact position as - // they were, thus avoiding clipping effect as signalled in - // BUG item #1762614. - _gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - - _gfx->setFont(_dialogueFont); - _gfx->flatBlitCnv(_char._talk, 0, 190, 80, Gfx::kBitFront); - - int16 v26, v28; - _gfx->getStringExtent(data->_description, 130, &v28, &v26); - Common::Rect r(v28, v26); - r.moveTo(140, 10); - _gfx->drawBalloon(r, 0); - _gfx->displayWrappedString(data->_description, 140, 10, 0, 130); - - waitUntilLeftClick(); + _gfx->setDialogueBalloon(data->_description, 140, 10, 130, 0, 0); + _gfx->setItem(_char._talk, 190, 80); + _gfx->setItemFrame(0, 0); - _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); - _gfx->updateScreen(); - - return; + _inputMode = kInputModeComment; } -// -// ZONE TYPE: EXAMINE -// - // display detail view of an item (and eventually comments) // -// works on the frontbuffer -// - void Parallaction::displayItemComment(ExamineData *data) { if (data->_description == NULL) return; diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index f8c792e148..e40d954f10 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -298,10 +298,40 @@ void Gfx::drawInventory() { g_system->copyRectToScreen(data, r.width(), r.left, r.top, r.width(), r.height()); } +void Gfx::drawItems() { + if (_numItems == 0) { + return; + } + + Graphics::Surface *surf = g_system->lockScreen(); + for (uint i = 0; i < _numItems; i++) { + flatBlit(_items[i].rect, _items[i].data->getData(_items[i].frame), surf, 0); + } + g_system->unlockScreen(); +} + +void Gfx::drawBalloons() { + if (_numBalloons == 0) { + return; + } + + Graphics::Surface *surf = g_system->lockScreen(); + for (uint i = 0; i < _numBalloons; i++) { + Common::Rect r(_balloons[i].surface.w, _balloons[i].surface.h); + r.moveTo(_balloons[i].x, _balloons[i].y); + flatBlit(r, (byte*)_balloons[i].surface.getBasePtr(0, 0), surf, 2); + } + g_system->unlockScreen(); +} + void Gfx::updateScreen() { g_system->copyRectToScreen((const byte*)_buffers[kBitFront]->pixels, _buffers[kBitFront]->pitch, _screenX, _screenY, _vm->_screenWidth, _vm->_screenHeight); drawInventory(); + + drawItems(); + drawBalloons(); + drawLabel(); g_system->updateScreen(); @@ -809,6 +839,8 @@ Gfx::Gfx(Parallaction* vm) : setPalette(_palette); + _numBalloons = 0; + _numItems = 0; _label = 0; _screenX = 0; @@ -872,4 +904,136 @@ void Gfx::freeBuffers() { } +void Gfx::setItem(Frames* frames, uint16 x, uint16 y) { + _items[_numItems].data = frames; + _items[_numItems].x = x; + _items[_numItems].y = y; + _numItems++; +} + +void Gfx::setItemFrame(uint item, uint16 f) { + assert(item < _numItems); + _items[item].frame = f; + _items[item].data->getRect(f, _items[item].rect); + _items[item].rect.moveTo(_items[item].x, _items[item].y); +} + +Gfx::Balloon *Gfx::createBalloon(char *text, uint16 maxwidth, uint16 winding) { + assert(_numBalloons < 5); + + Gfx::Balloon *balloon = &_balloons[_numBalloons]; + _numBalloons++; + + int16 w, h; + getStringExtent(text, maxwidth, &w, &h); + + balloon->surface.create(w + 5, h + 9, 1); + balloon->surface.fillRect(Common::Rect(w + 5, h + 9), 2); + + Common::Rect r(w + 5, h); + balloon->surface.fillRect(r, 0); + r.grow(-1); + balloon->surface.fillRect(r, 1); + + // draws tail + // TODO: this bitmap tail should only be used for Dos games. Amiga should use a polygon fill. + winding = (winding == 0 ? 1 : 0); + Common::Rect s(BALLOON_TAIL_WIDTH, BALLOON_TAIL_HEIGHT); + s.moveTo(r.width()/2 - 5, r.bottom - 1); + flatBlit(s, _resBalloonTail[winding], &balloon->surface, 2); + + return balloon; +} + + +void Gfx::setDialogueBalloon(char *text, uint16 x, uint16 y, uint16 maxwidth, uint16 winding, byte textColor) { + + Common::Rect rect; + + setFont(_vm->_dialogueFont); + Gfx::Balloon *balloon = createBalloon(text, maxwidth, winding); + drawWrappedText(&balloon->surface, text, textColor, maxwidth); + + balloon->x = x; + balloon->y = y; +} + +void Gfx::freeBalloons() { + for (uint i = 0; i < _numBalloons; i++) { + _balloons[i].surface.free(); + } + _numBalloons = 0; +} + +void Gfx::freeItems() { + _numItems = 0; +} + +void Gfx::hideDialogueStuff() { + freeItems(); + freeBalloons(); +} + +void Gfx::drawText(Graphics::Surface* surf, uint16 x, uint16 y, const char *text, byte color) { + byte *dst = (byte*)surf->getBasePtr(x, y); + _font->setColor(color); + _font->drawString(dst, surf->w, text); +} + +bool Gfx::drawWrappedText(Graphics::Surface* surf, char *text, byte color, int16 wrapwidth) { + + uint16 lines = 0; + bool rv = false; + uint16 linewidth = 0; + + uint16 rx = 10; + uint16 ry = 4; + + char token[40]; + + if (wrapwidth == -1) + wrapwidth = _vm->_screenWidth; + + while (strlen(text) > 0) { + + text = parseNextToken(text, token, 40, " ", true); + + if (!scumm_stricmp(token, "%p")) { + lines++; + rx = 10; + ry = 4 + lines*10; // y + + strcpy(token, "> ......."); + strncpy(token+2, _password, strlen(_password)); + rv = true; + } else { + + linewidth += getStringWidth(token); + + if (linewidth > wrapwidth) { + // wrap line + lines++; + rx = 10; // x + ry = 4 + lines*10; // y + linewidth = getStringWidth(token); + } + + if (!scumm_stricmp(token, "%s")) { + sprintf(token, "%d", _score); + } + + } + + drawText(surf, rx, ry, token, color); + + rx += getStringWidth(token) + getStringWidth(" "); + linewidth += getStringWidth(" "); + + text = Common::ltrim(text); + } + + return rv; + +} + } // namespace Parallaction diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 9476edb517..2bc17f0b77 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -231,6 +231,12 @@ public: void backupGetBackground(GetData *data, int16 x, int16 y); void restoreGetBackground(const Common::Rect& r, byte *data); + void setDialogueBalloon(char *text, uint16 x, uint16 y, uint16 maxwidth, uint16 winding, byte textColor); + void setItem(Frames* frames, uint16 x, uint16 y); + void setItemFrame(uint item, uint16 f); + void hideDialogueStuff(); + void freeBalloons(); + void freeItems(); // low level surfaces void clearScreen(Gfx::Buffers buffer); @@ -280,14 +286,41 @@ protected: bool _halfbrite; protected: + struct Balloon { + uint16 x; + uint16 y; + uint16 winding; + Graphics::Surface surface; + } _balloons[5]; + + uint _numBalloons; + + struct Item { + uint16 x; + uint16 y; + uint16 frame; + Frames *data; + + Common::Rect rect; + } _items[2]; + + uint _numItems; + void drawInventory(); void drawLabel(); + void drawItems(); + void drawBalloons(); + void initBuffers(int w, int h); void freeBuffers(); void copyRect(uint width, uint height, byte *dst, uint dstPitch, byte *src, uint srcPitch); + Balloon *createBalloon(char *text, uint16 maxwidth, uint16 winding); + + void drawText(Graphics::Surface* surf, uint16 x, uint16 y, const char *text, byte color); + bool drawWrappedText(Graphics::Surface* surf, char *text, byte color, int16 wrapwidth); void blit(const Common::Rect& r, uint16 z, byte *data, Graphics::Surface *surf); void flatBlit(const Common::Rect& r, byte *data, Graphics::Surface *surf, byte transparentColor); }; diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index 1dd377b9a3..5031e7be22 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -270,6 +270,8 @@ void waitUntilLeftClick() { void Parallaction::runGame() { + _inputMode = kInputModeGame; + while ((_engineFlags & kEngineQuit) == 0) { updateInput(); @@ -283,14 +285,13 @@ void Parallaction::runGame() { changeLocation(_location._name); } - eraseAnimations(); - - runScripts(); - walk(); - - runJobs(); - - drawAnimations(); + if (_inputMode == kInputModeGame) { + eraseAnimations(); + runScripts(); + walk(); + runJobs(); + drawAnimations(); + } updateView(); @@ -387,11 +388,7 @@ void Parallaction::processInput(InputData *data) { - - - - -void Parallaction::updateInput() { +void Parallaction::updateGameInput() { int16 keyDown = readInput(); @@ -429,6 +426,27 @@ void Parallaction::updateInput() { if (_input._event != kEvNone) processInput(&_input); +} + +void Parallaction::updateCommentInput() { + waitUntilLeftClick(); + + _gfx->hideDialogueStuff(); + _inputMode = kInputModeGame; +} + +void Parallaction::updateInput() { + + switch (_inputMode) { + case kInputModeComment: + updateCommentInput(); + break; + + case kInputModeGame: + updateGameInput(); + break; + } + return; } diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 874c5cb1b6..f6749d908f 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -376,6 +376,16 @@ public: void waitTime(uint32 t); + enum { + kInputModeGame = 0, + kInputModeComment = 1 + }; + + int _inputMode; + + void updateGameInput(); + void updateCommentInput(); + uint _lookup; Common::Stack<OpcodeSet*> _opcodes; Common::Stack<Table*> _statements; |