aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction/graphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/parallaction/graphics.cpp')
-rw-r--r--engines/parallaction/graphics.cpp784
1 files changed, 228 insertions, 556 deletions
diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp
index 58fb02a750..c19d6ae5e5 100644
--- a/engines/parallaction/graphics.cpp
+++ b/engines/parallaction/graphics.cpp
@@ -33,6 +33,11 @@
namespace Parallaction {
+// this is the size of the receiving buffer for unpacked frames,
+// since BRA uses some insanely big animations.
+#define MAXIMUM_UNPACKED_BITMAP_SIZE 640*401
+
+
void Gfx::registerVar(const Common::String &name, int32 initialValue) {
if (_vars.contains(name)) {
warning("Variable '%s' already registered, ignoring initial value.\n", name.c_str());
@@ -64,10 +69,6 @@ int32 Gfx::getVar(const Common::String &name) {
#define LABEL_TRANSPARENT_COLOR 0xFF
-#define BALLOON_TRANSPARENT_COLOR 2
-
-
-int16 Gfx::_dialogueBalloonX[5] = { 80, 120, 150, 150, 150 };
void halfbritePixel(int x, int y, int color, void *data) {
byte *buffer = (byte*)data;
@@ -152,6 +153,13 @@ void Palette::setEntry(uint index, int red, int green, int blue) {
_data[index*3+2] = blue & 0xFF;
}
+void Palette::getEntry(uint index, int &red, int &green, int &blue) {
+ assert(index < _colors);
+ red = _data[index*3];
+ green = _data[index*3+1];
+ blue = _data[index*3+2];
+}
+
void Palette::makeGrayscale() {
byte v;
for (uint16 i = 0; i < _colors; i++) {
@@ -238,37 +246,6 @@ void Palette::rotate(uint first, uint last, bool forward) {
}
-#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
- }
-};
-
void Gfx::setPalette(Palette pal) {
byte sysPal[256*4];
@@ -292,7 +269,7 @@ void Gfx::animatePalette() {
PaletteFxRange *range;
for (uint16 i = 0; i < 4; i++) {
- range = &_backgroundInfo.ranges[i];
+ range = &_backgroundInfo->ranges[i];
if ((range->_flags & 1) == 0) continue; // animated palette
range->_timer += range->_step * 2; // update timer
@@ -337,10 +314,14 @@ void Gfx::setProjectorProgram(int16 *data) {
}
void Gfx::drawInventory() {
-
+/*
if ((_engineFlags & kEngineInventory) == 0) {
return;
}
+*/
+ if (_vm->_input->_inputMode != Input::kInputModeInventory) {
+ return;
+ }
Common::Rect r;
_vm->_inventoryRenderer->getRect(r);
@@ -356,21 +337,19 @@ void Gfx::drawItems() {
Graphics::Surface *surf = g_system->lockScreen();
for (uint i = 0; i < _numItems; i++) {
- blt(_items[i].rect, _items[i].data->getData(_items[i].frame), surf, LAYER_FOREGROUND, _items[i].transparentColor);
+ drawGfxObject(_items[i].data, *surf, false);
}
g_system->unlockScreen();
}
void Gfx::drawBalloons() {
- if (_numBalloons == 0) {
+ if (_balloons.size() == 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);
- blt(r, (byte*)_balloons[i].surface.getBasePtr(0, 0), surf, LAYER_FOREGROUND, BALLOON_TRANSPARENT_COLOR);
+ for (uint i = 0; i < _balloons.size(); i++) {
+ drawGfxObject(_balloons[i], *surf, false);
}
g_system->unlockScreen();
}
@@ -380,29 +359,37 @@ void Gfx::clearScreen() {
}
void Gfx::beginFrame() {
-
- int32 oldBackgroundMode = _varBackgroundMode;
- _varBackgroundMode = getVar("background_mode");
-
- if (oldBackgroundMode != _varBackgroundMode) {
- switch (_varBackgroundMode) {
- case 1:
- _bitmapMask.free();
- break;
- case 2:
- _bitmapMask.create(_backgroundInfo.width, _backgroundInfo.height, 1);
- byte *data = (byte*)_bitmapMask.pixels;
- for (uint y = 0; y < _bitmapMask.h; y++) {
- for (uint x = 0; x < _bitmapMask.w; x++) {
- *data++ = _backgroundInfo.mask.getValue(x, y);
+ _skipBackground = (_backgroundInfo->bg.pixels == 0); // don't render frame if background is missing
+
+ if (!_skipBackground) {
+ int32 oldBackgroundMode = _varBackgroundMode;
+ _varBackgroundMode = getVar("background_mode");
+ if (oldBackgroundMode != _varBackgroundMode) {
+ switch (_varBackgroundMode) {
+ case 1:
+ _bitmapMask.free();
+ break;
+ case 2:
+ _bitmapMask.create(_backgroundInfo->width, _backgroundInfo->height, 1);
+ byte *data = (byte*)_bitmapMask.pixels;
+ for (uint y = 0; y < _bitmapMask.h; y++) {
+ for (uint x = 0; x < _bitmapMask.w; x++) {
+ *data++ = _backgroundInfo->mask.getValue(x, y);
+ }
}
+ break;
}
- break;
}
}
+ _varDrawPathZones = getVar("draw_path_zones");
+ if (_varDrawPathZones == 1 && _vm->getGameType() != GType_BRA) {
+ setVar("draw_path_zones", 0);
+ _varDrawPathZones = 0;
+ warning("Path zones are supported only in Big Red Adventure");
+ }
- if (_vm->_screenWidth >= _backgroundInfo.width) {
+ if (_skipBackground || (_vm->_screenWidth >= _backgroundInfo->width)) {
_varScrollX = 0;
} else {
_varScrollX = getVar("scroll_x");
@@ -427,24 +414,38 @@ int32 Gfx::getRenderMode(const char *type) {
void Gfx::updateScreen() {
- // background may not cover the whole screen, so adjust bulk update size
- uint w = MIN(_vm->_screenWidth, (int32)_backgroundInfo.width);
- uint h = MIN(_vm->_screenHeight, (int32)_backgroundInfo.height);
-
- byte *backgroundData = 0;
- uint16 backgroundPitch = 0;
- switch (_varBackgroundMode) {
- case 1:
- backgroundData = (byte*)_backgroundInfo.bg.getBasePtr(_varScrollX, 0);
- backgroundPitch = _backgroundInfo.bg.pitch;
- break;
- case 2:
- backgroundData = (byte*)_bitmapMask.getBasePtr(_varScrollX, 0);
- backgroundPitch = _bitmapMask.pitch;
- break;
+ if (!_skipBackground) {
+ // background may not cover the whole screen, so adjust bulk update size
+ uint w = MIN(_vm->_screenWidth, (int32)_backgroundInfo->width);
+ uint h = MIN(_vm->_screenHeight, (int32)_backgroundInfo->height);
+
+ byte *backgroundData = 0;
+ uint16 backgroundPitch = 0;
+ switch (_varBackgroundMode) {
+ case 1:
+ backgroundData = (byte*)_backgroundInfo->bg.getBasePtr(_varScrollX, 0);
+ backgroundPitch = _backgroundInfo->bg.pitch;
+ break;
+ case 2:
+ backgroundData = (byte*)_bitmapMask.getBasePtr(_varScrollX, 0);
+ backgroundPitch = _bitmapMask.pitch;
+ break;
+ }
+ g_system->copyRectToScreen(backgroundData, backgroundPitch, _backgroundInfo->x, _backgroundInfo->y, w, h);
}
- g_system->copyRectToScreen(backgroundData, backgroundPitch, _backgroundInfo.x, _backgroundInfo.y, w, h);
+ if (_varDrawPathZones == 1) {
+ Graphics::Surface *surf = g_system->lockScreen();
+ ZoneList::iterator b = _vm->_location._zones.begin();
+ ZoneList::iterator e = _vm->_location._zones.end();
+ for (; b != e; b++) {
+ ZonePtr z = *b;
+ if (z->_type & kZonePath) {
+ surf->frameRect(Common::Rect(z->_left, z->_top, z->_right, z->_bottom), 2);
+ }
+ }
+ g_system->unlockScreen();
+ }
_varRenderMode = _varAnimRenderMode;
@@ -498,17 +499,17 @@ void Gfx::patchBackground(Graphics::Surface &surf, int16 x, int16 y, bool mask)
Common::Rect r(surf.w, surf.h);
r.moveTo(x, y);
- uint16 z = (mask) ? _backgroundInfo.getLayer(y) : LAYER_FOREGROUND;
- blt(r, (byte*)surf.pixels, &_backgroundInfo.bg, z, 0);
+ uint16 z = (mask) ? _backgroundInfo->getLayer(y) : LAYER_FOREGROUND;
+ blt(r, (byte*)surf.pixels, &_backgroundInfo->bg, z, 0);
}
void Gfx::fillBackground(const Common::Rect& r, byte color) {
- _backgroundInfo.bg.fillRect(r, color);
+ _backgroundInfo->bg.fillRect(r, color);
}
void Gfx::invertBackground(const Common::Rect& r) {
- byte *d = (byte*)_backgroundInfo.bg.getBasePtr(r.left, r.top);
+ byte *d = (byte*)_backgroundInfo->bg.getBasePtr(r.left, r.top);
for (int i = 0; i < r.height(); i++) {
for (int j = 0; j < r.width(); j++) {
@@ -516,146 +517,7 @@ void Gfx::invertBackground(const Common::Rect& r) {
d++;
}
- d += (_backgroundInfo.bg.pitch - r.width());
- }
-
-}
-
-// this is the maximum size of an unpacked frame in BRA
-byte _unpackedBitmap[640*401];
-
-#if 0
-void Gfx::unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, byte transparentColor) {
-
- byte *d = _unpackedBitmap;
-
- while (size > 0) {
-
- uint8 p = *data++;
- size--;
- uint8 color = p & 0xF;
- uint8 repeat = (p & 0xF0) >> 4;
- if (repeat == 0) {
- repeat = *data++;
- size--;
- }
-
- memset(d, color, repeat);
- d += repeat;
- }
-
- blt(r, _unpackedBitmap, surf, z, transparentColor);
-}
-#endif
-void Gfx::unpackBlt(const Common::Rect& r, byte *data, uint size, Graphics::Surface *surf, uint16 z, byte transparentColor) {
-
- byte *d = _unpackedBitmap;
- uint pixelsLeftInLine = r.width();
-
- while (size > 0) {
- uint8 p = *data++;
- size--;
- uint8 color = p & 0xF;
- uint8 repeat = (p & 0xF0) >> 4;
- if (repeat == 0) {
- repeat = *data++;
- size--;
- }
- if (repeat == 0) {
- // end of line
- repeat = pixelsLeftInLine;
- pixelsLeftInLine = r.width();
- } else {
- pixelsLeftInLine -= repeat;
- }
-
- memset(d, color, repeat);
- d += repeat;
- }
-
- blt(r, _unpackedBitmap, surf, z, transparentColor);
-}
-
-
-void Gfx::blt(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, byte transparentColor) {
-
- Common::Point dp;
- Common::Rect q(r);
-
- Common::Rect clipper(surf->w, surf->h);
-
- q.clip(clipper);
- if (!q.isValidRect()) return;
-
- dp.x = q.left;
- dp.y = q.top;
-
- q.translate(-r.left, -r.top);
-
- byte *s = data + q.left + q.top * r.width();
- byte *d = (byte*)surf->getBasePtr(dp.x, dp.y);
-
- uint sPitch = r.width() - q.width();
- uint dPitch = surf->w - q.width();
-
-
- if (_varRenderMode == 2) {
-
- for (uint16 i = 0; i < q.height(); i++) {
-
- for (uint16 j = 0; j < q.width(); j++) {
- if (*s != transparentColor) {
- if (_backgroundInfo.mask.data && (z < LAYER_FOREGROUND)) {
- byte v = _backgroundInfo.mask.getValue(dp.x + j, dp.y + i);
- if (z >= v) *d = 5;
- } else {
- *d = 5;
- }
- }
-
- s++;
- d++;
- }
-
- s += sPitch;
- d += dPitch;
- }
-
- } else {
- if (_backgroundInfo.mask.data && (z < LAYER_FOREGROUND)) {
-
- for (uint16 i = 0; i < q.height(); i++) {
-
- for (uint16 j = 0; j < q.width(); j++) {
- if (*s != transparentColor) {
- byte v = _backgroundInfo.mask.getValue(dp.x + j, dp.y + i);
- if (z >= v) *d = *s;
- }
-
- s++;
- d++;
- }
-
- s += sPitch;
- d += dPitch;
- }
-
- } else {
-
- for (uint16 i = q.top; i < q.bottom; i++) {
- for (uint16 j = q.left; j < q.right; j++) {
- if (*s != transparentColor)
- *d = *s;
-
- s++;
- d++;
- }
-
- s += sPitch;
- d += dPitch;
- }
-
- }
+ d += (_backgroundInfo->bg.pitch - r.width());
}
}
@@ -669,10 +531,9 @@ void setupLabelSurface(Graphics::Surface &surf, uint w, uint h) {
surf.fillRect(Common::Rect(w,h), LABEL_TRANSPARENT_COLOR);
}
-Label *Gfx::renderFloatingLabel(Font *font, char *text) {
+uint Gfx::renderFloatingLabel(Font *font, char *text) {
- Label *label = new Label;
- Graphics::Surface *cnv = &label->_cnv;
+ Graphics::Surface *cnv = new Graphics::Surface;
uint w, h;
@@ -698,80 +559,38 @@ Label *Gfx::renderFloatingLabel(Font *font, char *text) {
drawText(font, cnv, 0, 0, text, 0);
}
- return label;
-}
+ GfxObj *obj = new GfxObj(kGfxObjTypeLabel, new SurfaceToFrames(cnv), "floatingLabel");
+ obj->transparentKey = LABEL_TRANSPARENT_COLOR;
+ obj->layer = LAYER_FOREGROUND;
-uint Gfx::createLabel(Font *font, const char *text, byte color) {
- assert(_numLabels < MAX_NUM_LABELS);
-
- Label *label = new Label;
- Graphics::Surface *cnv = &label->_cnv;
-
- uint w, h;
-
- if (_vm->getPlatform() == Common::kPlatformAmiga) {
- w = font->getStringWidth(text) + 2;
- h = font->height() + 2;
-
- setupLabelSurface(*cnv, w, h);
-
- drawText(font, cnv, 0, 2, text, 0);
- drawText(font, cnv, 2, 0, text, color);
- } else {
- w = font->getStringWidth(text);
- h = font->height();
-
- setupLabelSurface(*cnv, w, h);
-
- drawText(font, cnv, 0, 0, text, color);
- }
-
- uint id = _numLabels;
- _labels[id] = label;
- _numLabels++;
+ uint id = _labels.size();
+ _labels.insert_at(id, obj);
return id;
}
-void Gfx::showLabel(uint id, int16 x, int16 y) {
- assert(id < _numLabels);
- _labels[id]->_visible = true;
+void Gfx::showFloatingLabel(uint label) {
+ assert(label < _labels.size());
- if (x == CENTER_LABEL_HORIZONTAL) {
- x = CLIP<int16>((_vm->_screenWidth - _labels[id]->_cnv.w) / 2, 0, _vm->_screenWidth/2);
- }
-
- if (y == CENTER_LABEL_VERTICAL) {
- y = CLIP<int16>((_vm->_screenHeight - _labels[id]->_cnv.h) / 2, 0, _vm->_screenHeight/2);
- }
+ hideFloatingLabel();
- _labels[id]->_pos.x = x;
- _labels[id]->_pos.y = y;
-}
+ _labels[label]->x = -1000;
+ _labels[label]->y = -1000;
+ _labels[label]->setFlags(kGfxObjVisible);
-void Gfx::hideLabel(uint id) {
- assert(id < _numLabels);
- _labels[id]->_visible = false;
+ _floatingLabel = label;
}
-void Gfx::freeLabels() {
- for (uint i = 0; i < _numLabels; i++) {
- delete _labels[i];
+void Gfx::hideFloatingLabel() {
+ if (_floatingLabel != NO_FLOATING_LABEL) {
+ _labels[_floatingLabel]->clearFlags(kGfxObjVisible);
}
- _numLabels = 0;
+ _floatingLabel = NO_FLOATING_LABEL;
}
-void Gfx::setFloatingLabel(Label *label) {
- _floatingLabel = label;
-
- if (_floatingLabel) {
- _floatingLabel->resetPosition();
- }
-}
-
void Gfx::updateFloatingLabel() {
- if (!_floatingLabel) {
+ if (_floatingLabel == NO_FLOATING_LABEL) {
return;
}
@@ -780,113 +599,115 @@ void Gfx::updateFloatingLabel() {
Common::Point cursor;
_vm->_input->getCursorPos(cursor);
+ Common::Rect r;
+ _labels[_floatingLabel]->getRect(0, r);
+
if (_vm->_input->_activeItem._id != 0) {
- _si = cursor.x + 16 - _floatingLabel->_cnv.w/2;
+ _si = cursor.x + 16 - r.width()/2;
_di = cursor.y + 34;
} else {
- _si = cursor.x + 8 - _floatingLabel->_cnv.w/2;
+ _si = cursor.x + 8 - r.width()/2;
_di = cursor.y + 21;
}
if (_si < 0) _si = 0;
if (_di > 190) _di = 190;
- if (_floatingLabel->_cnv.w + _si > _vm->_screenWidth)
- _si = _vm->_screenWidth - _floatingLabel->_cnv.w;
+ if (r.width() + _si > _vm->_screenWidth)
+ _si = _vm->_screenWidth - r.width();
- _floatingLabel->_pos.x = _si;
- _floatingLabel->_pos.y = _di;
+ _labels[_floatingLabel]->x = _si;
+ _labels[_floatingLabel]->y = _di;
}
-void Gfx::drawLabels() {
- if ((!_floatingLabel) && (_numLabels == 0)) {
- return;
- }
- updateFloatingLabel();
- Graphics::Surface* surf = g_system->lockScreen();
- for (uint i = 0; i < _numLabels; i++) {
- if (_labels[i]->_visible) {
- Common::Rect r(_labels[i]->_cnv.w, _labels[i]->_cnv.h);
- r.moveTo(_labels[i]->_pos);
- blt(r, (byte*)_labels[i]->_cnv.getBasePtr(0, 0), surf, LAYER_FOREGROUND, LABEL_TRANSPARENT_COLOR);
- }
- }
- if (_floatingLabel) {
- Common::Rect r(_floatingLabel->_cnv.w, _floatingLabel->_cnv.h);
- r.moveTo(_floatingLabel->_pos);
- blt(r, (byte*)_floatingLabel->_cnv.getBasePtr(0, 0), surf, LAYER_FOREGROUND, LABEL_TRANSPARENT_COLOR);
- }
+uint Gfx::createLabel(Font *font, const char *text, byte color) {
+ assert(_labels.size() < MAX_NUM_LABELS);
- g_system->unlockScreen();
-}
+ Graphics::Surface *cnv = new Graphics::Surface;
-Label::Label() {
- resetPosition();
- _visible = false;
-}
+ uint w, h;
-Label::~Label() {
- free();
-}
+ if (_vm->getPlatform() == Common::kPlatformAmiga) {
+ w = font->getStringWidth(text) + 2;
+ h = font->height() + 2;
-void Label::free() {
- _cnv.free();
- resetPosition();
-}
+ setupLabelSurface(*cnv, w, h);
-void Label::resetPosition() {
- _pos.x = -1000;
- _pos.y = -1000;
-}
+ drawText(font, cnv, 0, 2, text, 0);
+ drawText(font, cnv, 2, 0, text, color);
+ } else {
+ w = font->getStringWidth(text);
+ h = font->height();
+ setupLabelSurface(*cnv, w, h);
-void Gfx::getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height) {
+ drawText(font, cnv, 0, 0, text, color);
+ }
- uint16 lines = 0;
- uint16 w = 0;
- *width = 0;
+ GfxObj *obj = new GfxObj(kGfxObjTypeLabel, new SurfaceToFrames(cnv), "label");
+ obj->transparentKey = LABEL_TRANSPARENT_COLOR;
+ obj->layer = LAYER_FOREGROUND;
- uint16 blankWidth = font->getStringWidth(" ");
- uint16 tokenWidth = 0;
+ int id = _labels.size();
- char token[MAX_TOKEN_LEN];
+ _labels.insert_at(id, obj);
- while (strlen(text) != 0) {
+ return id;
+}
- text = parseNextToken(text, token, MAX_TOKEN_LEN, " ", true);
- tokenWidth = font->getStringWidth(token);
+void Gfx::showLabel(uint id, int16 x, int16 y) {
+ assert(id < _labels.size());
+ _labels[id]->setFlags(kGfxObjVisible);
- w += tokenWidth;
+ Common::Rect r;
+ _labels[id]->getRect(0, r);
- if (!scumm_stricmp(token, "%p")) {
- lines++;
- } else {
- if (w > maxwidth) {
- w -= tokenWidth;
- lines++;
- if (w > *width)
- *width = w;
+ if (x == CENTER_LABEL_HORIZONTAL) {
+ x = CLIP<int16>((_vm->_screenWidth - r.width()) / 2, 0, _vm->_screenWidth/2);
+ }
- w = tokenWidth;
- }
- }
+ if (y == CENTER_LABEL_VERTICAL) {
+ y = CLIP<int16>((_vm->_screenHeight - r.height()) / 2, 0, _vm->_screenHeight/2);
+ }
- w += blankWidth;
- text = Common::ltrim(text);
+ _labels[id]->x = x;
+ _labels[id]->y = y;
+}
+
+void Gfx::hideLabel(uint id) {
+ assert(id < _labels.size());
+ _labels[id]->clearFlags(kGfxObjVisible);
+}
+
+void Gfx::freeLabels() {
+ for (uint i = 0; i < _labels.size(); i++) {
+ delete _labels[i];
}
+ _labels.clear();
+ _floatingLabel = NO_FLOATING_LABEL;
+}
- if (*width < w) *width = w;
- *width += 10;
+void Gfx::drawLabels() {
+ if (_labels.size() == 0) {
+ return;
+ }
- *height = lines * 10 + 20;
+ updateFloatingLabel();
- return;
+ Graphics::Surface* surf = g_system->lockScreen();
+
+ for (uint i = 0; i < _labels.size(); i++) {
+ drawGfxObject(_labels[i], *surf, false);
+ }
+
+ g_system->unlockScreen();
}
+
void Gfx::copyRect(const Common::Rect &r, Graphics::Surface &src, Graphics::Surface &dst) {
byte *s = (byte*)src.getBasePtr(r.left, r.top);
@@ -903,7 +724,7 @@ void Gfx::copyRect(const Common::Rect &r, Graphics::Surface &src, Graphics::Surf
}
void Gfx::grabBackground(const Common::Rect& r, Graphics::Surface &dst) {
- copyRect(r, _backgroundInfo.bg, dst);
+ copyRect(r, _backgroundInfo->bg, dst);
}
@@ -917,17 +738,20 @@ Gfx::Gfx(Parallaction* vm) :
setPalette(_palette);
- _numBalloons = 0;
_numItems = 0;
- _numLabels = 0;
- _floatingLabel = 0;
+ _floatingLabel = NO_FLOATING_LABEL;
_screenX = 0;
_screenY = 0;
+ _backgroundInfo = 0;
+
_halfbrite = false;
_hbCircleRadius = 0;
+ _unpackedBitmap = new byte[MAXIMUM_UNPACKED_BITMAP_SIZE];
+ assert(_unpackedBitmap);
+
registerVar("background_mode", 1);
_varBackgroundMode = 1;
@@ -937,26 +761,39 @@ Gfx::Gfx(Parallaction* vm) :
registerVar("anim_render_mode", 1);
registerVar("misc_render_mode", 1);
+ registerVar("draw_path_zones", 0);
+
+ if ((_vm->getGameType() == GType_BRA) && (_vm->getPlatform() == Common::kPlatformPC)) {
+ // this loads the backup palette needed by the PC version of BRA (see setBackground()).
+ BackgroundInfo paletteInfo;
+ _disk->loadSlide(paletteInfo, "pointer");
+ _backupPal.clone(paletteInfo.palette);
+ }
+
return;
}
Gfx::~Gfx() {
- freeBackground();
+ delete _backgroundInfo;
+
+ freeLabels();
+
+ delete []_unpackedBitmap;
return;
}
-int Gfx::setItem(Frames* frames, uint16 x, uint16 y, byte transparentColor) {
+int Gfx::setItem(GfxObj* frames, uint16 x, uint16 y, byte transparentColor) {
int id = _numItems;
_items[id].data = frames;
- _items[id].x = x;
- _items[id].y = y;
-
- _items[id].transparentColor = transparentColor;
+ _items[id].data->x = x;
+ _items[id].data->y = y;
+ _items[id].data->layer = LAYER_FOREGROUND;
+ _items[id].data->transparentKey = transparentColor;
_numItems++;
@@ -965,223 +802,58 @@ int Gfx::setItem(Frames* frames, uint16 x, uint16 y, byte transparentColor) {
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::getBalloon(uint id) {
- assert(id < _numBalloons);
- return &_balloons[id];
-}
-
-int Gfx::createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness) {
- assert(_numBalloons < 5);
-
- int id = _numBalloons;
-
- Gfx::Balloon *balloon = &_balloons[id];
-
- int16 real_h = (winding == -1) ? h : h + 9;
- balloon->surface.create(w, real_h, 1);
- balloon->surface.fillRect(Common::Rect(w, real_h), BALLOON_TRANSPARENT_COLOR);
-
- 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);
- blt(s, _resBalloonTail[winding], &balloon->surface, LAYER_FOREGROUND, BALLOON_TRANSPARENT_COLOR);
- }
-
- _numBalloons++;
-
- return id;
-}
-
-int Gfx::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);
- Gfx::Balloon *balloon = &_balloons[id];
-
- drawWrappedText(_vm->_dialogueFont, &balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
-
- balloon->x = x;
- balloon->y = y;
-
- return id;
-}
-
-int Gfx::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);
- Gfx::Balloon *balloon = &_balloons[id];
-
- drawWrappedText(_vm->_dialogueFont, &balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
-
- balloon->x = _dialogueBalloonX[id];
- balloon->y = 10;
-
- if (id > 0) {
- balloon->y += _balloons[id - 1].y + _balloons[id - 1].outerBox.height();
- }
-
-
- return id;
+ _items[item].data->frame = f;
+ _items[item].data->setFlags(kGfxObjVisible);
}
-void Gfx::setBalloonText(uint id, char *text, byte textColor) {
- Gfx::Balloon *balloon = getBalloon(id);
- balloon->surface.fillRect(balloon->innerBox, 1);
- drawWrappedText(_vm->_dialogueFont, &balloon->surface, text, textColor, MAX_BALLOON_WIDTH);
-}
+GfxObj* Gfx::registerBalloon(Frames *frames, const char *text) {
-int Gfx::setLocationBalloon(char *text, bool endGame) {
+ GfxObj *obj = new GfxObj(kGfxObjTypeBalloon, frames, text);
- int16 w, h;
+ obj->layer = LAYER_FOREGROUND;
+ obj->frame = 0;
+ obj->setFlags(kGfxObjVisible);
- getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h);
+ _balloons.push_back(obj);
- int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR);
- Gfx::Balloon *balloon = &_balloons[id];
- drawWrappedText(_vm->_dialogueFont, &balloon->surface, text, 0, MAX_BALLOON_WIDTH);
-
- balloon->x = 5;
- balloon->y = 5;
-
- return id;
+ return obj;
}
-int Gfx::hitTestDialogueBalloon(int x, int y) {
-
- Common::Point p;
-
- for (uint i = 0; i < _numBalloons; i++) {
- p.x = x - _balloons[i].x;
- p.y = y - _balloons[i].y;
-
- if (_balloons[i].innerBox.contains(p))
- return i;
+void Gfx::destroyBalloons() {
+ for (uint i = 0; i < _balloons.size(); i++) {
+ delete _balloons[i];
}
-
- return -1;
-}
-
-
-void Gfx::freeBalloons() {
- for (uint i = 0; i < _numBalloons; i++) {
- _balloons[i].surface.free();
- }
- _numBalloons = 0;
+ _balloons.clear();
}
void Gfx::freeItems() {
_numItems = 0;
}
-void Gfx::hideDialogueStuff() {
- freeItems();
- freeBalloons();
-}
-
-void Gfx::drawText(Font *font, 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);
-}
-
-void Gfx::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;
+void Gfx::setBackground(uint type, BackgroundInfo *info) {
+ delete _backgroundInfo;
+ _backgroundInfo = info;
- 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);
+ if (type == kBackgroundLocation) {
+ // The PC version of BRA needs the entries 20-31 of the palette to be constant, but
+ // the background resource files are screwed up. The right colors come from an unused
+ // bitmap (pointer.bmp). Nothing is known about the Amiga version so far.
+ if ((_vm->getGameType() == GType_BRA) && (_vm->getPlatform() == Common::kPlatformPC)) {
+ int r, g, b;
+ for (uint i = 16; i < 32; i++) {
+ _backupPal.getEntry(i, r, g, b);
+ _backgroundInfo->palette.setEntry(i, r, g, b);
}
-
}
- drawText(font, surf, rx, ry, token, color);
-
- rx += tokenWidth + blankWidth;
- linewidth += blankWidth;
-
- text = Common::ltrim(text);
- }
-
-}
-
-void Gfx::freeBackground() {
- _backgroundInfo.free();
-}
-
-void Gfx::setBackground(uint type, const char* name, const char* mask, const char* path) {
-
- freeBackground();
-
- if (type == kBackgroundLocation) {
- _disk->loadScenery(_backgroundInfo, name, mask, path);
- setPalette(_backgroundInfo.palette);
- _palette.clone(_backgroundInfo.palette);
+ setPalette(_backgroundInfo->palette);
+ _palette.clone(_backgroundInfo->palette);
} else {
- _disk->loadSlide(_backgroundInfo, name);
- setPalette(_backgroundInfo.palette);
+ for (uint i = 0; i < 6; i++)
+ _backgroundInfo->ranges[i]._flags = 0; // disable palette cycling for slides
+ setPalette(_backgroundInfo->palette);
}
-
}
} // namespace Parallaction