aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/m4/dialogs.cpp109
-rw-r--r--engines/m4/dialogs.h18
-rw-r--r--engines/m4/font.h3
-rw-r--r--engines/m4/graphics.cpp6
-rw-r--r--engines/m4/graphics.h3
-rw-r--r--engines/m4/scene.cpp10
-rw-r--r--engines/m4/viewmgr.h2
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 {