diff options
Diffstat (limited to 'engines/sci/gui')
| -rw-r--r-- | engines/sci/gui/gui.cpp | 42 | ||||
| -rw-r--r-- | engines/sci/gui/gui.h | 11 | ||||
| -rw-r--r-- | engines/sci/gui/gui_controls.cpp | 231 | ||||
| -rw-r--r-- | engines/sci/gui/gui_controls.h | 60 | ||||
| -rw-r--r-- | engines/sci/gui/gui_gfx.cpp | 548 | ||||
| -rw-r--r-- | engines/sci/gui/gui_gfx.h | 49 | ||||
| -rw-r--r-- | engines/sci/gui/gui_text.cpp | 367 | ||||
| -rw-r--r-- | engines/sci/gui/gui_text.h | 30 | ||||
| -rw-r--r-- | engines/sci/gui/gui_windowmgr.cpp | 17 | ||||
| -rw-r--r-- | engines/sci/gui/gui_windowmgr.h | 5 | 
10 files changed, 737 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;  | 
