aboutsummaryrefslogtreecommitdiff
path: root/engines/access
diff options
context:
space:
mode:
authorPaul Gilbert2014-08-17 18:56:05 -0400
committerPaul Gilbert2014-08-17 18:56:05 -0400
commit9393f6d7559653a28166fe74da9745e95b76f85b (patch)
tree23c8bba593a9f55a1ef3eaa06cf14468d0e2527f /engines/access
parent4ea9339d183cb53f465d7752e739cf8a153a7978 (diff)
downloadscummvm-rg350-9393f6d7559653a28166fe74da9745e95b76f85b.tar.gz
scummvm-rg350-9393f6d7559653a28166fe74da9745e95b76f85b.tar.bz2
scummvm-rg350-9393f6d7559653a28166fe74da9745e95b76f85b.zip
ACCESS: Implemented bubble box drawing code
Diffstat (limited to 'engines/access')
-rw-r--r--engines/access/asurface.cpp12
-rw-r--r--engines/access/asurface.h7
-rw-r--r--engines/access/bubble_box.cpp167
-rw-r--r--engines/access/bubble_box.h27
-rw-r--r--engines/access/data.cpp85
-rw-r--r--engines/access/data.h19
6 files changed, 271 insertions, 46 deletions
diff --git a/engines/access/asurface.cpp b/engines/access/asurface.cpp
index 08caa8a3b2..99292278f3 100644
--- a/engines/access/asurface.cpp
+++ b/engines/access/asurface.cpp
@@ -115,6 +115,11 @@ int ASurface::_lastBoundsW;
int ASurface::_lastBoundsH;
int ASurface::_scrollX;
int ASurface::_scrollY;
+int ASurface::_orgX1;
+int ASurface::_orgY1;
+int ASurface::_orgX2;
+int ASurface::_orgY2;
+int ASurface::_lColor;
void ASurface::init() {
_leftSkip = _rightSkip = 0;
@@ -123,6 +128,9 @@ void ASurface::init() {
_lastBoundsX = _lastBoundsY = 0;
_lastBoundsW = _lastBoundsH = 0;
_scrollX = _scrollY = 0;
+ _orgX1 = _orgY1 = 0;
+ _orgX2 = _orgY2 = 0;
+ _lColor = 0;
}
ASurface::~ASurface() {
@@ -329,4 +337,8 @@ void ASurface::restoreBlock() {
}
}
+void ASurface::drawRect() {
+ Graphics::Surface::fillRect(Common::Rect(_orgX1, _orgY1, _orgX2, _orgY2), _lColor);
+}
+
} // End of namespace Access
diff --git a/engines/access/asurface.h b/engines/access/asurface.h
index 85550d9eee..400dd07b4d 100644
--- a/engines/access/asurface.h
+++ b/engines/access/asurface.h
@@ -46,9 +46,14 @@ public:
static int _lastBoundsX, _lastBoundsY;
static int _lastBoundsW, _lastBoundsH;
static int _scrollX, _scrollY;
+ static int _orgX1, _orgY1;
+ static int _orgX2, _orgY2;
+ static int _lColor;
static void init();
public:
+ virtual void plotFrame(SpriteFrame *frame, const Common::Point &pt);
+public:
virtual ~ASurface();
void clearBuffer();
@@ -75,7 +80,7 @@ public:
void restoreBlock();
- virtual void plotFrame(SpriteFrame *frame, const Common::Point &pt);
+ void drawRect();
};
class SpriteFrame : public ASurface {
diff --git a/engines/access/bubble_box.cpp b/engines/access/bubble_box.cpp
index 5f0cb9443b..f910028fc5 100644
--- a/engines/access/bubble_box.cpp
+++ b/engines/access/bubble_box.cpp
@@ -26,18 +26,15 @@
namespace Access {
-Box::Box(AccessEngine *vm) : Manager(vm) {
- _edgeSize = 0;
-}
-
-void Box::doBox(int item, int box) {
- error("TODO: doBox");
-}
-
-/*------------------------------------------------------------------------*/
-
-BubbleBox::BubbleBox(AccessEngine *vm) : Box(vm) {
+BubbleBox::BubbleBox(AccessEngine *vm) : Manager(vm) {
+ _type = TYPE_2;
+ _bounds = Common::Rect(64, 32, 64 + 130, 32 + 122);
_bubblePtr = nullptr;
+ _fieldD = 0;
+ _fieldE = 0;
+ _fieldF = 0;
+ _field10 = 0;
+
_maxChars = 0;
}
@@ -69,7 +66,7 @@ void BubbleBox::placeBubble1(const Common::String &msg) {
calcBubble(msg);
- Common::Rect r = BubbleBox::_bubbles[0];
+ Common::Rect r = _bubbles[0];
r.translate(-2, 0);
_vm->_screen->saveBlock(r);
printBubble(msg);
@@ -81,7 +78,7 @@ void BubbleBox::calcBubble(const Common::String &msg) {
Common::Point printStart = _vm->_fonts._printStart;
// Figure out maximum width allowed
- if (_edgeSize == 4) {
+ if (_type == TYPE_4) {
_vm->_fonts._printMaxX = 110;
} else {
_vm->_fonts._printMaxX = _vm->_fonts._font2.stringWidth(_bubblePtr);
@@ -96,14 +93,14 @@ void BubbleBox::calcBubble(const Common::String &msg) {
int width = 0;
bool lastLine;
do {
- lastLine = _vm->_fonts._font2.getLine(s, _vm->_fonts._printMaxX, line, width);
- width = MIN(width, _vm->_fonts._printMaxX);
+ lastLine = _vm->_fonts._font2.getLine(s, _maxChars * 6, line, width);
+ width = MAX(width, _vm->_fonts._printMaxX);
_vm->_fonts._printOrg.y += 6;
_vm->_fonts._printOrg.x = _vm->_fonts._printStart.x;
} while (!lastLine);
- if (_edgeSize == 4)
+ if (_type == TYPE_4)
++_vm->_fonts._printOrg.y += 6;
// Determine the width for the area
@@ -114,17 +111,17 @@ void BubbleBox::calcBubble(const Common::String &msg) {
// Determine the height for area
int y = _vm->_fonts._printOrg.y + 6;
- if (_edgeSize == 4)
+ if (_type == TYPE_4)
y += 6;
int height = y - bounds.top;
bounds.setHeight(height);
- height -= (_edgeSize == 4) ? 30 : 24;
+ height -= (_type == TYPE_4) ? 30 : 24;
if (height >= 0)
bounds.setHeight(bounds.height() + 13 - (height % 13));
// Add the new bounds to the bubbles list
- BubbleBox::_bubbles.push_back(bounds);
+ _bubbles.push_back(bounds);
// Restore points
_vm->_fonts._printOrg = printOrg;
@@ -132,13 +129,139 @@ void BubbleBox::calcBubble(const Common::String &msg) {
}
void BubbleBox::printBubble(const Common::String &msg) {
- drawBubble(BubbleBox::_bubbles.size() - 1);
- error("TODO: printBubble");
+ drawBubble(_bubbles.size() - 1);
+
+ // Loop through drawing the lines
+ Common::String s = msg;
+ Common::String line;
+ int width = 0;
+ bool lastLine;
+ do {
+ // Get next line
+ Font &font2 = _vm->_fonts._font2;
+ lastLine = font2.getLine(s, _maxChars * 6, line, width);
+
+ // Set font colors
+ font2._fontColors[0] = 0;
+ font2._fontColors[1] = 0;
+ font2._fontColors[2] = 0;
+ font2._fontColors[3] = 0;
+
+ int xp = _vm->_fonts._printOrg.x;
+ if (_type == TYPE_4)
+ xp = (_bounds.width() - width) / 2 + _bounds.left - 4;
+
+ // Draw the text
+ font2.drawString(_vm->_screen, line, Common::Point(xp, _vm->_fonts._printOrg.y));
+
+ // Move print position
+ _vm->_fonts._printOrg.y += 6;
+ _vm->_fonts._printOrg.x = _vm->_fonts._printStart.x;
+ } while (!lastLine);
}
void BubbleBox::drawBubble(int index) {
- _bounds = BubbleBox::_bubbles[index];
+ _bounds = _bubbles[index];
doBox(0, 0);
}
+void BubbleBox::doBox(int item, int box) {
+ FontManager &fonts = _vm->_fonts;
+ ASurface &screen = *_vm->_screen;
+
+ _startItem = item;
+ _startBox = box;
+
+ // Save state information
+ FontVal charSet = fonts._charSet;
+ FontVal charFor = fonts._charFor;
+ Common::Point printOrg = fonts._printOrg;
+ Common::Point printStart = fonts._printStart;
+ int charCol = _charCol;
+ int rowOff = _rowOff;
+
+ _vm->_screen->saveScreen();
+ _vm->_screen->setDisplayScan();
+ fonts._charFor._hi = 0xff;
+ fonts._charSet._lo = 1;
+ fonts._charSet._hi = 0;
+
+ if (_type == TYPE_4) {
+ fonts._charFor._lo = 0xFF;
+ error("TODO: filename listing");
+ return;
+ }
+
+ // Get icons data
+ byte *iconData = _vm->_files->loadFile("ICONS.LZ");
+ SpriteResource *icons = new SpriteResource(_vm, iconData, _vm->_files->_filesize);
+ delete[] iconData;
+
+ // Set the up boundaries and color to use for the box background
+ _vm->_screen->_orgX1 = _bounds.left;
+ _vm->_screen->_orgY1 = _bounds.top;
+ _vm->_screen->_orgX2 = _bounds.right;
+ _vm->_screen->_orgY2 = _bounds.bottom;
+ _vm->_screen->_lColor = 1;
+
+ int h = _bounds.height() - (_type == TYPE_4) ? 30 : 24;
+ int ySize = (h < 0) ? 0 : (h + 12) / 13;
+ int w = _bounds.width() - 24;
+ int xSize = (w < 0) ? 0 : (w + 19) / 20;
+
+ // Draw a background for the entire area
+ screen.drawRect();
+
+ // Draw images to form the top border
+ int xp, yp;
+ screen.plotImage(icons, 20, Common::Point(screen._orgX1, screen._orgY1));
+ xp = screen._orgX1 + 12;
+ for (int x = 0; x < xSize; ++x, xp += 20)
+ screen.plotImage(icons, 24 + x, Common::Point(xp, screen._orgY1));
+ screen.plotImage(icons, 21, Common::Point(xp, screen._orgY1));
+
+ // Draw images to form the bottom border
+ yp = screen._orgY2 - (_type == TYPE_4) ? 18 : 12;
+ screen.plotImage(icons, (_type == TYPE_4) ? 72 : 22,
+ Common::Point(screen._orgX1, yp));
+ xp = screen._orgX1 + 12;
+ yp += (_type == TYPE_4) ? 4 : 8;
+
+ for (int x = 0; x < xSize; ++x, xp += 20) {
+ screen.plotImage(icons, (_type == TYPE_4 ? 62 : 34) + x,
+ Common::Point(xp, yp));
+ }
+
+ yp -= (_type == TYPE_4) ? 18 : 12;
+ screen.plotImage(icons, (_type == TYPE_4) ? 73 : 23,
+ Common::Point(screen._orgX1, yp));
+
+ if (_type == TYPE_4) {
+ // Further stuff
+ warning("YSIZE not yet used %d", ySize);
+ error("TODO: Box type 4");
+ }
+
+ // Handle drawing title
+ int titleWidth = _vm->_fonts._font2.stringWidth(_bubblePtr);
+ Font &font2 = _vm->_fonts._font2;
+ font2._fontColors[0] = 0;
+ font2._fontColors[1] = 3;
+ font2._fontColors[2] = 2;
+ font2._fontColors[3] = 1;
+ font2.drawString(_vm->_screen, _bubblePtr, Common::Point(
+ _bounds.left + (_bounds.width() / 2) - (titleWidth / 2), _bounds.top + 1));
+
+ // Restore positional state
+ fonts._charSet = charSet;
+ fonts._charFor = charFor;
+ fonts._printOrg = printOrg;
+ fonts._printStart = printStart;
+ _charCol = charCol;
+ _rowOff = rowOff;
+
+ // Free icons data
+ delete icons;
+}
+
} // End of namespace Access
diff --git a/engines/access/bubble_box.h b/engines/access/bubble_box.h
index 189e0b1c04..3ddb2f72e3 100644
--- a/engines/access/bubble_box.h
+++ b/engines/access/bubble_box.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "common/rect.h"
+#include "common/str-array.h"
#include "common/stream.h"
#include "common/types.h"
#include "graphics/surface.h"
@@ -35,20 +36,24 @@ namespace Access {
class AccessEngine;
-class Box: public Manager {
-public:
- int _edgeSize;
- Common::Rect _bounds;
-public:
- Box(AccessEngine *vm);
-
- void doBox(int item, int box);
-};
+enum BoxType { TYPE_2 = 2, TYPE_4 = 4 };
-class BubbleBox: public Box {
+class BubbleBox: public Manager {
+private:
+ int _startItem, _startBox;
+ int _charCol, _rowOff;
+ Common::Point _fileStart;
public:
+ BoxType _type;
+ Common::Rect _bounds;
+ Common::StringArray _nameIndex;
Common::String _bubbleTitle;
const char *_bubblePtr;
+ int _fieldD;
+ int _fieldE;
+ int _fieldF;
+ int _field10;
+
int _maxChars;
Common::Array<Common::Rect> _bubbles;
public:
@@ -77,7 +82,7 @@ public:
*/
void drawBubble(int index);
-
+ void doBox(int item, int box);
};
} // End of namespace Access
diff --git a/engines/access/data.cpp b/engines/access/data.cpp
index 65702db9f1..1fba854f19 100644
--- a/engines/access/data.cpp
+++ b/engines/access/data.cpp
@@ -46,21 +46,57 @@ void TimerList::restoreTimers() {
/*------------------------------------------------------------------------*/
+byte Font::_fontColors[4];
+
Font::Font() {
}
+Font::~Font() {
+ for (uint i = 0; i < _chars.size(); ++i)
+ _chars[i].free();
+}
+
void Font::load(const int *index, const byte *data) {
+ assert(_chars.size() == 0);
int count = index[0];
- _v1 = index[1];
- _v2 = index[2];
-
- _chars.clear();
- for (int idx = 0; idx < count; ++idx)
- _chars.push_back(data + index[idx + 3]);
+ _bitWidth = index[1];
+ _height = index[2];
+
+ _chars.resize(count);
+
+ for (int i = 0; i < count; ++i) {
+ const byte *pData = data + index[i + 3];
+ _chars[i].create(*pData++, _height, Graphics::PixelFormat::createFormatCLUT8());
+
+ for (int y = 0; y < _height; ++y) {
+ int bitsLeft = 0;
+ byte srcByte = 0;
+ byte pixel;
+
+ byte *pDest = (byte *)_chars[i].getBasePtr(0, y);
+ for (int x = 0; x < _chars[i].w; ++x, ++pDest) {
+ // Get the pixel
+ pixel = 0;
+ for (int pixelCtr = 0; pixelCtr < _bitWidth; ++pixelCtr) {
+ // No bits in current byte left, so get next byte
+ if (bitsLeft == 0) {
+ bitsLeft = 8;
+ srcByte = *pData++;
+ }
+
+ pixel = (pixel << 1) | (srcByte >> 7);
+ srcByte <<= 1;
+ }
+
+ // Write out the pixel
+ *pDest = pixel;
+ }
+ }
+ }
}
int Font::charWidth(char c) {
- return *_chars[c - ' '];
+ return _chars[c - ' '].w;
}
int Font::stringWidth(const Common::String &msg) {
@@ -69,10 +105,11 @@ int Font::stringWidth(const Common::String &msg) {
for (const char *c = msg.c_str(); *c != '\0'; ++c)
total += charWidth(*c);
- return 0;
+ return total;
}
bool Font::getLine(Common::String &s, int maxWidth, Common::String &line, int &width) {
+ assert(maxWidth > 0);
width = 0;
const char *src = s.c_str();
char c;
@@ -92,7 +129,8 @@ bool Font::getLine(Common::String &s, int maxWidth, Common::String &line, int &w
// Reached maximum allowed. Work backwards to find space at the
// start of the current word as a point to split the line on
- while (*src != ' ' && src >= s.c_str()) {
+ --src;
+ while (src >= s.c_str() && *src != ' ') {
width -= charWidth(*src);
--src;
}
@@ -111,10 +149,39 @@ bool Font::getLine(Common::String &s, int maxWidth, Common::String &line, int &w
return true;
}
+void Font::drawString(Graphics::Surface *s, const Common::String &msg, const Common::Point &pt) {
+ Common::Point currPt = pt;
+ const char *msgP = msg.c_str();
+
+ while (*msgP) {
+ currPt.x += drawChar(s, *msgP, currPt);
+ ++msgP;
+ }
+}
+
+int Font::drawChar(Graphics::Surface *s, char c, Common::Point &pt) {
+ Graphics::Surface &ch = _chars[c - ' '];
+
+ // Loop through the lines of the character
+ for (int y = 0; y < ch.h; ++y) {
+ byte *pSrc = (byte *)ch.getBasePtr(0, y);
+ byte *pDest = (byte *)s->getBasePtr(pt.x, pt.y + y);
+
+ // Loop through the horizontal pixels of the line
+ for (int x = 0; x < ch.w; ++x, ++pSrc, ++pDest) {
+ if (*pSrc != 0)
+ *pDest = _fontColors[*pSrc];
+ }
+ }
+
+ return ch.w;
+}
+
/*------------------------------------------------------------------------*/
FontManager::FontManager() {
_printMaxX = 0;
+ Common::fill(&Font::_fontColors[0], &Font::_fontColors[4], 0);
}
} // End of namespace Access
diff --git a/engines/access/data.h b/engines/access/data.h
index 910e2523d1..fd3c889ddb 100644
--- a/engines/access/data.h
+++ b/engines/access/data.h
@@ -87,12 +87,16 @@ public:
class Font {
private:
- int _v1;
- int _v2;
- Common::Array<const byte *> _chars;
+ int _bitWidth;
+ int _height;
+ Common::Array<Graphics::Surface> _chars;
+public:
+ static byte _fontColors[4];
public:
Font();
+ ~Font();
+
/**
* Load the given font data
*/
@@ -118,6 +122,15 @@ public:
*/
bool getLine(Common::String &s, int maxWidth, Common::String &line, int &width);
+ /**
+ * Draw a string on a given surface
+ */
+ void drawString(Graphics::Surface *s, const Common::String &msg, const Common::Point &pt);
+
+ /**
+ * Draw a character on a given surface
+ */
+ int drawChar(Graphics::Surface *s, char c, Common::Point &pt);
};
class FontManager {