aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/parallaction/exec_ns.cpp39
-rw-r--r--engines/parallaction/graphics.cpp164
-rw-r--r--engines/parallaction/graphics.h33
-rw-r--r--engines/parallaction/parallaction.cpp44
-rw-r--r--engines/parallaction/parallaction.h10
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;