aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorMartin Kiewitz2009-10-28 12:58:13 +0000
committerMartin Kiewitz2009-10-28 12:58:13 +0000
commitc6f96d6ac39cfe24d38d30a4b6cc7a0c707f181a (patch)
treebc62b94360a4a162e866013d3eabab9ab23b00ed /engines/sci
parentc781f013210faa35bff381ca2b537e2f40750bf5 (diff)
downloadscummvm-rg350-c6f96d6ac39cfe24d38d30a4b6cc7a0c707f181a.tar.gz
scummvm-rg350-c6f96d6ac39cfe24d38d30a4b6cc7a0c707f181a.tar.bz2
scummvm-rg350-c6f96d6ac39cfe24d38d30a4b6cc7a0c707f181a.zip
SCI/newgui: SciGuiControls created, SciGuiText now active
svn-id: r45457
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/gui/gui.cpp42
-rw-r--r--engines/sci/gui/gui.h11
-rw-r--r--engines/sci/gui/gui_controls.cpp231
-rw-r--r--engines/sci/gui/gui_controls.h60
-rw-r--r--engines/sci/gui/gui_gfx.cpp548
-rw-r--r--engines/sci/gui/gui_gfx.h49
-rw-r--r--engines/sci/gui/gui_text.cpp367
-rw-r--r--engines/sci/gui/gui_text.h30
-rw-r--r--engines/sci/gui/gui_windowmgr.cpp17
-rw-r--r--engines/sci/gui/gui_windowmgr.h5
-rw-r--r--engines/sci/module.mk1
11 files changed, 738 insertions, 623 deletions
diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp
index 40434de5ff..4c3ed22999 100644
--- a/engines/sci/gui/gui.cpp
+++ b/engines/sci/gui/gui.cpp
@@ -36,6 +36,8 @@
#include "sci/gui/gui_gfx.h"
#include "sci/gui/gui_windowmgr.h"
#include "sci/gui/gui_animate.h"
+#include "sci/gui/gui_controls.h"
+#include "sci/gui/gui_text.h"
#include "sci/gui/gui_transitions.h"
#include "sci/gui/gui_view.h"
@@ -56,7 +58,11 @@ SciGui::SciGui(EngineState *state, SciGuiScreen *screen, SciGuiPalette *palette,
_gfx = new SciGuiGfx(_s, _screen, _palette);
_transitions = new SciGuiTransitions(this, _screen, _palette, _s->resMan->isVGA());
_animate = new SciGuiAnimate(_s, _gfx, _screen, _palette);
- _windowMgr = new SciGuiWindowMgr(_screen, _gfx, _animate);
+ _text = new SciGuiText(_s->resMan, _gfx, _screen);
+ _windowMgr = new SciGuiWindowMgr(_screen, _gfx, _animate, _text);
+ _controls = new SciGuiControls(_s->_segMan, _gfx, _text);
+ _gfx->init(_text);
+ _windowMgr->init();
// _gui32 = new SciGui32(_s, _screen, _palette, _cursor); // for debug purposes
}
@@ -212,7 +218,7 @@ void SciGui::display(const char *text, int argc, reg_t *argv) {
argc--; argv++;
break;
case SCI_DISPLAY_SETFONT:
- _gfx->SetFont(argv[0].toUint16());
+ _text->SetFont(argv[0].toUint16());
argc--; argv++;
break;
case SCI_DISPLAY_WIDTH:
@@ -240,7 +246,7 @@ void SciGui::display(const char *text, int argc, reg_t *argv) {
}
// now drawing the text
- _gfx->TextSize(rect, text, -1, width);
+ _text->Size(rect, text, -1, width);
rect.moveTo(_gfx->GetPort()->curLeft, _gfx->GetPort()->curTop);
_gfx->Move(rect.right <= _screen->_width ? 0 : _screen->_width - rect.right, rect.bottom <= _screen->_height ? 0 : _screen->_width - rect.bottom);
rect.moveTo(_gfx->GetPort()->curLeft, _gfx->GetPort()->curTop);
@@ -249,7 +255,7 @@ void SciGui::display(const char *text, int argc, reg_t *argv) {
_s->r_acc = _gfx->BitsSave(rect, SCI_SCREEN_MASK_VISUAL);
if (bgcolor != -1)
_gfx->FillRect(rect, SCI_SCREEN_MASK_VISUAL, bgcolor, 0, 0);
- _gfx->TextBox(text, 0, rect, alignment, -1);
+ _text->Box(text, 0, rect, alignment, -1);
if (_screen->_picNotValid == 0 && bRedraw)
_gfx->BitsShow(rect);
// restoring port and cursor pos
@@ -263,18 +269,18 @@ void SciGui::display(const char *text, int argc, reg_t *argv) {
void SciGui::textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight) {
Common::Rect rect(0, 0, *textWidth, *textHeight);
- _gfx->TextSize(rect, text, font, maxWidth);
+ _text->Size(rect, text, font, maxWidth);
*textWidth = rect.width(); *textHeight = rect.height();
}
// Used SCI1+ for text codes
void SciGui::textFonts(int argc, reg_t *argv) {
- _gfx->SetTextFonts(argc, argv);
+ _text->CodeSetFonts(argc, argv);
}
// Used SCI1+ for text codes
void SciGui::textColors(int argc, reg_t *argv) {
- _gfx->SetTextColors(argc, argv);
+ _text->CodeSetColors(argc, argv);
}
void SciGui::drawStatus(const char *text, int16 colorPen, int16 colorBack) {
@@ -283,7 +289,7 @@ void SciGui::drawStatus(const char *text, int16 colorPen, int16 colorBack) {
_gfx->FillRect(_gfx->_menuRect, 1, colorBack);
_gfx->PenColor(colorPen);
_gfx->MoveTo(0, 1);
- _gfx->Draw_String(text);
+ _text->Draw_String(text);
_gfx->BitsShow(_gfx->_menuRect);
_gfx->SetPort(oldPort);
}
@@ -323,7 +329,7 @@ void SciGui::drawControlButton(Common::Rect rect, reg_t obj, const char *text, i
_gfx->FrameRect(rect);
rect.grow(-2);
_gfx->TextFace(style & 1 ? 0 : 1);
- _gfx->TextBox(text, 0, rect, SCI_TEXT_ALIGNMENT_CENTER, fontId);
+ _text->Box(text, 0, rect, SCI_TEXT_ALIGNMENT_CENTER, fontId);
_gfx->TextFace(0);
rect.grow(1);
if (style & 8) // selected
@@ -343,7 +349,7 @@ void SciGui::drawControlText(Common::Rect rect, reg_t obj, const char *text, int
rect.grow(1);
_gfx->EraseRect(rect);
rect.grow(-1);
- _gfx->TextBox(text, 0, rect, alignment, fontId);
+ _text->Box(text, 0, rect, alignment, fontId);
if (style & 8) { // selected
_gfx->FrameRect(rect);
}
@@ -358,18 +364,18 @@ void SciGui::drawControlText(Common::Rect rect, reg_t obj, const char *text, int
void SciGui::drawControlTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) {
Common::Rect textRect = rect;
- uint16 oldFontId = _gfx->GetFontId();
+ uint16 oldFontId = _text->GetFontId();
rect.grow(1);
- _gfx->TexteditCursorErase();
+ _controls->TexteditCursorErase();
_gfx->EraseRect(rect);
- _gfx->TextBox(text, 0, textRect, SCI_TEXT_ALIGNMENT_LEFT, fontId);
+ _text->Box(text, 0, textRect, SCI_TEXT_ALIGNMENT_LEFT, fontId);
_gfx->FrameRect(rect);
if (style & 8) {
- _gfx->SetFont(fontId);
+ _text->SetFont(fontId);
rect.grow(-1);
- _gfx->TexteditCursorDraw(rect, text, cursorPos);
- _gfx->SetFont(oldFontId);
+ _controls->TexteditCursorDraw(rect, text, cursorPos);
+ _text->SetFont(oldFontId);
rect.grow(1);
}
if (_screen->_picNotValid == 0)
@@ -392,7 +398,7 @@ void SciGui::drawControlIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId,
void SciGui::drawControlList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite) {
if (!hilite) {
- _gfx->drawListControl(rect, obj, maxChars, count, entries, fontId, upperPos, cursorPos, isAlias);
+ _controls->drawListControl(rect, obj, maxChars, count, entries, fontId, upperPos, cursorPos, isAlias);
rect.grow(1);
if (isAlias && (style & 8)) {
_gfx->FrameRect(rect);
@@ -408,7 +414,7 @@ void SciGui::editControl(reg_t controlObject, reg_t eventObject) {
switch (controlType) {
case SCI_CONTROLS_TYPE_TEXTEDIT:
// Only process textedit controls in here
- _gfx->TexteditChange(controlObject, eventObject);
+ _controls->TexteditChange(controlObject, eventObject);
return;
}
}
diff --git a/engines/sci/gui/gui.h b/engines/sci/gui/gui.h
index 08ac12686a..6c5ac46bdf 100644
--- a/engines/sci/gui/gui.h
+++ b/engines/sci/gui/gui.h
@@ -45,10 +45,11 @@ class SciGuiScreen;
class SciGuiPalette;
class SciGuiCursor;
class SciGuiGfx;
-class SciGuiresources;
class SciGuiWindowMgr;
-class SciGuiTransitions;
class SciGuiAnimate;
+class SciGuiControls;
+class SciGuiText;
+class SciGuiTransitions;
class SciGui32; // for debug purposes
class SciGui {
@@ -147,10 +148,12 @@ private:
virtual void addToPicSetPicNotValid();
SciGuiGfx *_gfx;
- SciGuiresources *_resources;
+// SciGuiresources *_resources;
SciGuiWindowMgr *_windowMgr;
- SciGuiTransitions *_transitions;
SciGuiAnimate *_animate;
+ SciGuiControls *_controls;
+ SciGuiText *_text;
+ SciGuiTransitions *_transitions;
// SciGui32 *_gui32; // for debug purposes
bool _usesOldGfxFunctions;
diff --git a/engines/sci/gui/gui_controls.cpp b/engines/sci/gui/gui_controls.cpp
new file mode 100644
index 0000000000..906cbc1257
--- /dev/null
+++ b/engines/sci/gui/gui_controls.cpp
@@ -0,0 +1,231 @@
+/* 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 "common/stack.h"
+#include "graphics/primitives.h"
+
+#include "sci/sci.h"
+#include "sci/engine/state.h"
+#include "sci/gui/gui_gfx.h"
+#include "sci/gui/gui_font.h"
+#include "sci/gui/gui_text.h"
+#include "sci/gui/gui_controls.h"
+
+namespace Sci {
+
+SciGuiControls::SciGuiControls(SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text)
+ : _segMan(segMan), _gfx(gfx), _text(text) {
+ init();
+}
+
+SciGuiControls::~SciGuiControls() {
+}
+
+void SciGuiControls::init() {
+ _texteditCursorVisible = false;
+}
+
+const char controlListUpArrow[2] = { 0x18, 0 };
+const char controlListDownArrow[2] = { 0x19, 0 };
+
+void SciGuiControls::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias) {
+ //SegManager *segMan = _s->_segMan;
+ Common::Rect workerRect = rect;
+ GuiResourceId oldFontId = _text->GetFontId();
+ int16 oldPenColor = _gfx->_curPort->penClr;
+ uint16 fontSize = 0;
+ int16 i;
+ const char *listEntry;
+ int16 listEntryLen;
+ int16 lastYpos;
+
+ // draw basic window
+ _gfx->EraseRect(workerRect);
+ workerRect.grow(1);
+ _gfx->FrameRect(workerRect);
+
+ // draw UP/DOWN arrows
+ // we draw UP arrow one pixel lower than sierra did, because it looks nicer. Also the DOWN arrow has one pixel
+ // line inbetween as well
+ workerRect.top++;
+ _text->Box(controlListUpArrow, 0, workerRect, SCI_TEXT_ALIGNMENT_CENTER, 0);
+ workerRect.top = workerRect.bottom - 10;
+ _text->Box(controlListDownArrow, 0, workerRect, SCI_TEXT_ALIGNMENT_CENTER, 0);
+
+ // Draw inner lines
+ workerRect.top = rect.top + 9;
+ workerRect.bottom -= 10;
+ _gfx->FrameRect(workerRect);
+ workerRect.grow(-1);
+
+ _text->SetFont(fontId);
+ fontSize = _gfx->_curPort->fontHeight;
+ _gfx->PenColor(_gfx->_curPort->penClr); _gfx->BackColor(_gfx->_curPort->backClr);
+ workerRect.bottom = workerRect.top + 9;
+ lastYpos = rect.bottom - fontSize;
+
+ // Write actual text
+ for (i = upperPos; i < count; i++) {
+ _gfx->EraseRect(workerRect);
+ listEntry = entries[i];
+ if (listEntry[0]) {
+ _gfx->MoveTo(workerRect.left, workerRect.top);
+ listEntryLen = strlen(listEntry);
+ _text->Draw(listEntry, 0, MIN(maxChars, listEntryLen), oldFontId, oldPenColor);
+ if ((!isAlias) && (i == cursorPos)) {
+ _gfx->InvertRect(workerRect);
+ }
+ }
+ workerRect.translate(0, fontSize);
+ if (workerRect.bottom > lastYpos)
+ break;
+ }
+
+ _text->SetFont(oldFontId);
+}
+
+void SciGuiControls::TexteditCursorDraw (Common::Rect rect, const char *text, uint16 curPos) {
+ int16 textWidth, i;
+ if (!_texteditCursorVisible) {
+ textWidth = 0;
+ for (i = 0; i < curPos; i++) {
+ textWidth += _text->_font->getCharWidth(text[i]);
+ }
+ _texteditCursorRect.left = rect.left + textWidth;
+ _texteditCursorRect.top = rect.top;
+ _texteditCursorRect.bottom = _texteditCursorRect.top + _text->_font->getHeight();
+ _texteditCursorRect.right = _texteditCursorRect.left + (text[curPos] == 0 ? 1 : _text->_font->getCharWidth(text[curPos]));
+ _gfx->InvertRect(_texteditCursorRect);
+ _gfx->BitsShow(_texteditCursorRect);
+ _texteditCursorVisible = true;
+ TexteditSetBlinkTime();
+ }
+}
+
+void SciGuiControls::TexteditCursorErase() {
+ if (_texteditCursorVisible) {
+ _gfx->InvertRect(_texteditCursorRect);
+ _gfx->BitsShow(_texteditCursorRect);
+ _texteditCursorVisible = false;
+ }
+ TexteditSetBlinkTime();
+}
+
+void SciGuiControls::TexteditSetBlinkTime() {
+ _texteditBlinkTime = g_system->getMillis() + (30 * 1000 / 60);
+}
+
+void SciGuiControls::TexteditChange(reg_t controlObject, reg_t eventObject) {
+ uint16 cursorPos = GET_SEL32V(_segMan, controlObject, cursor);
+ uint16 maxChars = GET_SEL32V(_segMan, controlObject, max);
+ reg_t textReference = GET_SEL32(_segMan, controlObject, text);
+ Common::String text;
+ uint16 textSize, eventType, eventKey;
+ bool textChanged = false;
+ Common::Rect rect;
+
+ if (textReference.isNull())
+ error("kEditControl called on object that doesnt have a text reference");
+ text = _segMan->getString(textReference);
+
+ if (!eventObject.isNull()) {
+ textSize = text.size();
+ eventType = GET_SEL32V(_segMan, eventObject, type);
+
+ switch (eventType) {
+ case SCI_EVT_MOUSE_PRESS:
+ // TODO: Implement mouse support for cursor change
+ break;
+ case SCI_EVT_KEYBOARD:
+ eventKey = GET_SEL32V(_segMan, eventObject, message);
+ switch (eventKey) {
+ case SCI_K_BACKSPACE:
+ if (cursorPos > 0) {
+ cursorPos--; text.deleteChar(cursorPos);
+ textChanged = true;
+ }
+ break;
+ case SCI_K_DELETE:
+ text.deleteChar(cursorPos);
+ textChanged = true;
+ break;
+ case SCI_K_HOME: // HOME
+ cursorPos = 0; textChanged = true;
+ break;
+ case SCI_K_END: // END
+ cursorPos = textSize; textChanged = true;
+ break;
+ case SCI_K_LEFT: // LEFT
+ if (cursorPos > 0) {
+ cursorPos--; textChanged = true;
+ }
+ break;
+ case SCI_K_RIGHT: // RIGHT
+ if (cursorPos + 1 <= textSize) {
+ cursorPos++; textChanged = true;
+ }
+ break;
+ default:
+ if (eventKey > 31 && eventKey < 256 && textSize < maxChars) {
+ // insert pressed character
+ // we check, if there is space left for this character
+
+ text.insertChar(eventKey, cursorPos++);
+ textChanged = true;
+ }
+ break;
+ }
+ break;
+ }
+ }
+
+ if (textChanged) {
+ GuiResourceId oldFontId = _text->GetFontId();
+ GuiResourceId fontId = GET_SEL32V(_segMan, controlObject, font);
+ rect = Common::Rect(GET_SEL32V(_segMan, controlObject, nsLeft), GET_SEL32V(_segMan, controlObject, nsTop),
+ GET_SEL32V(_segMan, controlObject, nsRight), GET_SEL32V(_segMan, controlObject, nsBottom));
+ TexteditCursorErase();
+ _gfx->EraseRect(rect);
+ _text->Box(text.c_str(), 0, rect, SCI_TEXT_ALIGNMENT_LEFT, fontId);
+ _gfx->BitsShow(rect);
+ _text->SetFont(fontId);
+ TexteditCursorDraw(rect, text.c_str(), cursorPos);
+ _text->SetFont(oldFontId);
+ // Write back string
+ _segMan->strcpy(textReference, text.c_str());
+ } else {
+ if (g_system->getMillis() >= _texteditBlinkTime) {
+ _gfx->InvertRect(_texteditCursorRect);
+ _gfx->BitsShow(_texteditCursorRect);
+ _texteditCursorVisible = !_texteditCursorVisible;
+ TexteditSetBlinkTime();
+ }
+ }
+
+ PUT_SEL32V(_segMan, controlObject, cursor, cursorPos);
+}
+
+} // End of namespace Sci
diff --git a/engines/sci/gui/gui_controls.h b/engines/sci/gui/gui_controls.h
new file mode 100644
index 0000000000..426cd6b96e
--- /dev/null
+++ b/engines/sci/gui/gui_controls.h
@@ -0,0 +1,60 @@
+/* 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$
+ *
+ */
+
+#ifndef SCI_GUI_CONTROLS_H
+#define SCI_GUI_CONTROLS_H
+
+namespace Sci {
+
+class SciGuiGfx;
+class SciGuiFont;
+class SciGuiText;
+class SciGuiControls {
+public:
+ SciGuiControls(SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text);
+ ~SciGuiControls();
+
+ void drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias);
+ void TexteditCursorDraw (Common::Rect rect, const char *text, uint16 curPos);
+ void TexteditCursorErase();
+ void TexteditChange(reg_t controlObject, reg_t eventObject);
+
+private:
+ void init(void);
+ void TexteditSetBlinkTime();
+
+ SegManager *_segMan;
+ SciGuiGfx *_gfx;
+ SciGuiText *_text;
+
+ // Textedit-Control related
+ Common::Rect _texteditCursorRect;
+ bool _texteditCursorVisible;
+ uint32 _texteditBlinkTime;
+};
+
+} // End of namespace Sci
+
+#endif
diff --git a/engines/sci/gui/gui_gfx.cpp b/engines/sci/gui/gui_gfx.cpp
index 3eb69f0553..36df1492b1 100644
--- a/engines/sci/gui/gui_gfx.cpp
+++ b/engines/sci/gui/gui_gfx.cpp
@@ -36,12 +36,12 @@
#include "sci/gui/gui_view.h"
#include "sci/gui/gui_screen.h"
#include "sci/gui/gui_palette.h"
+#include "sci/gui/gui_text.h"
namespace Sci {
SciGuiGfx::SciGuiGfx(EngineState *state, SciGuiScreen *screen, SciGuiPalette *palette)
: _s(state), _screen(screen), _palette(palette) {
- init();
}
SciGuiGfx::~SciGuiGfx() {
@@ -49,12 +49,8 @@ SciGuiGfx::~SciGuiGfx() {
delete _menuPort;
}
-void SciGuiGfx::init() {
- _font = NULL;
- _textFonts = NULL; _textFontsCount = 0;
- _textColors = NULL; _textColorsCount = 0;
-
- _texteditCursorVisible = false;
+void SciGuiGfx::init(SciGuiText *text) {
+ _text = text;
// _mainPort is not known to windowmanager, that's okay according to sierra sci
// its not even used currently in our engine
@@ -65,7 +61,7 @@ void SciGuiGfx::init() {
// _menuPort has actually hardcoded id 0xFFFF. Its not meant to be known to windowmanager according to sierra sci
_menuPort = new GuiPort(0xFFFF);
OpenPort(_menuPort);
- SetFont(0);
+ _text->SetFont(0);
_menuPort->rect = Common::Rect(0, 0, _screen->_width, _screen->_height);
_menuRect = Common::Rect(0, 0, _screen->_width, 9);
}
@@ -95,32 +91,13 @@ void SciGuiGfx::Move(int16 left, int16 top) {
_curPort->curLeft += left;
}
-GuiResourceId SciGuiGfx::GetFontId() {
- return _curPort->fontId;
-}
-
-SciGuiFont *SciGuiGfx::GetFont() {
- if ((_font == NULL) || (_font->getResourceId() != _curPort->fontId))
- _font = new SciGuiFont(_s->resMan, _curPort->fontId);
-
- return _font;
-}
-
-void SciGuiGfx::SetFont(GuiResourceId fontId) {
- if ((_font == NULL) || (_font->getResourceId() != fontId))
- _font = new SciGuiFont(_s->resMan, fontId);
-
- _curPort->fontId = _font->getResourceId();
- _curPort->fontHeight = _font->getHeight();
-}
-
void SciGuiGfx::OpenPort(GuiPort *port) {
port->fontId = 0;
port->fontHeight = 8;
GuiPort *tmp = _curPort;
_curPort = port;
- SetFont(port->fontId);
+ _text->SetFont(port->fontId);
_curPort = tmp;
port->top = 0;
@@ -257,331 +234,6 @@ void SciGuiGfx::OffsetLine(Common::Point &start, Common::Point &end) {
end.y += _curPort->top;
}
-//-----------------------------
-
-void SciGuiGfx::ClearChar(int16 chr) {
- if (_curPort->penMode != 1)
- return;
- Common::Rect rect;
- rect.top = _curPort->curTop;
- rect.bottom = rect.top + _curPort->fontHeight;
- rect.left = _curPort->curLeft;
- rect.right = rect.left + GetFont()->getCharWidth(chr);
- EraseRect(rect);
-}
-
-void SciGuiGfx::DrawChar(int16 chr) {
- chr = chr & 0xFF;
- ClearChar(chr);
- StdChar(chr);
- _curPort->curLeft += GetFont()->getCharWidth(chr);
-}
-
-void SciGuiGfx::StdChar(int16 chr) {
-#if 0
- CResFont*res = getResFont();
- if (res)
- res->Draw(chr, _curPort->top + _curPort->curTop, _curPort->left
- + _curPort->curLeft, _vSeg, 320, _curPort->penClr,
- _curPort->textFace);
-#endif
-}
-
-void SciGuiGfx::SetTextFonts(int argc, reg_t *argv) {
- int i;
-
- if (_textFonts) {
- delete _textFonts;
- }
- _textFontsCount = argc;
- _textFonts = new GuiResourceId[argc];
- for (i = 0; i < argc; i++) {
- _textFonts[i] = (GuiResourceId)argv[i].toUint16();
- }
-}
-
-void SciGuiGfx::SetTextColors(int argc, reg_t *argv) {
- int i;
-
- if (_textColors) {
- delete _textColors;
- }
- _textColorsCount = argc;
- _textColors = new uint16[argc];
- for (i = 0; i < argc; i++) {
- _textColors[i] = argv[i].toUint16();
- }
-}
-
-// This internal function gets called as soon as a '|' is found in a text
-// It will process the encountered code and set new font/set color
-// We only support one-digit codes currently, don't know if multi-digit codes are possible
-// Returns textcode character count
-int16 SciGuiGfx::TextCodeProcessing(const char *&text, GuiResourceId orgFontId, int16 orgPenColor) {
- const char *textCode = text;
- int16 textCodeSize = 0;
- char curCode;
- unsigned char curCodeParm;
-
- // Find the end of the textcode
- while ((++textCodeSize) && (*text != 0) && (*text++ != 0x7C)) { }
-
- // possible TextCodes:
- // c -> sets textColor to current port pen color
- // cX -> sets textColor to _textColors[X-1]
- curCode = textCode[0];
- curCodeParm = textCode[1];
- if (isdigit(curCodeParm)) {
- curCodeParm -= '0';
- } else {
- curCodeParm = 0;
- }
- switch (curCode) {
- case 'c': // set text color
- if (curCodeParm == 0) {
- _curPort->penClr = orgPenColor;
- } else {
- if (curCodeParm < _textColorsCount) {
- _curPort->penClr = _textColors[curCodeParm];
- }
- }
- break;
- case 'f':
- if (curCodeParm == 0) {
- SetFont(orgFontId);
- } else {
- if (curCodeParm < _textFontsCount) {
- SetFont(_textFonts[curCodeParm]);
- }
- }
- break;
- }
- return textCodeSize;
-}
-
-// return max # of chars to fit maxwidth with full words
-int16 SciGuiGfx::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgFontId) {
- char curChar;
- int16 maxChars = 0, curCharCount = 0;
- uint16 width = 0;
- GuiResourceId oldFontId = GetFontId();
- int16 oldPenColor = _curPort->penClr;
-
- GetFont();
- if (!_font)
- return 0;
-
- while (width <= maxWidth) {
- curChar = *text++;
- switch (curChar) {
- case 0x7C:
- if (getSciVersion() >= SCI_VERSION_1_1) {
- curCharCount++;
- curCharCount += TextCodeProcessing(text, orgFontId, oldPenColor);
- continue;
- }
- break;
-
- case 0xD:
- curCharCount++;
- continue;
-
- case 0xA:
- curCharCount++;
- case 0:
- SetFont(oldFontId);
- PenColor(oldPenColor);
- return curCharCount;
-
- case ' ':
- maxChars = curCharCount + 1;
- break;
- }
- width += _font->getCharWidth(curChar);
- curCharCount++;
- }
- SetFont(oldFontId);
- PenColor(oldPenColor);
- return maxChars;
-}
-
-void SciGuiGfx::TextWidth(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight) {
- unsigned char curChar;
- GuiResourceId oldFontId = GetFontId();
- int16 oldPenColor = _curPort->penClr;
-
- textWidth = 0; textHeight = 0;
-
- GetFont();
- if (_font) {
- text += from;
- while (len--) {
- curChar = *text++;
- switch (curChar) {
- case 0x0A:
- case 0x0D:
- textHeight = MAX<int16> (textHeight, _curPort->fontHeight);
- break;
- case 0x7C:
- if (getSciVersion() >= SCI_VERSION_1_1) {
- len -= TextCodeProcessing(text, orgFontId, 0);
- break;
- }
- default:
- textHeight = MAX<int16> (textHeight, _curPort->fontHeight);
- textWidth += _font->getCharWidth(curChar);
- }
- }
- }
- SetFont(oldFontId);
- PenColor(oldPenColor);
- return;
-}
-
-void SciGuiGfx::StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight) {
- TextWidth(str, 0, (int16)strlen(str), orgFontId, textWidth, textHeight);
-}
-
-int16 SciGuiGfx::TextSize(Common::Rect &rect, const char *str, GuiResourceId fontId, int16 maxWidth) {
- GuiResourceId oldFontId = GetFontId();
- int16 oldPenColor = _curPort->penClr;
- int16 charCount;
- int16 maxTextWidth = 0, textWidth;
- int16 totalHeight = 0, textHeight;
-
- if (fontId != -1)
- SetFont(fontId);
- rect.top = rect.left = 0;
-
- if (maxWidth < 0) { // force output as single line
- StringWidth(str, oldFontId, textWidth, textHeight);
- rect.bottom = textHeight;
- rect.right = textWidth;
- } else {
- // rect.right=found widest line with RTextWidth and GetLongest
- // rect.bottom=num. lines * GetPointSize
- rect.right = (maxWidth ? maxWidth : 192);
- const char*p = str;
- while (*p) {
- //if (*p == 0xD || *p == 0xA) {
- // p++;
- // continue;
- //}
- charCount = GetLongest(p, rect.right, oldFontId);
- if (charCount == 0)
- break;
- TextWidth(p, 0, charCount, oldFontId, textWidth, textHeight);
- maxTextWidth = MAX(textWidth, maxTextWidth);
- totalHeight += textHeight;
- p += charCount;
- }
- rect.bottom = totalHeight;
- rect.right = maxWidth ? maxWidth : MIN(rect.right, maxTextWidth);
- }
- SetFont(oldFontId);
- PenColor(oldPenColor);
- return rect.right;
-}
-
-// returns maximum font height used
-void SciGuiGfx::DrawText(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor) {
- int16 curChar, charWidth;
- Common::Rect rect;
-
- GetFont();
- if (!_font)
- return;
-
- rect.top = _curPort->curTop;
- rect.bottom = rect.top + _curPort->fontHeight;
- text += from;
- while (len--) {
- curChar = (*text++);
- switch (curChar) {
- case 0x0A:
- case 0x0D:
- case 0:
- break;
- case 0x7C:
- if (getSciVersion() >= SCI_VERSION_1_1) {
- len -= TextCodeProcessing(text, orgFontId, orgPenColor);
- break;
- }
- default:
- charWidth = _font->getCharWidth(curChar);
- // clear char
- if (_curPort->penMode == 1) {
- rect.left = _curPort->curLeft;
- rect.right = rect.left + charWidth;
- EraseRect(rect);
- }
- // CharStd
- _font->draw(_screen, curChar, _curPort->top + _curPort->curTop, _curPort->left + _curPort->curLeft, _curPort->penClr, _curPort->textFace);
- _curPort->curLeft += charWidth;
- }
- }
-}
-
-// returns maximum font height used
-void SciGuiGfx::ShowText(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor) {
- Common::Rect rect;
-
- rect.top = _curPort->curTop;
- rect.bottom = rect.top + GetPointSize();
- rect.left = _curPort->curLeft;
- DrawText(text, from, len, orgFontId, orgPenColor);
- rect.right = _curPort->curLeft;
- BitsShow(rect);
-}
-
-// Draws a text in rect.
-void SciGuiGfx::TextBox(const char *text, int16 bshow, const Common::Rect &rect, GuiTextAlignment alignment, GuiResourceId fontId) {
- int16 textWidth, textHeight, charCount, offset;
- int16 hline = 0;
- GuiResourceId orgFontId = GetFontId();
- int16 orgPenColor = _curPort->penClr;
-
- if (fontId != -1)
- SetFont(fontId);
-
- while (*text) {
-// if (*text == 0xD || *text == 0xA) {
-// text++;
-// continue;
-// }
- charCount = GetLongest(text, rect.width(), orgFontId);
- if (charCount == 0)
- break;
- TextWidth(text, 0, charCount, orgFontId, textWidth, textHeight);
- switch (alignment) {
- case SCI_TEXT_ALIGNMENT_RIGHT:
- offset = rect.width() - textWidth;
- break;
- case SCI_TEXT_ALIGNMENT_CENTER:
- offset = (rect.width() - textWidth) / 2;
- break;
- case SCI_TEXT_ALIGNMENT_LEFT:
- offset = 0;
- break;
-
- default: // left-aligned
- warning("Invalid alignment %d used in TextBox()", alignment);
- }
- MoveTo(rect.left + offset, rect.top + hline);
-
- if (bshow) {
- ShowText(text, 0, charCount, orgFontId, orgPenColor);
- } else {
- DrawText(text, 0, charCount, orgFontId, orgPenColor);
- }
-
- hline += textHeight;
- text += charCount;
- }
- SetFont(orgFontId);
- PenColor(orgPenColor);
-}
-
void SciGuiGfx::BitsShow(const Common::Rect &rect) {
Common::Rect workerRect(rect.left, rect.top, rect.right, rect.bottom);
workerRect.clip(_curPort->rect);
@@ -644,15 +296,6 @@ void SciGuiGfx::BitsFree(GuiMemoryHandle memoryHandle) {
}
}
-void SciGuiGfx::Draw_String(const char *text) {
- GuiResourceId orgFontId = GetFontId();
- int16 orgPenColor = _curPort->penClr;
-
- DrawText(text, 0, strlen(text), orgFontId, orgPenColor);
- SetFont(orgFontId);
- PenColor(orgPenColor);
-}
-
void SciGuiGfx::drawPicture(GuiResourceId pictureId, int16 animationNr, bool mirroredFlag, bool addToFlag, GuiResourceId paletteId) {
SciGuiPicture *picture;
@@ -727,187 +370,6 @@ void SciGuiGfx::drawCel(SciGuiView *view, GuiViewLoopNo loopNo, GuiViewCelNo cel
view->draw(celRect, clipRect, clipRectTranslated, loopNo, celNo, priority, paletteNo);
}
-const char controlListUpArrow[2] = { 0x18, 0 };
-const char controlListDownArrow[2] = { 0x19, 0 };
-
-void SciGuiGfx::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias) {
- //SegManager *segMan = _s->_segMan;
- Common::Rect workerRect = rect;
- GuiResourceId oldFontId = GetFontId();
- int16 oldPenColor = _curPort->penClr;
- uint16 fontSize = 0;
- int16 i;
- const char *listEntry;
- int16 listEntryLen;
- int16 lastYpos;
-
- // draw basic window
- EraseRect(workerRect);
- workerRect.grow(1);
- FrameRect(workerRect);
-
- // draw UP/DOWN arrows
- // we draw UP arrow one pixel lower than sierra did, because it looks nicer. Also the DOWN arrow has one pixel
- // line inbetween as well
- workerRect.top++;
- TextBox(controlListUpArrow, 0, workerRect, SCI_TEXT_ALIGNMENT_CENTER, 0);
- workerRect.top = workerRect.bottom - 10;
- TextBox(controlListDownArrow, 0, workerRect, SCI_TEXT_ALIGNMENT_CENTER, 0);
-
- // Draw inner lines
- workerRect.top = rect.top + 9;
- workerRect.bottom -= 10;
- FrameRect(workerRect);
- workerRect.grow(-1);
-
- SetFont(fontId);
- fontSize = _curPort->fontHeight;
- PenColor(_curPort->penClr); BackColor(_curPort->backClr);
- workerRect.bottom = workerRect.top + 9;
- lastYpos = rect.bottom - fontSize;
-
- // Write actual text
- for (i = upperPos; i < count; i++) {
- EraseRect(workerRect);
- listEntry = entries[i];
- if (listEntry[0]) {
- MoveTo(workerRect.left, workerRect.top);
- listEntryLen = strlen(listEntry);
- DrawText(listEntry, 0, MIN(maxChars, listEntryLen), oldFontId, oldPenColor);
- if ((!isAlias) && (i == cursorPos)) {
- InvertRect(workerRect);
- }
- }
- workerRect.translate(0, fontSize);
- if (workerRect.bottom > lastYpos)
- break;
- }
-
- SetFont(oldFontId);
-}
-
-void SciGuiGfx::TexteditCursorDraw (Common::Rect rect, const char *text, uint16 curPos) {
- int16 textWidth, i;
- if (!_texteditCursorVisible) {
- textWidth = 0;
- for (i = 0; i < curPos; i++) {
- textWidth += _font->getCharWidth(text[i]);
- }
- _texteditCursorRect.left = rect.left + textWidth;
- _texteditCursorRect.top = rect.top;
- _texteditCursorRect.bottom = _texteditCursorRect.top + _font->getHeight();
- _texteditCursorRect.right = _texteditCursorRect.left + (text[curPos] == 0 ? 1 : _font->getCharWidth(text[curPos]));
- InvertRect(_texteditCursorRect);
- BitsShow(_texteditCursorRect);
- _texteditCursorVisible = true;
- TexteditSetBlinkTime();
- }
-}
-
-void SciGuiGfx::TexteditCursorErase() {
- if (_texteditCursorVisible) {
- InvertRect(_texteditCursorRect);
- BitsShow(_texteditCursorRect);
- _texteditCursorVisible = false;
- }
- TexteditSetBlinkTime();
-}
-
-void SciGuiGfx::TexteditSetBlinkTime() {
- _texteditBlinkTime = g_system->getMillis() + (30 * 1000 / 60);
-}
-
-void SciGuiGfx::TexteditChange(reg_t controlObject, reg_t eventObject) {
- SegManager *segMan = _s->_segMan;
- uint16 cursorPos = GET_SEL32V(segMan, controlObject, cursor);
- uint16 maxChars = GET_SEL32V(segMan, controlObject, max);
- reg_t textReference = GET_SEL32(segMan, controlObject, text);
- Common::String text;
- uint16 textSize, eventType, eventKey;
- bool textChanged = false;
- Common::Rect rect;
-
- if (textReference.isNull())
- error("kEditControl called on object that doesnt have a text reference");
- text = segMan->getString(textReference);
-
- if (!eventObject.isNull()) {
- textSize = text.size();
- eventType = GET_SEL32V(segMan, eventObject, type);
-
- switch (eventType) {
- case SCI_EVT_MOUSE_PRESS:
- // TODO: Implement mouse support for cursor change
- break;
- case SCI_EVT_KEYBOARD:
- eventKey = GET_SEL32V(segMan, eventObject, message);
- switch (eventKey) {
- case SCI_K_BACKSPACE:
- if (cursorPos > 0) {
- cursorPos--; text.deleteChar(cursorPos);
- textChanged = true;
- }
- break;
- case SCI_K_DELETE:
- text.deleteChar(cursorPos);
- textChanged = true;
- break;
- case SCI_K_HOME: // HOME
- cursorPos = 0; textChanged = true;
- break;
- case SCI_K_END: // END
- cursorPos = textSize; textChanged = true;
- break;
- case SCI_K_LEFT: // LEFT
- if (cursorPos > 0) {
- cursorPos--; textChanged = true;
- }
- break;
- case SCI_K_RIGHT: // RIGHT
- if (cursorPos + 1 <= textSize) {
- cursorPos++; textChanged = true;
- }
- break;
- default:
- if (eventKey > 31 && eventKey < 256 && textSize < maxChars) {
- // insert pressed character
- // we check, if there is space left for this character
-
- text.insertChar(eventKey, cursorPos++);
- textChanged = true;
- }
- break;
- }
- break;
- }
- }
-
- if (textChanged) {
- GuiResourceId oldFontId = GetFontId();
- GuiResourceId fontId = GET_SEL32V(segMan, controlObject, font);
- rect = Common::Rect(GET_SEL32V(segMan, controlObject, nsLeft), GET_SEL32V(segMan, controlObject, nsTop),
- GET_SEL32V(segMan, controlObject, nsRight), GET_SEL32V(segMan, controlObject, nsBottom));
- TexteditCursorErase();
- EraseRect(rect);
- TextBox(text.c_str(), 0, rect, SCI_TEXT_ALIGNMENT_LEFT, fontId);
- BitsShow(rect);
- SetFont(fontId);
- TexteditCursorDraw(rect, text.c_str(), cursorPos);
- SetFont(oldFontId);
- // Write back string
- segMan->strcpy(textReference, text.c_str());
- } else {
- if (g_system->getMillis() >= _texteditBlinkTime) {
- InvertRect(_texteditCursorRect);
- BitsShow(_texteditCursorRect);
- _texteditCursorVisible = !_texteditCursorVisible;
- TexteditSetBlinkTime();
- }
- }
-
- PUT_SEL32V(segMan, controlObject, cursor, cursorPos);
-}
-
uint16 SciGuiGfx::onControl(uint16 screenMask, Common::Rect rect) {
Common::Rect outRect(rect.left, rect.top, rect.right, rect.bottom);
int16 x, y;
diff --git a/engines/sci/gui/gui_gfx.h b/engines/sci/gui/gui_gfx.h
index 61f7b414bf..257f2a6609 100644
--- a/engines/sci/gui/gui_gfx.h
+++ b/engines/sci/gui/gui_gfx.h
@@ -44,7 +44,7 @@ public:
SciGuiGfx(EngineState *state, SciGuiScreen *screen, SciGuiPalette *palette);
~SciGuiGfx();
- void init(void);
+ void init(SciGuiText *text);
// FIXME: Don't store EngineState
void resetEngineState(EngineState *newState) { _s = newState; }
@@ -63,9 +63,6 @@ public:
void PenMode(int16 mode);
void TextFace(int16 textFace);
int16 GetPointSize(void);
- GuiResourceId GetFontId();
- SciGuiFont *GetFont();
- void SetFont(GuiResourceId fontId);
void ClearScreen(byte color = 255);
void InvertRect(const Common::Rect &rect);
@@ -76,36 +73,16 @@ public:
void OffsetRect(Common::Rect &r);
void OffsetLine(Common::Point &start, Common::Point &end);
- void ClearChar(int16 chr);
- void DrawChar(int16 chr);
- void StdChar(int16 chr);
-
- void SetTextFonts(int argc, reg_t *argv);
- void SetTextColors(int argc, reg_t *argv);
- int16 TextSize(Common::Rect &rect, const char *str, GuiResourceId fontId, int16 maxwidth);
- void ShowString(const char *str, GuiResourceId orgFontId, int16 orgPenColor) {
- ShowText(str, 0, (int16)strlen(str), orgFontId, orgPenColor);
- }
- void DrawString(const char *str, GuiResourceId orgFontId, int16 orgPenColor) {
- DrawText(str, 0, (int16)strlen(str), orgFontId, orgPenColor);
- }
- void TextBox(const char *str, int16 bshow, const Common::Rect &rect, GuiTextAlignment alignment, GuiResourceId fontId);
void BitsShow(const Common::Rect &r);
GuiMemoryHandle BitsSave(const Common::Rect &rect, byte screenFlags);
void BitsGetRect(GuiMemoryHandle memoryHandle, Common::Rect *destRect);
void BitsRestore(GuiMemoryHandle memoryHandle);
void BitsFree(GuiMemoryHandle memoryHandle);
- void Draw_String(const char *text);
-
void drawPicture(GuiResourceId pictureId, int16 animationNr, bool mirroredFlag, bool addToFlag, GuiResourceId paletteId);
void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, byte priority, uint16 paletteNo);
void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, Common::Rect celRect, byte priority, uint16 paletteNo);
void drawCel(SciGuiView *view, GuiViewLoopNo loopNo, GuiViewCelNo celNo, Common::Rect celRect, byte priority, uint16 paletteNo);
- void drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias);
- void TexteditCursorDraw (Common::Rect rect, const char *text, uint16 curPos);
- void TexteditCursorErase();
- void TexteditChange(reg_t controlObject, reg_t eventObject);
uint16 onControl(uint16 screenMask, Common::Rect rect);
@@ -120,40 +97,20 @@ public:
GuiPort *_menuPort;
Common::Rect _menuRect;
+ GuiPort *_curPort;
private:
- int16 TextCodeProcessing(const char *&text, GuiResourceId orgFontId, int16 orgPenColor);
- void TextWidth(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight);
- void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight);
- int16 GetLongest(const char *str, int16 maxwidth, GuiResourceId orgFontId);
- void DrawText(const char *str, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor);
- void ShowText(const char *str, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor);
-
- void TexteditSetBlinkTime();
-
EngineState *_s;
SciGuiScreen *_screen;
SciGuiPalette *_palette;
+ SciGuiText *_text;
Common::Rect _bounds;
GuiPort *_mainPort;
- GuiPort *_curPort;
-
- int _textFontsCount;
- GuiResourceId *_textFonts;
- int _textColorsCount;
- uint16 *_textColors;
// Priority Bands related variables
int16 _priorityTop, _priorityBottom, _priorityBandCount;
byte _priorityBands[200];
-
- // Textedit-Control related
- Common::Rect _texteditCursorRect;
- bool _texteditCursorVisible;
- uint32 _texteditBlinkTime;
-
- SciGuiFont *_font;
};
} // End of namespace Sci
diff --git a/engines/sci/gui/gui_text.cpp b/engines/sci/gui/gui_text.cpp
index 3ba99f0566..91cc02a0f5 100644
--- a/engines/sci/gui/gui_text.cpp
+++ b/engines/sci/gui/gui_text.cpp
@@ -28,13 +28,15 @@
#include "graphics/primitives.h"
#include "sci/sci.h"
-#include "sci/gui/gui_screen.h"
+#include "sci/engine/state.h"
+#include "sci/gui/gui_gfx.h"
+#include "sci/gui/gui_font.h"
#include "sci/gui/gui_text.h"
namespace Sci {
-SciGuiText::SciGuiText(SciGuiScreen *screen)
- : _screen(screen) {
+SciGuiText::SciGuiText(ResourceManager *resMan, SciGuiGfx *gfx, SciGuiScreen *screen)
+ : _resMan(resMan), _gfx(gfx), _screen(screen) {
init();
}
@@ -42,8 +44,367 @@ SciGuiText::~SciGuiText() {
}
void SciGuiText::init() {
+ _font = NULL;
_codeFonts = NULL; _codeFontsCount = 0;
_codeColors = NULL; _codeColorsCount = 0;
}
+GuiResourceId SciGuiText::GetFontId() {
+ return _gfx->_curPort->fontId;
+}
+
+SciGuiFont *SciGuiText::GetFont() {
+ if ((_font == NULL) || (_font->getResourceId() != _gfx->_curPort->fontId))
+ _font = new SciGuiFont(_resMan, _gfx->_curPort->fontId);
+
+ return _font;
+}
+
+void SciGuiText::SetFont(GuiResourceId fontId) {
+ if ((_font == NULL) || (_font->getResourceId() != fontId))
+ _font = new SciGuiFont(_resMan, fontId);
+
+ _gfx->_curPort->fontId = _font->getResourceId();
+ _gfx->_curPort->fontHeight = _font->getHeight();
+}
+
+void SciGuiText::CodeSetFonts(int argc, reg_t *argv) {
+ int i;
+
+ if (_codeFonts) {
+ delete _codeFonts;
+ }
+ _codeFontsCount = argc;
+ _codeFonts = new GuiResourceId[argc];
+ for (i = 0; i < argc; i++) {
+ _codeFonts[i] = (GuiResourceId)argv[i].toUint16();
+ }
+}
+
+void SciGuiText::CodeSetColors(int argc, reg_t *argv) {
+ int i;
+
+ if (_codeColors) {
+ delete _codeColors;
+ }
+ _codeColorsCount = argc;
+ _codeColors = new uint16[argc];
+ for (i = 0; i < argc; i++) {
+ _codeColors[i] = argv[i].toUint16();
+ }
+}
+
+void SciGuiText::ClearChar(int16 chr) {
+ if (_gfx->_curPort->penMode != 1)
+ return;
+ Common::Rect rect;
+ rect.top = _gfx->_curPort->curTop;
+ rect.bottom = rect.top + _gfx->_curPort->fontHeight;
+ rect.left = _gfx->_curPort->curLeft;
+ rect.right = rect.left + GetFont()->getCharWidth(chr);
+ _gfx->EraseRect(rect);
+}
+
+void SciGuiText::DrawChar(int16 chr) {
+ chr = chr & 0xFF;
+ ClearChar(chr);
+ StdChar(chr);
+ _gfx->_curPort->curLeft += GetFont()->getCharWidth(chr);
+}
+
+void SciGuiText::StdChar(int16 chr) {
+#if 0
+ CResFont*res = getResFont();
+ if (res)
+ res->Draw(chr, _curPort->top + _curPort->curTop, _curPort->left
+ + _curPort->curLeft, _vSeg, 320, _curPort->penClr,
+ _curPort->textFace);
+#endif
+}
+
+// This internal function gets called as soon as a '|' is found in a text
+// It will process the encountered code and set new font/set color
+// We only support one-digit codes currently, don't know if multi-digit codes are possible
+// Returns textcode character count
+int16 SciGuiText::CodeProcessing(const char *&text, GuiResourceId orgFontId, int16 orgPenColor) {
+ const char *textCode = text;
+ int16 textCodeSize = 0;
+ char curCode;
+ unsigned char curCodeParm;
+
+ // Find the end of the textcode
+ while ((++textCodeSize) && (*text != 0) && (*text++ != 0x7C)) { }
+
+ // possible TextCodes:
+ // c -> sets textColor to current port pen color
+ // cX -> sets textColor to _textColors[X-1]
+ curCode = textCode[0];
+ curCodeParm = textCode[1];
+ if (isdigit(curCodeParm)) {
+ curCodeParm -= '0';
+ } else {
+ curCodeParm = 0;
+ }
+ switch (curCode) {
+ case 'c': // set text color
+ if (curCodeParm == 0) {
+ _gfx->_curPort->penClr = orgPenColor;
+ } else {
+ if (curCodeParm < _codeColorsCount) {
+ _gfx->_curPort->penClr = _codeColors[curCodeParm];
+ }
+ }
+ break;
+ case 'f':
+ if (curCodeParm == 0) {
+ SetFont(orgFontId);
+ } else {
+ if (curCodeParm < _codeFontsCount) {
+ SetFont(_codeFonts[curCodeParm]);
+ }
+ }
+ break;
+ }
+ return textCodeSize;
+}
+
+// return max # of chars to fit maxwidth with full words
+int16 SciGuiText::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgFontId) {
+ char curChar;
+ int16 maxChars = 0, curCharCount = 0;
+ uint16 width = 0;
+ GuiResourceId oldFontId = GetFontId();
+ int16 oldPenColor = _gfx->_curPort->penClr;
+
+ GetFont();
+ if (!_font)
+ return 0;
+
+ while (width <= maxWidth) {
+ curChar = *text++;
+ switch (curChar) {
+ case 0x7C:
+ if (getSciVersion() >= SCI_VERSION_1_1) {
+ curCharCount++;
+ curCharCount += CodeProcessing(text, orgFontId, oldPenColor);
+ continue;
+ }
+ break;
+
+ case 0xD:
+ curCharCount++;
+ continue;
+
+ case 0xA:
+ curCharCount++;
+ case 0:
+ SetFont(oldFontId);
+ _gfx->PenColor(oldPenColor);
+ return curCharCount;
+
+ case ' ':
+ maxChars = curCharCount + 1;
+ break;
+ }
+ width += _font->getCharWidth(curChar);
+ curCharCount++;
+ }
+ SetFont(oldFontId);
+ _gfx->PenColor(oldPenColor);
+ return maxChars;
+}
+
+void SciGuiText::Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight) {
+ unsigned char curChar;
+ GuiResourceId oldFontId = GetFontId();
+ int16 oldPenColor = _gfx->_curPort->penClr;
+
+ textWidth = 0; textHeight = 0;
+
+ GetFont();
+ if (_font) {
+ text += from;
+ while (len--) {
+ curChar = *text++;
+ switch (curChar) {
+ case 0x0A:
+ case 0x0D:
+ textHeight = MAX<int16> (textHeight, _gfx->_curPort->fontHeight);
+ break;
+ case 0x7C:
+ if (getSciVersion() >= SCI_VERSION_1_1) {
+ len -= CodeProcessing(text, orgFontId, 0);
+ break;
+ }
+ default:
+ textHeight = MAX<int16> (textHeight, _gfx->_curPort->fontHeight);
+ textWidth += _font->getCharWidth(curChar);
+ }
+ }
+ }
+ SetFont(oldFontId);
+ _gfx->PenColor(oldPenColor);
+ return;
+}
+
+void SciGuiText::StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight) {
+ Width(str, 0, (int16)strlen(str), orgFontId, textWidth, textHeight);
+}
+
+void SciGuiText::ShowString(const char *str, GuiResourceId orgFontId, int16 orgPenColor) {
+ Show(str, 0, (int16)strlen(str), orgFontId, orgPenColor);
+}
+void SciGuiText::DrawString(const char *str, GuiResourceId orgFontId, int16 orgPenColor) {
+ Draw(str, 0, (int16)strlen(str), orgFontId, orgPenColor);
+}
+
+int16 SciGuiText::Size(Common::Rect &rect, const char *str, GuiResourceId fontId, int16 maxWidth) {
+ GuiResourceId oldFontId = GetFontId();
+ int16 oldPenColor = _gfx->_curPort->penClr;
+ int16 charCount;
+ int16 maxTextWidth = 0, textWidth;
+ int16 totalHeight = 0, textHeight;
+
+ if (fontId != -1)
+ SetFont(fontId);
+ rect.top = rect.left = 0;
+
+ if (maxWidth < 0) { // force output as single line
+ StringWidth(str, oldFontId, textWidth, textHeight);
+ rect.bottom = textHeight;
+ rect.right = textWidth;
+ } else {
+ // rect.right=found widest line with RTextWidth and GetLongest
+ // rect.bottom=num. lines * GetPointSize
+ rect.right = (maxWidth ? maxWidth : 192);
+ const char*p = str;
+ while (*p) {
+ //if (*p == 0xD || *p == 0xA) {
+ // p++;
+ // continue;
+ //}
+ charCount = GetLongest(p, rect.right, oldFontId);
+ if (charCount == 0)
+ break;
+ Width(p, 0, charCount, oldFontId, textWidth, textHeight);
+ maxTextWidth = MAX(textWidth, maxTextWidth);
+ totalHeight += textHeight;
+ p += charCount;
+ }
+ rect.bottom = totalHeight;
+ rect.right = maxWidth ? maxWidth : MIN(rect.right, maxTextWidth);
+ }
+ SetFont(oldFontId);
+ _gfx->PenColor(oldPenColor);
+ return rect.right;
+}
+
+// returns maximum font height used
+void SciGuiText::Draw(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor) {
+ int16 curChar, charWidth;
+ Common::Rect rect;
+
+ GetFont();
+ if (!_font)
+ return;
+
+ rect.top = _gfx->_curPort->curTop;
+ rect.bottom = rect.top + _gfx->_curPort->fontHeight;
+ text += from;
+ while (len--) {
+ curChar = (*text++);
+ switch (curChar) {
+ case 0x0A:
+ case 0x0D:
+ case 0:
+ break;
+ case 0x7C:
+ if (getSciVersion() >= SCI_VERSION_1_1) {
+ len -= CodeProcessing(text, orgFontId, orgPenColor);
+ break;
+ }
+ default:
+ charWidth = _font->getCharWidth(curChar);
+ // clear char
+ if (_gfx->_curPort->penMode == 1) {
+ rect.left = _gfx->_curPort->curLeft;
+ rect.right = rect.left + charWidth;
+ _gfx->EraseRect(rect);
+ }
+ // CharStd
+ _font->draw(_screen, curChar, _gfx->_curPort->top + _gfx->_curPort->curTop, _gfx->_curPort->left + _gfx->_curPort->curLeft, _gfx->_curPort->penClr, _gfx->_curPort->textFace);
+ _gfx->_curPort->curLeft += charWidth;
+ }
+ }
+}
+
+// returns maximum font height used
+void SciGuiText::Show(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor) {
+ Common::Rect rect;
+
+ rect.top = _gfx->_curPort->curTop;
+ rect.bottom = rect.top + _gfx->GetPointSize();
+ rect.left = _gfx->_curPort->curLeft;
+ Draw(text, from, len, orgFontId, orgPenColor);
+ rect.right = _gfx->_curPort->curLeft;
+ _gfx->BitsShow(rect);
+}
+
+// Draws a text in rect.
+void SciGuiText::Box(const char *text, int16 bshow, const Common::Rect &rect, GuiTextAlignment alignment, GuiResourceId fontId) {
+ int16 textWidth, textHeight, charCount, offset;
+ int16 hline = 0;
+ GuiResourceId orgFontId = GetFontId();
+ int16 orgPenColor = _gfx->_curPort->penClr;
+
+ if (fontId != -1)
+ SetFont(fontId);
+
+ while (*text) {
+// if (*text == 0xD || *text == 0xA) {
+// text++;
+// continue;
+// }
+ charCount = GetLongest(text, rect.width(), orgFontId);
+ if (charCount == 0)
+ break;
+ Width(text, 0, charCount, orgFontId, textWidth, textHeight);
+ switch (alignment) {
+ case SCI_TEXT_ALIGNMENT_RIGHT:
+ offset = rect.width() - textWidth;
+ break;
+ case SCI_TEXT_ALIGNMENT_CENTER:
+ offset = (rect.width() - textWidth) / 2;
+ break;
+ case SCI_TEXT_ALIGNMENT_LEFT:
+ offset = 0;
+ break;
+
+ default: // left-aligned
+ warning("Invalid alignment %d used in TextBox()", alignment);
+ }
+ _gfx->MoveTo(rect.left + offset, rect.top + hline);
+
+ if (bshow) {
+ Show(text, 0, charCount, orgFontId, orgPenColor);
+ } else {
+ Draw(text, 0, charCount, orgFontId, orgPenColor);
+ }
+
+ hline += textHeight;
+ text += charCount;
+ }
+ SetFont(orgFontId);
+ _gfx->PenColor(orgPenColor);
+}
+
+void SciGuiText::Draw_String(const char *text) {
+ GuiResourceId orgFontId = GetFontId();
+ int16 orgPenColor = _gfx->_curPort->penClr;
+
+ Draw(text, 0, strlen(text), orgFontId, orgPenColor);
+ SetFont(orgFontId);
+ _gfx->PenColor(orgPenColor);
+}
+
} // End of namespace Sci
diff --git a/engines/sci/gui/gui_text.h b/engines/sci/gui/gui_text.h
index 856e3d47ce..75bd90e326 100644
--- a/engines/sci/gui/gui_text.h
+++ b/engines/sci/gui/gui_text.h
@@ -32,16 +32,44 @@ namespace Sci {
#define SCI_TEXT_ALIGNMENT_CENTER 1
#define SCI_TEXT_ALIGNMENT_LEFT 0
+class SciGuiGfx;
class SciGuiScreen;
class SciGuiFont;
class SciGuiText {
public:
- SciGuiText(SciGuiScreen *screen);
+ SciGuiText(ResourceManager *_resMan, SciGuiGfx *gfx, SciGuiScreen *screen);
~SciGuiText();
+ GuiResourceId GetFontId();
+ SciGuiFont *GetFont();
+ void SetFont(GuiResourceId fontId);
+
+ void CodeSetFonts(int argc, reg_t *argv);
+ void CodeSetColors(int argc, reg_t *argv);
+ int16 CodeProcessing(const char *&text, GuiResourceId orgFontId, int16 orgPenColor);
+
+ void ClearChar(int16 chr);
+ void DrawChar(int16 chr);
+ void StdChar(int16 chr);
+
+ int16 GetLongest(const char *text, int16 maxWidth, GuiResourceId orgFontId);
+ void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight);
+ void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight);
+ void ShowString(const char *str, GuiResourceId orgFontId, int16 orgPenColor);
+ void DrawString(const char *str, GuiResourceId orgFontId, int16 orgPenColor);
+ int16 Size(Common::Rect &rect, const char *str, GuiResourceId fontId, int16 maxWidth);
+ void Draw(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor);
+ void Show(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor);
+ void Box(const char *text, int16 bshow, const Common::Rect &rect, GuiTextAlignment alignment, GuiResourceId fontId);
+ void Draw_String(const char *text);
+
+ SciGuiFont *_font;
+
private:
void init(void);
+ ResourceManager *_resMan;
+ SciGuiGfx *_gfx;
SciGuiScreen *_screen;
int _codeFontsCount;
diff --git a/engines/sci/gui/gui_windowmgr.cpp b/engines/sci/gui/gui_windowmgr.cpp
index 1d40fa353d..6db959b3cc 100644
--- a/engines/sci/gui/gui_windowmgr.cpp
+++ b/engines/sci/gui/gui_windowmgr.cpp
@@ -30,6 +30,7 @@
#include "sci/gui/gui_screen.h"
#include "sci/gui/gui_gfx.h"
#include "sci/gui/gui_animate.h"
+#include "sci/gui/gui_text.h"
#include "sci/gui/gui_windowmgr.h"
namespace Sci {
@@ -43,9 +44,15 @@ enum {
SCI_WINDOWMGR_STYLE_USER = (1 << 7)
};
-SciGuiWindowMgr::SciGuiWindowMgr(SciGuiScreen *screen, SciGuiGfx *gfx, SciGuiAnimate *animate)
- : _screen(screen), _gfx(gfx), _animate(animate) {
+SciGuiWindowMgr::SciGuiWindowMgr(SciGuiScreen *screen, SciGuiGfx *gfx, SciGuiAnimate *animate, SciGuiText *text)
+ : _screen(screen), _gfx(gfx), _animate(animate), _text(text) {
+}
+
+SciGuiWindowMgr::~SciGuiWindowMgr() {
+ // TODO: Clear _windowList and delete all stuff in it?
+}
+void SciGuiWindowMgr::init() {
_wmgrPort = new GuiPort(0);
_windowsById.resize(1);
_windowsById[0] = _wmgrPort;
@@ -66,10 +73,6 @@ SciGuiWindowMgr::SciGuiWindowMgr(SciGuiScreen *screen, SciGuiGfx *gfx, SciGuiAni
_picWind = NewWindow(Common::Rect(0, offTop, _screen->_width, _screen->_height), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true);
}
-SciGuiWindowMgr::~SciGuiWindowMgr() {
- // TODO: Clear _windowList and delete all stuff in it?
-}
-
int16 SciGuiWindowMgr::isFrontWindow(GuiWindow *pWnd) {
return _windowList.back() == pWnd;
}
@@ -224,7 +227,7 @@ void SciGuiWindowMgr::DrawWindow(GuiWindow *pWnd) {
if (!pWnd->title.empty()) {
int16 oldcolor = _gfx->GetPort()->penClr;
_gfx->PenColor(255);
- _gfx->TextBox(pWnd->title.c_str(), 1, r, SCI_TEXT_ALIGNMENT_CENTER, 0);
+ _text->Box(pWnd->title.c_str(), 1, r, SCI_TEXT_ALIGNMENT_CENTER, 0);
_gfx->PenColor(oldcolor);
}
diff --git a/engines/sci/gui/gui_windowmgr.h b/engines/sci/gui/gui_windowmgr.h
index 8ec95720e2..ae3e4f5bca 100644
--- a/engines/sci/gui/gui_windowmgr.h
+++ b/engines/sci/gui/gui_windowmgr.h
@@ -33,9 +33,11 @@ namespace Sci {
class SciGuiWindowMgr {
public:
- SciGuiWindowMgr(SciGuiScreen *screen, SciGuiGfx *gfx, SciGuiAnimate *animate);
+ SciGuiWindowMgr(SciGuiScreen *screen, SciGuiGfx *gfx, SciGuiAnimate *animate, SciGuiText *text);
~SciGuiWindowMgr();
+ void init();
+
int16 isFrontWindow(GuiWindow *wnd);
void BeginUpdate(GuiWindow *wnd);
void EndUpdate(GuiWindow *wnd);
@@ -55,6 +57,7 @@ private:
SciGuiScreen *_screen;
SciGuiGfx *_gfx;
SciGuiAnimate *_animate;
+ SciGuiText *_text;
/** The list of open 'windows' (and ports), in visual order. */
PortList _windowList;
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 4437cc03ac..2335b4b60f 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -48,6 +48,7 @@ MODULE_OBJS := \
gfx/palette.o \
gui/gui.o \
gui/gui_animate.o \
+ gui/gui_controls.o \
gui/gui_cursor.o \
gui/gui_font.o \
gui/gui_gfx.o \