mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-28 04:34:50 +00:00
8bdbbaf413
svn-id: r33432
729 lines
18 KiB
C++
729 lines
18 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
#include "common/util.h"
|
|
|
|
#include "parallaction/graphics.h"
|
|
#include "parallaction/parallaction.h"
|
|
|
|
namespace Parallaction {
|
|
|
|
|
|
#define BALLOON_TRANSPARENT_COLOR_NS 2
|
|
#define BALLOON_TRANSPARENT_COLOR_BR 0
|
|
|
|
#define BALLOON_TAIL_WIDTH 12
|
|
#define BALLOON_TAIL_HEIGHT 10
|
|
|
|
|
|
byte _resBalloonTail[2][BALLOON_TAIL_WIDTH*BALLOON_TAIL_HEIGHT] = {
|
|
{
|
|
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02,
|
|
0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02,
|
|
0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
|
|
0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
|
|
0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
|
|
0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02,
|
|
0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
|
|
0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
|
0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
|
0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
|
},
|
|
{
|
|
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02,
|
|
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x02,
|
|
0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
|
|
0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
|
|
0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
|
0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
|
|
0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x02,
|
|
0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02,
|
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02,
|
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02
|
|
}
|
|
};
|
|
|
|
class BalloonManager_ns : public BalloonManager {
|
|
|
|
static int16 _dialogueBalloonX[5];
|
|
|
|
struct Balloon {
|
|
Common::Rect outerBox;
|
|
Common::Rect innerBox;
|
|
Graphics::Surface *surface;
|
|
GfxObj *obj;
|
|
} _intBalloons[5];
|
|
|
|
uint _numBalloons;
|
|
|
|
void getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height);
|
|
void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth);
|
|
int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness);
|
|
Balloon *getBalloon(uint id);
|
|
|
|
Gfx *_gfx;
|
|
|
|
public:
|
|
BalloonManager_ns(Gfx *gfx);
|
|
~BalloonManager_ns();
|
|
|
|
void freeBalloons();
|
|
int setLocationBalloon(char *text, bool endGame);
|
|
int setDialogueBalloon(char *text, uint16 winding, byte textColor);
|
|
int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor);
|
|
void setBalloonText(uint id, char *text, byte textColor);
|
|
int hitTestDialogueBalloon(int x, int y);
|
|
};
|
|
|
|
int16 BalloonManager_ns::_dialogueBalloonX[5] = { 80, 120, 150, 150, 150 };
|
|
|
|
BalloonManager_ns::BalloonManager_ns(Gfx *gfx) : _numBalloons(0), _gfx(gfx) {
|
|
|
|
}
|
|
|
|
BalloonManager_ns::~BalloonManager_ns() {
|
|
|
|
}
|
|
|
|
|
|
BalloonManager_ns::Balloon* BalloonManager_ns::getBalloon(uint id) {
|
|
assert(id < _numBalloons);
|
|
return &_intBalloons[id];
|
|
}
|
|
|
|
int BalloonManager_ns::createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness) {
|
|
assert(_numBalloons < 5);
|
|
|
|
int id = _numBalloons;
|
|
|
|
Balloon *balloon = &_intBalloons[id];
|
|
|
|
int16 real_h = (winding == -1) ? h : h + 9;
|
|
balloon->surface = new Graphics::Surface;
|
|
balloon->surface->create(w, real_h, 1);
|
|
balloon->surface->fillRect(Common::Rect(w, real_h), BALLOON_TRANSPARENT_COLOR_NS);
|
|
|
|
Common::Rect r(w, h);
|
|
balloon->surface->fillRect(r, 0);
|
|
balloon->outerBox = r;
|
|
|
|
r.grow(-borderThickness);
|
|
balloon->surface->fillRect(r, 1);
|
|
balloon->innerBox = r;
|
|
|
|
if (winding != -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);
|
|
_gfx->blt(s, _resBalloonTail[winding], balloon->surface, LAYER_FOREGROUND, BALLOON_TRANSPARENT_COLOR_NS);
|
|
}
|
|
|
|
_numBalloons++;
|
|
|
|
return id;
|
|
}
|
|
|
|
|
|
int BalloonManager_ns::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) {
|
|
|
|
int16 w, h;
|
|
|
|
getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
|
|
|
|
int id = createBalloon(w+5, h, winding, 1);
|
|
Balloon *balloon = &_intBalloons[id];
|
|
|
|
drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
|
|
|
|
// TODO: extract some text to make a name for obj
|
|
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
|
|
balloon->obj->x = x;
|
|
balloon->obj->y = y;
|
|
balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_NS;
|
|
|
|
return id;
|
|
}
|
|
|
|
int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, byte textColor) {
|
|
|
|
int16 w, h;
|
|
|
|
getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
|
|
|
|
int id = createBalloon(w+5, h, winding, 1);
|
|
Balloon *balloon = &_intBalloons[id];
|
|
|
|
drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
|
|
|
|
// TODO: extract some text to make a name for obj
|
|
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
|
|
balloon->obj->x = _dialogueBalloonX[id];
|
|
balloon->obj->y = 10;
|
|
balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_NS;
|
|
|
|
if (id > 0) {
|
|
balloon->obj->y += _intBalloons[id - 1].obj->y + _intBalloons[id - 1].outerBox.height();
|
|
}
|
|
|
|
|
|
return id;
|
|
}
|
|
|
|
void BalloonManager_ns::setBalloonText(uint id, char *text, byte textColor) {
|
|
Balloon *balloon = getBalloon(id);
|
|
balloon->surface->fillRect(balloon->innerBox, 1);
|
|
drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
|
|
}
|
|
|
|
|
|
int BalloonManager_ns::setLocationBalloon(char *text, bool endGame) {
|
|
|
|
int16 w, h;
|
|
|
|
getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
|
|
|
|
int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR_NS);
|
|
Balloon *balloon = &_intBalloons[id];
|
|
drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH);
|
|
|
|
// TODO: extract some text to make a name for obj
|
|
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
|
|
balloon->obj->x = 5;
|
|
balloon->obj->y = 5;
|
|
balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_NS;
|
|
|
|
return id;
|
|
}
|
|
|
|
int BalloonManager_ns::hitTestDialogueBalloon(int x, int y) {
|
|
|
|
Common::Point p;
|
|
|
|
for (uint i = 0; i < _numBalloons; i++) {
|
|
p.x = x - _intBalloons[i].obj->x;
|
|
p.y = y - _intBalloons[i].obj->y;
|
|
|
|
if (_intBalloons[i].innerBox.contains(p))
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void BalloonManager_ns::freeBalloons() {
|
|
_gfx->destroyBalloons();
|
|
|
|
for (uint i = 0; i < _numBalloons; i++) {
|
|
_intBalloons[i].obj = 0;
|
|
_intBalloons[i].surface = 0; // no need to delete surface, since it is done by destroyBalloons
|
|
}
|
|
|
|
_numBalloons = 0;
|
|
}
|
|
|
|
void BalloonManager_ns::drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth) {
|
|
|
|
uint16 lines = 0;
|
|
uint16 linewidth = 0;
|
|
|
|
uint16 rx = 10;
|
|
uint16 ry = 4;
|
|
|
|
uint16 blankWidth = font->getStringWidth(" ");
|
|
uint16 tokenWidth = 0;
|
|
|
|
char token[MAX_TOKEN_LEN];
|
|
|
|
if (wrapwidth == -1)
|
|
wrapwidth = _vm->_screenWidth;
|
|
|
|
while (strlen(text) > 0) {
|
|
|
|
text = parseNextToken(text, token, MAX_TOKEN_LEN, " ", true);
|
|
|
|
if (!scumm_stricmp(token, "%p")) {
|
|
lines++;
|
|
rx = 10;
|
|
ry = 4 + lines*10; // y
|
|
|
|
strcpy(token, "> .......");
|
|
strncpy(token+2, _password, strlen(_password));
|
|
tokenWidth = font->getStringWidth(token);
|
|
} else {
|
|
tokenWidth = font->getStringWidth(token);
|
|
|
|
linewidth += tokenWidth;
|
|
|
|
if (linewidth > wrapwidth) {
|
|
// wrap line
|
|
lines++;
|
|
rx = 10; // x
|
|
ry = 4 + lines*10; // y
|
|
linewidth = tokenWidth;
|
|
}
|
|
|
|
if (!scumm_stricmp(token, "%s")) {
|
|
sprintf(token, "%d", _score);
|
|
}
|
|
|
|
}
|
|
|
|
_gfx->drawText(font, surf, rx, ry, token, color);
|
|
|
|
rx += tokenWidth + blankWidth;
|
|
linewidth += blankWidth;
|
|
|
|
text = Common::ltrim(text);
|
|
}
|
|
|
|
}
|
|
|
|
void BalloonManager_ns::getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height) {
|
|
|
|
uint16 lines = 0;
|
|
uint16 w = 0;
|
|
*width = 0;
|
|
|
|
uint16 blankWidth = font->getStringWidth(" ");
|
|
uint16 tokenWidth = 0;
|
|
|
|
char token[MAX_TOKEN_LEN];
|
|
|
|
while (strlen(text) != 0) {
|
|
|
|
text = parseNextToken(text, token, MAX_TOKEN_LEN, " ", true);
|
|
tokenWidth = font->getStringWidth(token);
|
|
|
|
w += tokenWidth;
|
|
|
|
if (!scumm_stricmp(token, "%p")) {
|
|
lines++;
|
|
} else {
|
|
if (w > maxwidth) {
|
|
w -= tokenWidth;
|
|
lines++;
|
|
if (w > *width)
|
|
*width = w;
|
|
|
|
w = tokenWidth;
|
|
}
|
|
}
|
|
|
|
w += blankWidth;
|
|
text = Common::ltrim(text);
|
|
}
|
|
|
|
if (*width < w) *width = w;
|
|
*width += 10;
|
|
|
|
*height = lines * 10 + 20;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class BalloonManager_br : public BalloonManager {
|
|
|
|
struct Balloon {
|
|
Common::Rect box;
|
|
Graphics::Surface *surface;
|
|
GfxObj *obj;
|
|
} _intBalloons[3];
|
|
|
|
uint _numBalloons;
|
|
|
|
Disk *_disk;
|
|
Gfx *_gfx;
|
|
|
|
Frames *_leftBalloon;
|
|
Frames *_rightBalloon;
|
|
|
|
void cacheAnims();
|
|
void getStringExtent(Font *font, const char *text, uint16 maxwidth, int16* width, int16* height);
|
|
void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth);
|
|
int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness);
|
|
Balloon *getBalloon(uint id);
|
|
Graphics::Surface *expandBalloon(Frames *data, int frameNum);
|
|
|
|
void textSetupRendering(const Common::String &text, Graphics::Surface *dest, Font *font, byte color);
|
|
void textEmitCenteredLine();
|
|
void textAccum(const Common::String &token, uint16 width);
|
|
void textNewLine();
|
|
|
|
Common::String _textLine;
|
|
Graphics::Surface *_textSurf;
|
|
Font *_textFont;
|
|
uint16 _textX, _textY;
|
|
byte _textColor;
|
|
uint16 _textLines, _textWidth;
|
|
|
|
void extentSetup(Font *font, int16 *width, int16 *height);
|
|
void extentAction();
|
|
|
|
int16 *_extentWidth, *_extentHeight;
|
|
|
|
|
|
public:
|
|
BalloonManager_br(Disk *disk, Gfx *gfx);
|
|
~BalloonManager_br();
|
|
|
|
void freeBalloons();
|
|
int setLocationBalloon(char *text, bool endGame);
|
|
int setDialogueBalloon(char *text, uint16 winding, byte textColor);
|
|
int setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor);
|
|
void setBalloonText(uint id, char *text, byte textColor);
|
|
int hitTestDialogueBalloon(int x, int y);
|
|
};
|
|
|
|
|
|
|
|
BalloonManager_br::Balloon* BalloonManager_br::getBalloon(uint id) {
|
|
assert(id < _numBalloons);
|
|
return &_intBalloons[id];
|
|
}
|
|
|
|
Graphics::Surface *BalloonManager_br::expandBalloon(Frames *data, int frameNum) {
|
|
|
|
Common::Rect rect;
|
|
data->getRect(frameNum, rect);
|
|
|
|
rect.translate(-rect.left, -rect.top);
|
|
|
|
Graphics::Surface *surf = new Graphics::Surface;
|
|
surf->create(rect.width(), rect.height(), 1);
|
|
|
|
_gfx->unpackBlt(rect, data->getData(frameNum), data->getRawSize(frameNum), surf, 0, BALLOON_TRANSPARENT_COLOR_BR);
|
|
|
|
return surf;
|
|
}
|
|
|
|
int BalloonManager_br::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 winding, byte textColor) {
|
|
cacheAnims();
|
|
|
|
int id = _numBalloons;
|
|
Frames *src = 0;
|
|
int srcFrame = 0;
|
|
|
|
Balloon *balloon = &_intBalloons[id];
|
|
|
|
if (winding == 0) {
|
|
src = _rightBalloon;
|
|
srcFrame = 0;
|
|
} else
|
|
if (winding == 1) {
|
|
src = _leftBalloon;
|
|
srcFrame = 0;
|
|
}
|
|
|
|
assert(src);
|
|
|
|
balloon->surface = expandBalloon(src, srcFrame);
|
|
src->getRect(srcFrame, balloon->box);
|
|
|
|
drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
|
|
|
|
// TODO: extract some text to make a name for obj
|
|
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
|
|
balloon->obj->x = x + balloon->box.left;
|
|
balloon->obj->y = y + balloon->box.top;
|
|
balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_BR;
|
|
|
|
printf("balloon (%i, %i)\n", balloon->obj->x, balloon->obj->y);
|
|
|
|
_numBalloons++;
|
|
|
|
return id;
|
|
}
|
|
|
|
int BalloonManager_br::setDialogueBalloon(char *text, uint16 winding, byte textColor) {
|
|
cacheAnims();
|
|
|
|
int id = _numBalloons;
|
|
Frames *src = 0;
|
|
int srcFrame = 0;
|
|
|
|
Balloon *balloon = &_intBalloons[id];
|
|
|
|
if (winding == 0) {
|
|
src = _rightBalloon;
|
|
srcFrame = id;
|
|
} else
|
|
if (winding == 1) {
|
|
src = _leftBalloon;
|
|
srcFrame = 0;
|
|
}
|
|
|
|
assert(src);
|
|
|
|
balloon->surface = expandBalloon(src, srcFrame);
|
|
src->getRect(srcFrame, balloon->box);
|
|
|
|
drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
|
|
|
|
// TODO: extract some text to make a name for obj
|
|
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
|
|
balloon->obj->x = balloon->box.left;
|
|
balloon->obj->y = balloon->box.top;
|
|
balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_BR;
|
|
|
|
if (id > 0) {
|
|
balloon->obj->y += _intBalloons[id - 1].obj->y + _intBalloons[id - 1].box.height();
|
|
}
|
|
|
|
_numBalloons++;
|
|
|
|
return id;
|
|
}
|
|
|
|
void BalloonManager_br::setBalloonText(uint id, char *text, byte textColor) { }
|
|
|
|
int BalloonManager_br::setLocationBalloon(char *text, bool endGame) {
|
|
/*
|
|
int16 w, h;
|
|
|
|
getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
|
|
|
|
int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR);
|
|
Balloon *balloon = &_intBalloons[id];
|
|
drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH);
|
|
|
|
// TODO: extract some text to make a name for obj
|
|
balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0);
|
|
balloon->obj->x = 5;
|
|
balloon->obj->y = 5;
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
int BalloonManager_br::hitTestDialogueBalloon(int x, int y) {
|
|
|
|
Common::Point p;
|
|
|
|
for (uint i = 0; i < _numBalloons; i++) {
|
|
p.x = x - _intBalloons[i].obj->x;
|
|
p.y = y - _intBalloons[i].obj->y;
|
|
|
|
if (_intBalloons[i].box.contains(p))
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void BalloonManager_br::freeBalloons() {
|
|
_gfx->destroyBalloons();
|
|
|
|
for (uint i = 0; i < _numBalloons; i++) {
|
|
_intBalloons[i].obj = 0;
|
|
_intBalloons[i].surface = 0; // no need to delete surface, since it is done by destroyBalloons
|
|
}
|
|
|
|
_numBalloons = 0;
|
|
}
|
|
|
|
void BalloonManager_br::cacheAnims() {
|
|
if (!_leftBalloon) {
|
|
_leftBalloon = _disk->loadFrames("fumetto.ani");
|
|
_rightBalloon = _disk->loadFrames("fumdx.ani");
|
|
}
|
|
}
|
|
|
|
|
|
void BalloonManager_br::extentSetup(Font *font, int16 *width, int16 *height) {
|
|
_extentWidth = width;
|
|
_extentHeight = height;
|
|
|
|
_textLine.clear();
|
|
_textLines = 0;
|
|
_textWidth = 0;
|
|
_textFont = font;
|
|
}
|
|
|
|
void BalloonManager_br::extentAction() {
|
|
if (_textWidth > *_extentWidth) {
|
|
*_extentWidth = _textWidth;
|
|
}
|
|
*_extentHeight = _textLines * _textFont->height();
|
|
}
|
|
|
|
void BalloonManager_br::textSetupRendering(const Common::String &text, Graphics::Surface *dest, Font *font, byte color) {
|
|
uint16 maxWidth = 216;
|
|
|
|
int16 w, h;
|
|
getStringExtent(font, text.c_str(), maxWidth, &w, &h);
|
|
|
|
w += 10;
|
|
h += 12;
|
|
|
|
_textLine.clear();
|
|
_textSurf = dest;
|
|
_textFont = font;
|
|
_textX = 0;
|
|
_textY = (_textSurf->h - h) / 2;
|
|
_textColor = color;
|
|
_textLines = 0;
|
|
_textWidth = 0;
|
|
}
|
|
|
|
void BalloonManager_br::textEmitCenteredLine() {
|
|
if (_textLine.empty()) {
|
|
return;
|
|
}
|
|
uint16 rx = _textX + (_textSurf->w - _textWidth) / 2;
|
|
uint16 ry = _textY + _textLines * _textFont->height(); // y
|
|
_gfx->drawText(_textFont, _textSurf, rx, ry, _textLine.c_str(), _textColor);
|
|
}
|
|
|
|
void BalloonManager_br::textAccum(const Common::String &token, uint16 width) {
|
|
if (token.empty()) {
|
|
return;
|
|
}
|
|
|
|
_textWidth += width;
|
|
_textLine += token;
|
|
}
|
|
|
|
void BalloonManager_br::textNewLine() {
|
|
_textLines++;
|
|
_textWidth = 0;
|
|
_textLine.clear();
|
|
}
|
|
|
|
|
|
// TODO: really, base this and getStringExtent on some kind of LineTokenizer, instead of
|
|
// repeating the algorithm and changing a couple of lines.
|
|
void BalloonManager_br::drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapWidth) {
|
|
textSetupRendering(text, surf, font, color);
|
|
|
|
wrapWidth = 216;
|
|
|
|
Common::StringTokenizer tokenizer(text, " ");
|
|
Common::String token;
|
|
Common::String blank(" ");
|
|
|
|
uint16 blankWidth = font->getStringWidth(" ");
|
|
uint16 tokenWidth = 0;
|
|
|
|
while (!tokenizer.empty()) {
|
|
token = tokenizer.nextToken();
|
|
|
|
if (token == '/') {
|
|
tokenWidth = 0;
|
|
textEmitCenteredLine();
|
|
textNewLine();
|
|
} else {
|
|
// todo: expand '%'
|
|
tokenWidth = font->getStringWidth(token.c_str());
|
|
|
|
if (_textWidth == 0) {
|
|
textAccum(token, tokenWidth);
|
|
} else {
|
|
if (_textWidth + blankWidth + tokenWidth <= wrapWidth) {
|
|
textAccum(blank, blankWidth);
|
|
textAccum(token, tokenWidth);
|
|
} else {
|
|
textEmitCenteredLine();
|
|
textNewLine();
|
|
textAccum(token, tokenWidth);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
textEmitCenteredLine();
|
|
}
|
|
|
|
|
|
|
|
void BalloonManager_br::getStringExtent(Font *font, const char *text, uint16 maxwidth, int16* width, int16* height) {
|
|
extentSetup(font, width, height);
|
|
|
|
Common::StringTokenizer tokenizer(text, " ");
|
|
Common::String token;
|
|
Common::String blank(" ");
|
|
|
|
uint16 blankWidth = font->getStringWidth(" ");
|
|
uint16 tokenWidth = 0;
|
|
|
|
while (!tokenizer.empty()) {
|
|
token = tokenizer.nextToken();
|
|
|
|
if (token == '/') {
|
|
tokenWidth = 0;
|
|
extentAction();
|
|
textNewLine();
|
|
} else {
|
|
// todo: expand '%'
|
|
tokenWidth = font->getStringWidth(token.c_str());
|
|
|
|
if (_textWidth == 0) {
|
|
textAccum(token, tokenWidth);
|
|
} else {
|
|
if (_textWidth + blankWidth + tokenWidth <= maxwidth) {
|
|
textAccum(blank, blankWidth);
|
|
textAccum(token, tokenWidth);
|
|
} else {
|
|
extentAction();
|
|
textNewLine();
|
|
textAccum(token, tokenWidth);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extentAction();
|
|
}
|
|
|
|
|
|
|
|
|
|
BalloonManager_br::BalloonManager_br(Disk *disk, Gfx *gfx) : _numBalloons(0), _disk(disk), _gfx(gfx), _leftBalloon(0), _rightBalloon(0) {
|
|
}
|
|
|
|
BalloonManager_br::~BalloonManager_br() {
|
|
delete _leftBalloon;
|
|
delete _rightBalloon;
|
|
}
|
|
|
|
void Parallaction::setupBalloonManager() {
|
|
if (_vm->getGameType() == GType_Nippon) {
|
|
_balloonMan = new BalloonManager_ns(_vm->_gfx);
|
|
} else
|
|
if (_vm->getGameType() == GType_BRA) {
|
|
_balloonMan = new BalloonManager_br(_vm->_disk, _vm->_gfx);
|
|
} else {
|
|
error("Unknown game type");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} // namespace Parallaction
|