diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/m4/dialogs.cpp | 109 | ||||
-rw-r--r-- | engines/m4/dialogs.h | 18 | ||||
-rw-r--r-- | engines/m4/font.h | 3 | ||||
-rw-r--r-- | engines/m4/graphics.cpp | 6 | ||||
-rw-r--r-- | engines/m4/graphics.h | 3 | ||||
-rw-r--r-- | engines/m4/scene.cpp | 10 | ||||
-rw-r--r-- | engines/m4/viewmgr.h | 2 |
7 files changed, 133 insertions, 18 deletions
diff --git a/engines/m4/dialogs.cpp b/engines/m4/dialogs.cpp index d4b341f891..9989d99309 100644 --- a/engines/m4/dialogs.cpp +++ b/engines/m4/dialogs.cpp @@ -35,17 +35,25 @@ static void strToUpper(char *s) { } } +const RGB8 DIALOG_PALETTE[8] = { + {0x80, 0x80, 0x80, 0xff}, {0x90, 0x90, 0x90, 0xff}, {0x70, 0x70, 0x70, 0xff}, {0x9c, 0x9c, 0x9c, 0xff}, + {0x80, 0x80, 0x80, 0xff}, {0x90, 0x90, 0x90, 0xff}, {0xDC, 0xDC, 0xDC, 0xff}, {0x00, 0x00, 0x00, 0xff} +}; + +#define ROR16(v,amt) (((uint16)(v) >> amt) | ((uint16)(v) << (16 - amt))) + void Dialog::initDialog() { } void Dialog::incLine() { - ++_numLines; - assert(++_numLines < 20); + _lines.push_back(*new DialogLine()); + assert(_lines.size() < 20); } void Dialog::writeChars(const char *line) { - + assert(_lines.size() > 0); + strcpy(_lines[_lines.size() - 1].data, line); } void Dialog::addLine(const char *line) { @@ -56,7 +64,7 @@ bool Dialog::matchCommand(const char *s1, const char *s2) { return strncmp(s1, s2, strlen(s2)) == 0; } -Dialog::Dialog(M4Engine *vm, const char *msgData): View(vm, Common::Rect(100, 80, 220, 140)) { +Dialog::Dialog(M4Engine *vm, const char *msgData): View(vm, Common::Rect(0, 0, 0, 0)) { assert(msgData); const char *srcP = msgData; bool skipLine = false; @@ -64,9 +72,11 @@ Dialog::Dialog(M4Engine *vm, const char *msgData): View(vm, Common::Rect(100, 80 bool cmdFlag = false; bool crFlag = false; - _dialogTitleId = 0; - _numLines = 0; + _screenType = LAYER_DIALOG; + _widthChars = 0; _dialogIndex = 0; + _askPosition.x = 0; + _askPosition.y = 0; char dialogLine[256]; char cmdText[80]; @@ -105,7 +115,8 @@ Dialog::Dialog(M4Engine *vm, const char *msgData): View(vm, Common::Rect(100, 80 // Title command int id = atoi(cmdText + 5); if (id > 0) - _dialogTitleId = id; + // Suffix provided - specifies the dialog width in number of chars + _widthChars = id; } else if (matchCommand(cmdText, "CR")) { // CR command if (skipLine) @@ -137,14 +148,90 @@ Dialog::Dialog(M4Engine *vm, const char *msgData): View(vm, Common::Rect(100, 80 if (!skipLine) incLine(); + + // FIXME: Remove dummy dialog test string + incLine(); + strcpy(_lines[_lines.size() - 1].data, "Test dialog"); + _lines[_lines.size() - 1].xp = 20; + draw(); } +Dialog::~Dialog() { + _vm->_palette->deleteRange(_palette); + delete _palette; +} + void Dialog::draw() { - // TODO: Implement rendering of dialog correctly - this->fillRect(Common::Rect(0, 0, width(), height()), 0); - _vm->_font->setColors(5, 5, 0xff); - _vm->_font->writeString(this, "This will be a dialog", 10, 10, 0, 0); + _vm->_font->setFont(FONT_INTERFACE_MADS); + + // Set up the palette for this view + _palette = new RGBList(8, NULL); + _palette->setRange(0, 8, DIALOG_PALETTE); + _vm->_palette->addRange(_palette); + + // Calculate bounds + int dlgWidth = _widthChars * (_vm->_font->getMaxWidth() + 1) + 10; + int dlgHeight = (_lines.size() + 1) * (_vm->_font->getHeight() + 1) + 10; + int dialogX = (_vm->_screen->width() - dlgWidth) / 2; + int dialogY = (_vm->_screen->height() - dlgHeight) / 2; + + // Create the surface for the dialog + create(dlgWidth, dlgHeight, 1); + _coords.left = dialogX; + _coords.top = dialogY; + _coords.right = dialogX + dlgWidth + 1; + _coords.bottom = dialogY + dlgHeight + 1; + + // Ask position + //int askY = (_vm->_font->getHeight() + 1) * _askPosition.y + 3; + + // Set up the dialog + fillRect(Common::Rect(0, 0, width(), height()), 3); + setColour(2); + hLine(1, width() - 1, height() - 2); // Bottom edge + hLine(0, width(), height() - 1); + vLine(width() - 2, 2, height()); // Right edge + vLine(width() - 1, 1, height()); + + // Render dialog interior + uint16 seed = 0xb78e; + for (int yp = 2; yp < (height() - 2); ++yp) { + byte *destP = this->getBasePtr(2, yp); + + for (int xp = 2; xp < (width() - 2); ++xp) { + // Adjust the random seed + uint16 v = seed; + seed += 0x181D; + v = ROR16(v, 9); + seed = (seed ^ v) + ROR16(v, 3); + + *destP++ = ((seed & 0x10) != 0) ? 1 : 0; + } + } + + // Handle drawing the text contents + _vm->_font->setColours(7, 7, 7); + setColour(7); + + for (uint lineCtr = 0, yp = 5; lineCtr < _lines.size(); ++lineCtr, yp += _vm->_font->getHeight() + 1) { + + if (_lines[lineCtr].xp == 0xff) { + hLine(2, width() - 6, ((_vm->_font->getHeight() + 1) >> 1) + yp); + } else { + Common::Point pt(_lines[lineCtr].xp & 0x7f, yp + + (((_lines[lineCtr].xp & 0x40) != 0) ? 1 : 0)); + + _vm->_font->writeString(this, _lines[lineCtr].data, pt.x, pt.y, 0, 0); + + if (_lines[lineCtr].xp & 0x80) + // Underline needed + hLine(pt.x, pt.x + _vm->_font->getWidth(_lines[lineCtr].data), pt.y); + } + } + + // Do final translation of the dialog to game palette + this->translate(_palette); } bool Dialog::onEvent(M4EventType eventType, int param1, int x, int y, bool &captureEvents) { diff --git a/engines/m4/dialogs.h b/engines/m4/dialogs.h index f25821e3a9..beb87ae17e 100644 --- a/engines/m4/dialogs.h +++ b/engines/m4/dialogs.h @@ -28,14 +28,26 @@ #include "m4/m4.h" #include "m4/viewmgr.h" +#include "common/list.h" namespace M4 { +class DialogLine { +public: + char data[100]; + uint8 xp; + + DialogLine() { data[0] = '\0'; xp = 0; } +}; + class Dialog: public View { private: - int _numLines; - int _dialogTitleId; + Common::Array<DialogLine> _lines; + int _widthChars; int _dialogIndex; + Common::Point _askPosition; + RGBList *_palette; + void initDialog(); void incLine(); @@ -45,7 +57,7 @@ private: void draw(); public: Dialog(M4Engine *vm, const char *msgData); - virtual ~Dialog() {} + virtual ~Dialog(); bool onEvent(M4EventType eventType, int param1, int x, int y, bool &captureEvents); }; diff --git a/engines/m4/font.h b/engines/m4/font.h index 75321d820c..f75e76e425 100644 --- a/engines/m4/font.h +++ b/engines/m4/font.h @@ -64,9 +64,12 @@ public: void setFont(const char *filename); void setColor(uint8 color); void setColors(uint8 alt1, uint8 alt2, uint8 foreground); + void setColour(uint8 colour) { setColor(colour); } + void setColours(uint8 alt1, uint8 alt2, uint8 foreground) { setColors(alt1, alt2, foreground); } int32 getWidth(char *text, int spaceWidth = -1); int32 getHeight() const { return _maxHeight; } + int32 getMaxWidth() const { return _maxWidth; } int32 write(M4Surface *surface, const char *text, int x, int y, int width, int spaceWidth, uint8 colors[]); int32 writeString(M4Surface *surface, const char *text, int x, int y, int width = 0, int spaceWidth = -1) { return write(surface, text, x, y, width, spaceWidth, _fontColors); diff --git a/engines/m4/graphics.cpp b/engines/m4/graphics.cpp index 5a6f598731..eb66a2e20e 100644 --- a/engines/m4/graphics.cpp +++ b/engines/m4/graphics.cpp @@ -59,6 +59,12 @@ RGBList::~RGBList() { delete[] _palIndexes; } +void RGBList::setRange(int start, int count, const RGB8 *src) { + assert((start + count) <= _size); + + Common::copy(&src[0], &src[count], &_data[start]); +} + //-------------------------------------------------------------------------- #define VGA_COLOR_TRANS(x) (x == 0x3f ? 255 : x << 2) diff --git a/engines/m4/graphics.h b/engines/m4/graphics.h index a6c5973a18..47253c4ed0 100644 --- a/engines/m4/graphics.h +++ b/engines/m4/graphics.h @@ -66,6 +66,8 @@ public: RGB8 *data() { return _data; } byte *palIndexes() { return _palIndexes; } int size() { return _size; } + RGB8 &operator[](int idx) { return _data[idx]; } + void setRange(int start, int count, const RGB8 *src); }; // M4Surface @@ -113,6 +115,7 @@ public: void madsloadInterface(int index, RGBList **palData); void setColor(byte value) { _color = value; } + void setColour(byte value) { _color = value; } inline byte getColor() const { return _color; } void vLine(int x, int y1, int y2); void hLine(int x1, int x2, int y); diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp index e233680493..843bc9c1d7 100644 --- a/engines/m4/scene.cpp +++ b/engines/m4/scene.cpp @@ -76,7 +76,7 @@ Scene::~Scene() { if (_sceneSprites) delete _sceneSprites; - _vm->_palette->deleteAllRanges(); +// _vm->_palette->deleteAllRanges(); if (_palData) delete _palData; @@ -558,7 +558,8 @@ bool Scene::onEvent(M4EventType eventType, int param1, int x, int y, bool &captu _vm->_interfaceView->_inventory.clearSelected(); } else { // ***DEBUG*** - sample dialog display - const char *msg = _vm->_globals->loadMessage(10); + int idx = _vm->_globals->messageIndexOf(0x277a); + const char *msg = _vm->_globals->loadMessage(idx); Dialog *dlg = new Dialog(_vm, msg); _vm->_viewManager->addView(dlg); _vm->_viewManager->moveToFront(dlg); @@ -840,6 +841,9 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) { _vm->_font->setFont(FONT_INTERFACE_MADS); char buffer[100]; + // Check to see if any dialog is currently active + bool dialogVisible = _vm->_viewManager->getView(LAYER_DIALOG) != NULL; + // Highlighting logic for action list int actionIndex = 0; for (int x = 0; x < 2; ++x) { @@ -901,7 +905,7 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) { M4Sprite *spr = _objectSprites->getFrame(_objectFrameNumber / INV_ANIM_FRAME_SPEED); spr->copyTo(destSurface, INVENTORY_X, INVENTORY_Y, 0); - if (!_vm->_globals->invObjectsStill) { + if (!_vm->_globals->invObjectsStill && !dialogVisible) { // If objetcs are to animated, move to the next frame if (++_objectFrameNumber >= (_objectSprites->getCount() * INV_ANIM_FRAME_SPEED)) _objectFrameNumber = 0; diff --git a/engines/m4/viewmgr.h b/engines/m4/viewmgr.h index 61dcc49ab2..59bd02019b 100644 --- a/engines/m4/viewmgr.h +++ b/engines/m4/viewmgr.h @@ -45,7 +45,7 @@ enum {SCREEN_DIALOG, SCREEN_BUFFER, SCREEN_TEXT, SCREEN_TRANSPARENT}; enum ScreenEventType {SCREVENT_NONE = 0, SCREVENT_KEY = 1, SCREVENT_MOUSE = 2, SCREVENT_ALL = 3}; enum ScreenLayers { LAYER_BACKGROUND = 0, LAYER_DRIFTER = 1, LAYER_INTERFACE = 1, LAYER_FLOATER = 2, - LAYER_SURFACE = 3, LAYER_MENU = 9, LAYER_MOUSE = 15 + LAYER_SURFACE = 3, LAYER_MENU = 9, LAYER_DIALOG = 10, LAYER_MOUSE = 15 }; enum ViewIds { |