[Scummvm-cvs-logs] CVS: scummvm/saga actor.cpp,1.155,1.156 actor.h,1.83,1.84 events.cpp,1.59,1.60 font.cpp,1.30,1.31 font.h,1.13,1.14 image.cpp,1.22,1.23 interface.cpp,1.115,1.116 ite_introproc.cpp,1.58,1.59 module.mk,1.26,1.27 objectmap.cpp,1.41,1.42 puzzle.cpp,1.10,1.11 puzzle.h,1.3,1.4 render.cpp,1.66,1.67 render.h,1.25,1.26 saga.h,1.105,1.106 scene.cpp,1.120,1.121 scene.h,1.61,1.62 script.h,1.92,1.93 sfuncs.cpp,1.137,1.138 sprite.cpp,1.58,1.59

Andrew Kurushin h00ligan at users.sourceforge.net
Thu Jul 14 10:48:23 CEST 2005


Update of /cvsroot/scummvm/scummvm/saga
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30762

Modified Files:
	actor.cpp actor.h events.cpp font.cpp font.h image.cpp 
	interface.cpp ite_introproc.cpp module.mk objectmap.cpp 
	puzzle.cpp puzzle.h render.cpp render.h saga.h scene.cpp 
	scene.h script.h sfuncs.cpp sprite.cpp 
Log Message:
font & text related changes:
-rewritten font loading
-actors box text output implemented
-many fixes
-implemented nonactors textoutput 



Index: actor.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/actor.cpp,v
retrieving revision 1.155
retrieving revision 1.156
diff -u -d -r1.155 -r1.156
--- actor.cpp	9 Jul 2005 23:07:45 -0000	1.155
+++ actor.cpp	14 Jul 2005 17:46:01 -0000	1.156
@@ -30,7 +30,6 @@
 #include "saga/sndres.h"
 #include "saga/sprite.h"
 #include "saga/font.h"
-#include "saga/text.h"
 #include "saga/sound.h"
 #include "saga/scene.h"
 
@@ -733,6 +732,8 @@
 	int i;
 	int talkspeed;
 	ActorData *actor;
+	int width, height, height2;
+	Point posPoint;
 
 	if (_activeSpeech.playing) {
 		_activeSpeech.playingTime -= msec;
@@ -817,13 +818,39 @@
 			actor->currentAction = kActionSpeak;
 			actor->actionCycle = _vm->_rnd.getRandomNumber(63);
 		}
-		for (i = 0; i < _activeSpeech.actorsCount; i++) {
-			actor = getActor(_activeSpeech.actorIds[i]);
-			_activeSpeech.speechCoords[i] = actor->screenPosition;
-			_activeSpeech.speechCoords[i].y -= ACTOR_DIALOGUE_HEIGHT;
-			_activeSpeech.speechCoords[i].y = MAX(_activeSpeech.speechCoords[i].y, (int16)10);
-		}
 	}
+
+	if (_activeSpeech.actorsCount == 1) {
+		width = _activeSpeech.speechBox.width();
+		height = _vm->_font->getHeight(kMediumFont, _activeSpeech.strings[0], width - 2, _activeSpeech.getFontFlags(0)) + 1;
+
+		if (height > 40 && width < _vm->getDisplayWidth() - 100) {
+			width = _vm->getDisplayWidth() - 100;
+			height = _vm->_font->getHeight(kMediumFont, _activeSpeech.strings[0], width - 2, _activeSpeech.getFontFlags(0)) + 1;
+		}
+
+		_activeSpeech.speechBox.setWidth(width);
+		
+		if (_activeSpeech.actorIds[0] != 0) {
+			actor = getActor(_activeSpeech.actorIds[0]);
+			_activeSpeech.speechBox.setHeight(height);
+
+			if (_activeSpeech.speechBox.right > _vm->getDisplayWidth() - 10) {
+				_activeSpeech.drawRect.left = _vm->getDisplayWidth() - 10 - width;
+			} else {
+				_activeSpeech.drawRect.left = _activeSpeech.speechBox.left;
+			}
+
+			height2 =  actor->screenPosition.y - 50;
+			_activeSpeech.speechBox.top = _activeSpeech.drawRect.top = MAX(10, (height2 - height) / 2);
+		} else {
+			_activeSpeech.drawRect.left = _activeSpeech.speechBox.left;
+			_activeSpeech.drawRect.top = _activeSpeech.speechBox.top + (_activeSpeech.speechBox.height() - height) / 2;
+		}
+		_activeSpeech.drawRect.setWidth(width);
+		_activeSpeech.drawRect.setHeight(height);
+	}		
+
 	_activeSpeech.playing = true;			
 }
 
@@ -1404,7 +1431,9 @@
 void Actor::drawSpeech(void) {
 	if (isSpeaking() && _activeSpeech.playing && !_vm->_script->_skipSpeeches) {
 		int i;
-		int textDrawFlags;
+		Point textPoint;
+		ActorData *actor;
+		int width, height;
 		char oneChar[2];
 		oneChar[1] = 0;
 		const char *outputString;
@@ -1419,26 +1448,24 @@
 			outputString = _activeSpeech.strings[0];
 		}
 
-		textDrawFlags = FONT_CENTERED;
-		if (_activeSpeech.outlineColor != 0) {
-			textDrawFlags |= FONT_OUTLINE;
-		}
-
-		if (_activeSpeech.actorIds[0] != 0) {
+		if (_activeSpeech.actorsCount > 1) {
+			height = _vm->_font->getHeight(kMediumFont);
+			width = _vm->_font->getStringWidth(kMediumFont, _activeSpeech.strings[0], 0, kFontNormal);
 			
-			for (i = 0; i < _activeSpeech.actorsCount; i++){
-				_vm->textDraw(MEDIUM_FONT_ID, backBuffer, outputString,
-					_activeSpeech.speechCoords[i].x, 
-					_activeSpeech.speechCoords[i].y, 
-					_activeSpeech.speechColor[i], 
-					_activeSpeech.outlineColor[i], textDrawFlags);
-			}
+			for ( i = 0; i < _activeSpeech.actorsCount; i++) {
+				actor = getActor(_activeSpeech.actorIds[i]);
+				calcScreenPosition(actor);
 
-		} else { // non actors speech
-			warning("non actors speech occures");
-			//todo: write it
-		}
+				textPoint.x = clamp( 10, actor->screenPosition.x - width / 2, _vm->getDisplayWidth() - 10 - width);
+				textPoint.y = clamp( 10, actor->screenPosition.y - 58, _vm->getSceneHeight() - 10 - height);
 
+				_vm->_font->textDraw(kMediumFont, backBuffer, _activeSpeech.strings[0], textPoint, 
+					_activeSpeech.speechColor[i], _activeSpeech.outlineColor[i], _activeSpeech.getFontFlags(i));
+			}
+		} else {
+			_vm->_font->textDrawRect(kMediumFont, backBuffer, _activeSpeech.strings[0], _activeSpeech.drawRect, _activeSpeech.speechColor[0],
+				_activeSpeech.outlineColor[0], _activeSpeech.getFontFlags(0));
+		}
 	}
 }
 
@@ -1820,6 +1847,7 @@
 void Actor::actorSpeech(uint16 actorId, const char **strings, int stringsCount, int sampleResourceId, int speechFlags) {
 	ActorData *actor;
 	int i;
+	int16 dist;
 
 	if (_vm->getGameType() == GType_IHNM) {
 		warning("Actors aren't implemented for IHNM yet");
@@ -1827,6 +1855,7 @@
 	}
 
 	actor = getActor(actorId);
+	calcScreenPosition(actor);
 	for (i = 0; i < stringsCount; i++) {
 		_activeSpeech.strings[i] = strings[i];
 	}
@@ -1840,9 +1869,24 @@
 	_activeSpeech.sampleResourceId = sampleResourceId;
 	_activeSpeech.playing = false;
 	_activeSpeech.slowModeCharIndex = 0;
+
+	dist = MIN(actor->screenPosition.x - 10, _vm->getDisplayWidth() - 10 - actor->screenPosition.x );
+	dist = clamp( 60, dist, 150 );
+
+	_activeSpeech.speechBox.left = actor->screenPosition.x - dist;
+	_activeSpeech.speechBox.right = actor->screenPosition.x + dist;
+
+	if (_activeSpeech.speechBox.left < 10) {
+		_activeSpeech.speechBox.right += 10 - _activeSpeech.speechBox.left; 
+		_activeSpeech.speechBox.left = 10; 
+	}
+	if (_activeSpeech.speechBox.right > _vm->getDisplayWidth() - 10) {
+		_activeSpeech.speechBox.left -= _activeSpeech.speechBox.right - _vm->getDisplayWidth() - 10;
+		_activeSpeech.speechBox.right = _vm->getDisplayWidth() - 10; 
+	}	
 }
 
-void Actor::nonActorSpeech(const char **strings, int stringsCount, int speechFlags) {
+void Actor::nonActorSpeech(const Common::Rect &box, const char **strings, int stringsCount, int speechFlags) {
 	int i;
 	
 	_vm->_script->wakeUpThreads(kWaitTypeSpeech);
@@ -1854,13 +1898,10 @@
 	_activeSpeech.speechFlags = speechFlags;
 	_activeSpeech.actorsCount = 1;
 	_activeSpeech.actorIds[0] = 0;
-	//_activeSpeech.speechColor[0] = ;
-	//_activeSpeech.outlineColor[0] = ;
-	//_activeSpeech.speechCoords[0].x = ;
-	//_activeSpeech.speechCoords[0].y = ;
 	_activeSpeech.sampleResourceId = -1;
 	_activeSpeech.playing = false;
 	_activeSpeech.slowModeCharIndex = 0;
+	_activeSpeech.speechBox = box;
 }
 
 void Actor::simulSpeech(const char *string, uint16 *actorIds, int actorIdsCount, int speechFlags, int sampleResourceId) {

Index: actor.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/actor.h,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -d -r1.83 -r1.84
--- actor.h	8 Jul 2005 16:55:54 -0000	1.83
+++ actor.h	14 Jul 2005 17:46:01 -0000	1.84
@@ -470,7 +470,8 @@
 	int outlineColor[ACTOR_SPEECH_ACTORS_MAX];
 	int speechFlags;
 	const char *strings[ACTOR_SPEECH_STRING_MAX];
-	Point speechCoords[ACTOR_SPEECH_ACTORS_MAX];
+	Rect speechBox;
+	Rect drawRect;
 	int stringsCount;
 	int slowModeCharIndex;
 	uint16 actorIds[ACTOR_SPEECH_ACTORS_MAX];
@@ -482,6 +483,14 @@
 	SpeechData() { 
 		memset(this, 0, sizeof(*this)); 
 	}
+
+	FontEffectFlags getFontFlags(int i) {
+		if (outlineColor[i] != 0) {
+			return kFontOutline;
+		} else {
+			return kFontNormal;
+		}
+	}
 };
 
 
@@ -545,7 +554,7 @@
 
 //	speech 
 	void actorSpeech(uint16 actorId, const char **strings, int stringsCount, int sampleResourceId, int speechFlags);
-	void nonActorSpeech(const char **strings, int stringsCount, int speechFlags);
+	void nonActorSpeech(const Common::Rect &box, const char **strings, int stringsCount, int speechFlags);
 	void simulSpeech(const char *string, uint16 *actorIds, int actorIdsCount, int speechFlags, int sampleResourceId);
 	void setSpeechColor(int speechColor, int outlineColor) {
 		_activeSpeech.speechColor[0] = speechColor;

Index: events.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/events.cpp,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -d -r1.59 -r1.60
--- events.cpp	9 Jul 2005 23:07:46 -0000	1.59
+++ events.cpp	14 Jul 2005 17:46:19 -0000	1.60
@@ -32,7 +32,6 @@
 #include "saga/console.h"
 #include "saga/scene.h"
 #include "saga/interface.h"
-#include "saga/text.h"
 #include "saga/palanim.h"
 #include "saga/render.h"
 #include "saga/sndres.h"
@@ -279,12 +278,10 @@
 	case TEXT_EVENT:
 		switch (event->op) {
 		case EVENT_DISPLAY:
-			_vm->textSetDisplay((TEXTLIST_ENTRY *)event->data, 1);
+			((TextListEntry *)event->data)->display = 1;
 			break;
 		case EVENT_REMOVE:
-			{
-				_vm->textDeleteEntry(_vm->_scene->_textList, (TEXTLIST_ENTRY *)event->data);
-			}
+			_vm->_scene->_textList.remove((TextListEntry *)event->data);
 			break;
 		default:
 			break;

Index: font.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/font.cpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- font.cpp	9 Jul 2005 16:23:44 -0000	1.30
+++ font.cpp	14 Jul 2005 17:46:19 -0000	1.31
@@ -36,19 +36,11 @@
 	int i;
 
 	// Load font module resource context 
-	_fontContext = _vm->getFileContext(GAME_RESOURCEFILE, 0);
-	if (_fontContext == NULL) {
-		error("Font::Font(): Couldn't get resource context.");
-	}
 
 	assert(_vm->getFontsCount() > 0);
 
-	_nFonts = 0;
-
-	_fonts = (FONT **)malloc(_vm->getFontsCount() * sizeof(*_fonts));
-	if (_fonts == NULL) {
-		memoryError("Font::Font");
-	}
+	_fonts = (FontData **)calloc(_vm->getFontsCount(), sizeof(*_fonts));
+	_loadedFonts = 0;
 
 	for (i = 0; i < _vm->getFontsCount(); i++) {
 		loadFont(_vm->getFontDescription(i)->fontResourceId);
@@ -58,377 +50,303 @@
 }
 
 Font::~Font(void) {
-//	int i;
-
 	debug(8, "Font::~Font(): Freeing fonts.");
-/*
-	for (i = 0 ; i < FONT_COUNT ; i++) {
-		if (_fonts[i] != NULL) {
-			if (_fonts[i]->normal_loaded) {
-				free(_fonts[i]->normal->font_free_p);
-				free(_fonts[i]->normal);
-			}
+	int i;
 
-			if (_fonts[i]->outline_loaded) {
-				free(_fonts[i]->outline->font_free_p);
-				free(_fonts[i]->outline);
-			}
+	for (i = 0 ; i < _loadedFonts ; i++) {
+		if (_fonts[i] != NULL) {
+			free(_fonts[i]->normal.font);
+			free(_fonts[i]->outline.font);
 		}
 
 		free(_fonts[i]);
 	}
-*/
 }
 
-int Font::loadFont(uint32 fontResourceId) {
-	FONT_HEADER fh;
-	FONT *font;
-	FONT_STYLE *normal_font;
-	byte *fontres_p;
-	size_t fontres_len;
-	int nbits;
+void Font::loadFont(uint32 fontResourceId) {
+	FontData *font;
+	byte *fontResourcePointer;
+	size_t fontResourceLength;
+	int numBits;
 	int c;
+	RSCFILE_CONTEXT *fontContext;
+
+
+	debug(1, "Font::loadFont(): Reading fontResourceId %d...", fontResourceId);
+
+	fontContext = _vm->getFileContext(GAME_RESOURCEFILE, 0);
+	if (fontContext == NULL) {
+		error("Font::Font(): Couldn't get resource context.");
+	}
 
 	// Load font resource
-	if (RSC_LoadResource(_fontContext, fontResourceId, &fontres_p, &fontres_len) != SUCCESS) {
+	if (RSC_LoadResource(fontContext, fontResourceId, &fontResourcePointer, &fontResourceLength) != SUCCESS) {
 		error("Font::loadFont(): Couldn't load font resource.");
 	}
 
-	if (fontres_len < FONT_DESCSIZE) {
-		warning("Font::loadFont(): Invalid font length (%d < %d)", fontres_len, FONT_DESCSIZE);
-		return FAILURE;
+	if (fontResourceLength < FONT_DESCSIZE) {
+		error("Font::loadFont(): Invalid font length (%d < %d)", fontResourceLength, FONT_DESCSIZE);
 	}
 
-	MemoryReadStreamEndian readS(fontres_p, fontres_len, IS_BIG_ENDIAN);
+	MemoryReadStreamEndian readS(fontResourcePointer, fontResourceLength, IS_BIG_ENDIAN);
 
 	// Create new font structure
-	font = (FONT *)malloc(sizeof(*font));
-	if (font == NULL) {
-		memoryError("Font::loadFont");
-	}
-
+	font = (FontData *)malloc(sizeof(*font));
+	
 	// Read font header
-	fh.c_height = readS.readUint16();
-	fh.c_width = readS.readUint16();
-	fh.row_length = readS.readUint16();
-
-	debug(1, "Font::loadFont(): Reading fontResourceId %d...", fontResourceId);
-
-	debug(2, "Character width: %d", fh.c_width);
-	debug(2, "Character height: %d", fh.c_height);
-	debug(2, "Row padding: %d", fh.row_length);
+	font->normal.header.charHeight = readS.readUint16();
+	font->normal.header.charWidth = readS.readUint16();
+	font->normal.header.rowLength = readS.readUint16();
 
-	// Create normal font style
-	normal_font = (FONT_STYLE *)malloc(sizeof(*normal_font));
-	if (normal_font == NULL) {
-		memoryError("Font::loadFont");
-	}
 
-	normal_font->font_free_p = fontres_p;
-	normal_font->hdr.c_height = fh.c_height;
-	normal_font->hdr.c_width = fh.c_width;
-	normal_font->hdr.row_length = fh.row_length;
+	debug(2, "Character width: %d", font->normal.header.charWidth);
+	debug(2, "Character height: %d", font->normal.header.charHeight);
+	debug(2, "Row padding: %d", font->normal.header.rowLength);
 
 	for (c = 0; c < FONT_CHARCOUNT; c++) {
-		normal_font->fce[c].index = readS.readUint16();
+		font->normal.fontCharEntry[c].index = readS.readUint16();
 	}
 
 	for (c = 0; c < FONT_CHARCOUNT; c++) {
-		nbits = normal_font->fce[c].width = readS.readByte();
-		normal_font->fce[c].byte_width = getByteLen(nbits);
+		numBits = font->normal.fontCharEntry[c].width = readS.readByte();
+		font->normal.fontCharEntry[c].byteWidth = getByteLen(numBits);
 	}
 
 	for (c = 0; c < FONT_CHARCOUNT; c++) {
-		normal_font->fce[c].flag = readS.readByte();
+		font->normal.fontCharEntry[c].flag = readS.readByte();
 	}
 
 	for (c = 0; c < FONT_CHARCOUNT; c++) {
-		normal_font->fce[c].tracking = readS.readByte();
+		font->normal.fontCharEntry[c].tracking = readS.readByte();
 	}
 
 	if (readS.pos() != FONT_DESCSIZE) {
-		warning("Invalid font resource size.");
-		return FAILURE;
+		error("Invalid font resource size.");
 	}
 
-	normal_font->font_p = fontres_p + FONT_DESCSIZE;
+	font->normal.font = (byte*)malloc(fontResourceLength - FONT_DESCSIZE);
+	memcpy(font->normal.font, fontResourcePointer + FONT_DESCSIZE, fontResourceLength - FONT_DESCSIZE);
 
-	font->normal = normal_font;
-	font->normal_loaded = 1;
+	RSC_FreeResource(fontResourcePointer);
 
-	// Create outline font style
-	font->outline = createOutline(normal_font);
-	font->outline_loaded = 1;
 
+	// Create outline font style
+	createOutline(font);
+	
 	// Set font data 
-	_fonts[_nFonts++] = font;
-
-	return SUCCESS;
+	_fonts[_loadedFonts++] = font;	
 }
 
-int Font::getHeight(int font_id) {
-	FONT *font;
 
-	if (!_initialized) {
-		return FAILURE;
-	}
-
-	if ((font_id < 0) || (font_id >= _nFonts) || (_fonts[font_id] == NULL)) {
-		error("Font::getHeight(): Invalid font id.");
-	}
-
-	font = _fonts[font_id];
-
-	return font->normal->hdr.c_height;
-}
-
-FONT_STYLE *Font::createOutline(FONT_STYLE *src_font) {
-	FONT_STYLE *new_font;
-	unsigned char *new_font_data;
-	size_t new_font_data_len;
-	int s_width = src_font->hdr.c_width;
-	int s_height = src_font->hdr.c_height;
-	int new_row_len = 0;
-	int row;
+void Font::createOutline(FontData *font) {
 	int i;
+	int row;
+	int newByteWidth;
+	int oldByteWidth;
+	int newRowLength = 0;
+	size_t indexOffset = 0;
 	int index;
-	size_t index_offset = 0;
-	int new_byte_width;
-	int old_byte_width;
-	int current_byte;
-	unsigned char *base_ptr;
-	unsigned char *src_ptr;
-	unsigned char *dest_ptr1;
-	unsigned char *dest_ptr2;
-	unsigned char *dest_ptr3;
-	unsigned char c_rep;
-
-	// Create new font style structure
-	new_font = (FONT_STYLE *)malloc(sizeof(*new_font));
-
-	if (new_font == NULL) {
-		memoryError("Font::createOutline");
-	}
+	int currentByte;
+	unsigned char *basePointer;
+	unsigned char *srcPointer;
+	unsigned char *destPointer1;
+	unsigned char *destPointer2;
+	unsigned char *destPointer3;
+	unsigned char charRep;
 
-	memset(new_font, 0, sizeof(*new_font));
 
 	// Populate new font style character data 
 	for (i = 0; i < FONT_CHARCOUNT; i++) {
-		new_byte_width = 0;
-		old_byte_width = 0;
-		index = src_font->fce[i].index;
+		newByteWidth = 0;
+		oldByteWidth = 0;
+		index = font->normal.fontCharEntry[i].index;
 		if ((index > 0) || (i == FONT_FIRSTCHAR)) {
-			index += index_offset;
+			index += indexOffset;
 		}
 
-		new_font->fce[i].index = index;
-		new_font->fce[i].tracking = src_font->fce[i].tracking;
-		new_font->fce[i].flag = src_font->fce[i].flag;
+		font->outline.fontCharEntry[i].index = index;
+		font->outline.fontCharEntry[i].tracking = font->normal.fontCharEntry[i].tracking;
+		font->outline.fontCharEntry[i].flag = font->normal.fontCharEntry[i].flag;
 
-		if (src_font->fce[i].width != 0) {
-			new_byte_width = getByteLen(src_font->fce[i].width + 2);
-			old_byte_width = getByteLen(src_font->fce[i].width);
+		if (font->normal.fontCharEntry[i].width != 0) {
+			newByteWidth = getByteLen(font->normal.fontCharEntry[i].width + 2);
+			oldByteWidth = getByteLen(font->normal.fontCharEntry[i].width);
 
-			if (new_byte_width > old_byte_width) {
-				index_offset++;
+			if (newByteWidth > oldByteWidth) {
+				indexOffset++;
 			}
 		}
 
-		new_font->fce[i].width = src_font->fce[i].width + 2;
-		new_font->fce[i].byte_width = new_byte_width;
-		new_row_len += new_byte_width;
+		font->outline.fontCharEntry[i].width = font->normal.fontCharEntry[i].width + 2;
+		font->outline.fontCharEntry[i].byteWidth = newByteWidth;
+		newRowLength += newByteWidth;
 	}
 
-	debug(2, "New row length: %d", new_row_len);
+	debug(2, "New row length: %d", newRowLength);
 
-	new_font->hdr.c_width = s_width + 2;
-	new_font->hdr.c_height = s_height + 2;
-	new_font->hdr.row_length = new_row_len;
+	font->outline.header = font->normal.header;
+	font->outline.header.charWidth += 2;
+	font->outline.header.charHeight += 2;
+	font->outline.header.rowLength = newRowLength;
 
 	// Allocate new font representation storage 
-	new_font_data_len = new_row_len * (s_height + 2);
-	new_font_data = (unsigned char *)malloc(new_font_data_len);
-
-	if (new_font_data == NULL) {
-		memoryError("Font::createOutline");
-	}
-
-	memset(new_font_data, 0, new_font_data_len);
-
-	new_font->font_free_p = new_font_data;
-	new_font->font_p = new_font_data;
+	font->outline.font = (unsigned char *)calloc(newRowLength, font->outline.header.charHeight);
 
+	
 	// Generate outline font representation
 	for (i = 0; i < FONT_CHARCOUNT; i++) {
-		for (row = 0; row < s_height; row++) {
-			for (current_byte = 0; current_byte < new_font->fce[i].byte_width; current_byte++) {
-				base_ptr = new_font->font_p + new_font->fce[i].index + current_byte;
-				dest_ptr1 = base_ptr + new_font->hdr.row_length * row;
-				dest_ptr2 = base_ptr + new_font->hdr.row_length * (row + 1);
-				dest_ptr3 = base_ptr + new_font->hdr.row_length * (row + 2);
-				if (current_byte > 0) {
+		for (row = 0; row < font->normal.header.charHeight; row++) {
+			for (currentByte = 0; currentByte < font->outline.fontCharEntry[i].byteWidth; currentByte++) {
+				basePointer = font->outline.font + font->outline.fontCharEntry[i].index + currentByte;
+				destPointer1 = basePointer + newRowLength * row;
+				destPointer2 = basePointer + newRowLength * (row + 1);
+				destPointer3 = basePointer + newRowLength * (row + 2);
+				if (currentByte > 0) {
 					// Get last two columns from previous byte
-					src_ptr = src_font->font_p + src_font->hdr.row_length * row + src_font->fce[i].index +
-								(current_byte - 1);
-					c_rep = *src_ptr;
-					*dest_ptr1 |= ((c_rep << 6) | (c_rep << 7));
-					*dest_ptr2 |= ((c_rep << 6) | (c_rep << 7));
-					*dest_ptr3 |= ((c_rep << 6) | (c_rep << 7));
+					srcPointer = font->normal.font + font->normal.header.rowLength * row + font->normal.fontCharEntry[i].index + (currentByte - 1);
+					charRep = *srcPointer;
+					*destPointer1 |= ((charRep << 6) | (charRep << 7));
+					*destPointer2 |= ((charRep << 6) | (charRep << 7));
+					*destPointer3 |= ((charRep << 6) | (charRep << 7));
 				}
 
-				if (current_byte < src_font->fce[i].byte_width) {
-					src_ptr = src_font->font_p + src_font->hdr.row_length * row + src_font->fce[i].index +
-								current_byte;
-					c_rep = *src_ptr;
-					*dest_ptr1 |= c_rep | (c_rep >> 1) | (c_rep >> 2);
-					*dest_ptr2 |= c_rep | (c_rep >> 1) | (c_rep >> 2);
-					*dest_ptr3 |= c_rep | (c_rep >> 1) | (c_rep >> 2);
+				if (currentByte < font->normal.fontCharEntry[i].byteWidth) {
+					srcPointer = font->normal.font + font->normal.header.rowLength * row + font->normal.fontCharEntry[i].index + currentByte;
+					charRep = *srcPointer;
+					*destPointer1 |= charRep | (charRep >> 1) | (charRep >> 2);
+					*destPointer2 |= charRep | (charRep >> 1) | (charRep >> 2);
+					*destPointer3 |= charRep | (charRep >> 1) | (charRep >> 2);
 				}
 			}
 		}
 
 		// "Hollow out" character to prevent overdraw
-		for (row = 0; row < s_height; row++) {
-			for (current_byte = 0; current_byte < new_font->fce[i].byte_width; current_byte++) {
-				dest_ptr2 = new_font->font_p +  new_font->hdr.row_length * (row + 1) + new_font->fce[i].index + current_byte;
-				if (current_byte > 0) {
+		for (row = 0; row < font->normal.header.charHeight; row++) {
+			for (currentByte = 0; currentByte < font->outline.fontCharEntry[i].byteWidth; currentByte++) {
+				destPointer2 = font->outline.font +  font->outline.header.rowLength * (row + 1) + font->outline.fontCharEntry[i].index + currentByte;
+				if (currentByte > 0) {
 					// Get last two columns from previous byte
-					src_ptr = src_font->font_p + src_font->hdr.row_length * row + src_font->fce[i].index +
-								(current_byte - 1);
-					*dest_ptr2 &= ((*src_ptr << 7) ^ 0xFFU);
+					srcPointer = font->normal.font + font->normal.header.rowLength * row + font->normal.fontCharEntry[i].index + (currentByte - 1);
+					*destPointer2 &= ((*srcPointer << 7) ^ 0xFFU);
 				}
 
-				if (current_byte < src_font->fce[i].byte_width) {
-					src_ptr = src_font->font_p + src_font->hdr.row_length * row + src_font->fce[i].index +
-								current_byte;
-					*dest_ptr2 &= ((*src_ptr >> 1) ^ 0xFFU);
+				if (currentByte < font->normal.fontCharEntry[i].byteWidth) {
+					srcPointer = font->normal.font + font->normal.header.rowLength * row + font->normal.fontCharEntry[i].index + currentByte;
+					*destPointer2 &= ((*srcPointer >> 1) ^ 0xFFU);
 				}
 			}
 		}
-	}
-
-	return new_font;
-}
-
-int Font::getByteLen(int num_bits) {
-	int byte_len;
-	byte_len = num_bits / 8;
-
-	if (num_bits % 8) {
-		byte_len++;
-	}
-
-	return byte_len;
+	}	
 }
 
 // Returns the horizontal length in pixels of the graphical representation
 // of at most 'test_str_ct' characters of the string 'test_str', taking
 // into account any formatting options specified by 'flags'.
 // If 'test_str_ct' is 0, all characters of 'test_str' are counted.
-int Font::getStringWidth(int font_id, const char *test_str, size_t test_str_ct, int flags) {
-	FONT *font;
+int Font::getStringWidth(FontId fontId, const char *text, size_t count, FontEffectFlags flags) {
+	FontData *font;
 	size_t ct;
 	int width = 0;
 	int ch;
-	const byte *txt_p;
-
-	if (!_initialized) {
-		return FAILURE;
-	}
+	const byte *txt;
 
-	if ((font_id < 0) || (font_id >= _nFonts) || (_fonts[font_id] == NULL)) {
-		error("Font::getStringWidth(): Invalid font id.");
-	}
+	validate(fontId);
 
-	font = _fonts[font_id];
-	assert(font != NULL);
+	font = _fonts[fontId];
 
-	txt_p = (const byte *) test_str;
+	txt = (const byte *) text;
 
-	for (ct = test_str_ct; *txt_p && (!test_str_ct || ct > 0); txt_p++, ct--) {
-		ch = *txt_p & 0xFFU;
+	for (ct = count; *txt && (!count || ct > 0); txt++, ct--) {
+		ch = *txt & 0xFFU;
 		// Translate character
 		ch = _charMap[ch];
 		assert(ch < FONT_CHARCOUNT);
-		width += font->normal->fce[ch].tracking;
+		width += font->normal.fontCharEntry[ch].tracking;
 	}
 
-	if ((flags & FONT_BOLD) || (flags & FONT_OUTLINE)) {
+	if ((flags & kFontBold) || (flags & kFontOutline)) {
 		width += 1;
 	}
 
 	return width;
 }
 
-int Font::draw(int font_id, Surface *ds, const char *draw_str, size_t draw_str_ct,
-			int text_x, int text_y, int color, int effect_color, int flags) {
-	FONT *font;
+int Font::getHeight(FontId fontId) {
+	FontData *font;
 
-	if (!_initialized) {
-		error("Font::draw(): Font Module not initialized.");
-	}
+	validate(fontId);
 
-	if ((font_id < 0) || (font_id >= _nFonts) || (_fonts[font_id] == NULL)) {
-		error("Font::draw(): Invalid font id.");
-	}
+	font = _fonts[fontId];
 
-	font = _fonts[font_id];
+	return font->normal.header.charHeight;
+}
 
-	if (flags & FONT_OUTLINE) { 
-		outFont(font->outline, ds, draw_str, draw_str_ct, text_x - 1, text_y - 1, effect_color, flags);
-		outFont(font->normal, ds, draw_str, draw_str_ct, text_x, text_y, color, flags);
-	} else if (flags & FONT_SHADOW) {
-		outFont(font->normal, ds, draw_str, draw_str_ct, text_x - 1, text_y + 1, effect_color, flags);
-		outFont(font->normal, ds, draw_str, draw_str_ct, text_x, text_y, color, flags);
+void Font::draw(FontId fontId, Surface *ds, const char *text, size_t count, const Common::Point &point,
+			   int color, int effectColor, FontEffectFlags flags) {
+	FontData *font;
+	Point offsetPoint(point);
+
+	validate(fontId);
+
+	font = _fonts[fontId];
+
+	if (flags & kFontOutline) { 
+		offsetPoint.x--;
+		offsetPoint.y--;
+		outFont(font->outline, ds, text, count, offsetPoint, effectColor, flags);
+		outFont(font->normal, ds, text, count, point, color, flags);
+	} else if (flags & kFontShadow) {
+		offsetPoint.x--;
+		offsetPoint.y++;
+		outFont(font->normal, ds, text, count, offsetPoint, effectColor, flags);
+		outFont(font->normal, ds, text, count, point, color, flags);
 	} else { // FONT_NORMAL
-		outFont(font->normal, ds, draw_str, draw_str_ct, text_x, text_y, color, flags);
+		outFont(font->normal, ds, text, count, point, color, flags);
 	}
-
-	return SUCCESS;
 }
 
-int Font::outFont(FONT_STYLE * draw_font, Surface *ds, const char *draw_str, size_t draw_str_ct,
-				  int text_x, int text_y, int color, int flags) {
-	const byte *draw_str_p;
-	byte *c_data_ptr;
+void Font::outFont(const FontStyle & drawFont, Surface *ds, const char *text, size_t count, const Common::Point &point, int color, FontEffectFlags flags) {
+	const byte *textPointer;
+	byte *c_dataPointer;
 	int c_code;
-	int char_row;
+	int charRow;
+	Point textPoint(point);
 
-	byte *output_ptr;
-	byte *output_ptr_min;
-	byte *output_ptr_max;
+	byte *outputPointer;
+	byte *outputPointer_min;
+	byte *outputPointer_max;
 
 	int row;
-	int row_limit;
+	int rowLimit;
 
 	int c_byte_len;
 	int c_byte;
 	int c_bit;
 	int ct;
 
-	if ((text_x > ds->w) || (text_y > ds->h)) {
+	if ((point.x > ds->w) || (point.y > ds->h)) {
 		// Output string can't be visible
-		return SUCCESS;
+		return;
 	}
 
-	draw_str_p = (const byte *) draw_str;
-	ct = draw_str_ct;
+	textPointer = (const byte *) text;
+	ct = count;
 
 	// Draw string one character at a time, maximum of 'draw_str'_ct 
 	// characters, or no limit if 'draw_str_ct' is 0
-	for (; *draw_str_p && (!draw_str_ct || ct); draw_str_p++, ct--) {
-		c_code = *draw_str_p & 0xFFU;
+	for (; *textPointer && (!count || ct); textPointer++, ct--) {
+		c_code = *textPointer & 0xFFU;
 
 		// Translate character
-		if (!(flags & FONT_DONTMAP))
+		if (!(flags & kFontDontmap))
 			c_code = _charMap[c_code];
 		assert(c_code < FONT_CHARCOUNT);
 
 		// Check if character is defined
-		if ((draw_font->fce[c_code].index == 0) && (c_code != FONT_FIRSTCHAR)) {
+		if ((drawFont.fontCharEntry[c_code].index == 0) && (c_code != FONT_FIRSTCHAR)) {
 #if FONT_SHOWUNDEFINED
 			if (c_code == FONT_CH_SPACE) {
-				text_x += draw_font->fce[c_code].tracking;
+				textPoint.x += drawFont.fontCharEntry[c_code].tracking;
 				continue;
 			}
 			c_code = FONT_CH_QMARK;
@@ -436,49 +354,269 @@
 			// Character code is not defined, but advance tracking
 			// ( Not defined if offset is 0, except for 33 ('!') which
 			//   is defined )
-			text_x += draw_font->fce[c_code].tracking;
+			textPoint.x += drawFont.fontCharEntry[c_code].tracking;
 			continue;
 #endif
 		}
 
 		// Get length of character in bytes
-		c_byte_len = ((draw_font->fce[c_code].width - 1) / 8) + 1;
-		row_limit = (ds->h < (text_y + draw_font->hdr.c_height)) ? ds->h : text_y + draw_font->hdr.c_height;
-		char_row = 0;
+		c_byte_len = ((drawFont.fontCharEntry[c_code].width - 1) / 8) + 1;
+		rowLimit = (ds->h < (textPoint.y + drawFont.header.charHeight)) ? ds->h : textPoint.y + drawFont.header.charHeight;
+		charRow = 0;
 
-		for (row = text_y; row < row_limit; row++, char_row++) {
+		for (row = textPoint.y; row < rowLimit; row++, charRow++) {
 			// Clip negative rows */
 			if (row < 0) {
 				continue;
 			}
 
-			output_ptr = (byte *)ds->pixels + (ds->pitch * row) + text_x;
-			output_ptr_min = (byte *)ds->pixels + (ds->pitch * row) + (text_x > 0 ? text_x : 0);
-			output_ptr_max = output_ptr + (ds->pitch - text_x);
+			outputPointer = (byte *)ds->pixels + (ds->pitch * row) + textPoint.x;
+			outputPointer_min = (byte *)ds->pixels + (ds->pitch * row) + (textPoint.x > 0 ? textPoint.x : 0);
+			outputPointer_max = outputPointer + (ds->pitch - textPoint.x);
 
 			// If character starts off the screen, jump to next character
-			if (output_ptr < output_ptr_min) {
+			if (outputPointer < outputPointer_min) {
 				break;
 			}
 
-			c_data_ptr = draw_font->font_p + char_row * draw_font->hdr.row_length + draw_font->fce[c_code].index;
+			c_dataPointer = drawFont.font + charRow * drawFont.header.rowLength + drawFont.fontCharEntry[c_code].index;
 
-			for (c_byte = 0; c_byte < c_byte_len; c_byte++, c_data_ptr++) {
+			for (c_byte = 0; c_byte < c_byte_len; c_byte++, c_dataPointer++) {
 				// Check each bit, draw pixel if bit is set
-				for (c_bit = 7; c_bit >= 0 && (output_ptr < output_ptr_max); c_bit--) {
-					if ((*c_data_ptr >> c_bit) & 0x01) {
-						*output_ptr = (byte) color;
+				for (c_bit = 7; c_bit >= 0 && (outputPointer < outputPointer_max); c_bit--) {
+					if ((*c_dataPointer >> c_bit) & 0x01) {
+						*outputPointer = (byte) color;
 					}
-					output_ptr++;
+					outputPointer++;
 				} // end per-bit processing
 			} // end per-byte processing
 		} // end per-row processing
 
 		// Advance tracking position
-		text_x += draw_font->fce[c_code].tracking;
+		textPoint.x += drawFont.fontCharEntry[c_code].tracking;
 	} // end per-character processing
+}
 
-	return SUCCESS;
+
+void Font::textDraw(FontId fontId, Surface *ds, const char *text, const Common::Point &point, int color, int effectColor, FontEffectFlags flags) {
+	int textWidth;
+	int textLength;
+	int fitWidth;
+	Common::Point textPoint(point);
+
+	textLength = strlen(text);
+
+	if (!(flags & kFontCentered)) {
+		// Text is not centered; No formatting required
+		draw(fontId, ds, text, textLength, point, color, effectColor, flags);
+		return;
+	}
+
+	// Text is centered... format output
+	// Enforce minimum and maximum center points for centered text
+	if (textPoint.x < TEXT_CENTERLIMIT) {
+		textPoint.x = TEXT_CENTERLIMIT;
+	}
+
+	if (textPoint.x > ds->w - TEXT_CENTERLIMIT) {
+		textPoint.x = ds->w - TEXT_CENTERLIMIT;
+	}
+
+	if (textPoint.x < (TEXT_MARGIN * 2)) {
+		// Text can't be centered if it's too close to the margin
+		return;
+	}
+
+	textWidth = getStringWidth(fontId, text, textLength, flags);
+
+	if (textPoint.x < (ds->w / 2)) {
+		// Fit to right side
+		fitWidth = (textPoint.x - TEXT_MARGIN) * 2;
+	} else {
+		// Fit to left side
+		fitWidth = ((ds->w - TEXT_MARGIN) - textPoint.x) * 2;
+	}
+
+	if (fitWidth >= textWidth) {
+		// Entire string fits, draw it
+		textPoint.x = textPoint.x - (textWidth / 2);
+		draw(fontId, ds, text, textLength, textPoint, color, effectColor, flags);
+		return;
+	}
+}
+
+int Font::getHeight(FontId fontId, const char *text, int width, FontEffectFlags flags) {
+	int textWidth;
+	int textLength;
+	int fitWidth;
+	const char *startPointer;
+	const char *searchPointer;
+	const char *measurePointer;
+	const char *foundPointer;
+	int len;
+	int w;
+	const char *endPointer;
+	int h;
+	int wc;
+	int w_total;
+	int len_total;
+	Common::Point textPoint;
+	Common::Point textPoint2;
+
+	textLength = strlen(text);
+
+	textWidth = getStringWidth(fontId, text, textLength, flags);
+	h = getHeight(fontId);
+	fitWidth = width;
+
+	textPoint.x = (fitWidth / 2);
+	textPoint.y = 0;
+
+	if (fitWidth >= textWidth) {		
+		return h;
+	}
+
+	// String won't fit on one line
+	w_total = 0;
+	len_total = 0;
+	wc = 0;
+
+	startPointer = text;
+	measurePointer = text;
+	searchPointer = text;
+	endPointer = text + textLength;
+
+	for (;;) {
+		foundPointer = strchr(searchPointer, ' ');
+		if (foundPointer == NULL) {
+			// Ran to the end of the buffer
+			len = endPointer - measurePointer;
+		} else {
+			len = foundPointer - measurePointer;
+		}
+
+		w = getStringWidth(fontId, measurePointer, len, flags);
+		measurePointer = foundPointer;
+
+		if ((w_total + w) > fitWidth) {
+			// This word won't fit
+			if (wc == 0) {
+				// The first word in the line didn't fit. abort
+				return textPoint.y;
+			}
+			// Wrap what we've got and restart
+			textPoint.y += h + TEXT_LINESPACING;
+			w_total = 0;
+			len_total = 0;
+			wc = 0;
+			measurePointer = searchPointer;
+			startPointer = searchPointer;
+		} else {
+			// Word will fit ok
+			w_total += w;
+			len_total += len;
+			wc++;
+			if (foundPointer == NULL) {
+				// Since word hit NULL but fit, we are done
+				return textPoint.y + h;
+			}
+			searchPointer = measurePointer + 1;
+		}
+	}
+}
+
+void Font::textDrawRect(FontId fontId, Surface *ds, const char *text, const Common::Rect &rect, int color, int effectColor, FontEffectFlags flags) {
+	int textWidth;
+	int textLength;
+	int fitWidth;
+	const char *startPointer;
+	const char *searchPointer;
+	const char *measurePointer;
+	const char *foundPointer;
+	int len;
+	int w;
+	const char *endPointer;
+	int h;
+	int wc;
+	int w_total;
+	int len_total;
+	Common::Point textPoint;
+	Common::Point textPoint2;
+
+	textLength = strlen(text);
+
+	textWidth = getStringWidth(fontId, text, textLength, flags);
+	fitWidth = rect.width();
+
+	textPoint.x = rect.left + (fitWidth / 2);
+	textPoint.y = rect.top;
+
+	if (fitWidth >= textWidth) {
+	// Entire string fits, draw it
+		textPoint.x -= (textWidth / 2);
+		draw(fontId, ds, text, textLength, textPoint, color, effectColor, flags);
+		return;
+	}
+
+	// String won't fit on one line
+	h = getHeight(fontId);
+	w_total = 0;
+	len_total = 0;
+	wc = 0;
+
+	startPointer = text;
+	measurePointer = text;
+	searchPointer = text;
+	endPointer = text + textLength;
+
+	for (;;) {
+		foundPointer = strchr(searchPointer, ' ');
+		if (foundPointer == NULL) {
+			// Ran to the end of the buffer
+			len = endPointer - measurePointer;
+		} else {
+			len = foundPointer - measurePointer;
+		}
+
+		w = getStringWidth(fontId, measurePointer, len, flags);
+		measurePointer = foundPointer;
+
+		if ((w_total + w) > fitWidth) {
+			// This word won't fit
+			if (wc == 0) {
+				// The first word in the line didn't fit. abort
+				return;
+			}
+
+			// Wrap what we've got and restart
+			textPoint2.x = textPoint.x - (w_total / 2);
+			textPoint2.y = textPoint.y;
+			draw(fontId, ds, startPointer, len_total, textPoint2, color, effectColor, flags);
+			textPoint.y += h + TEXT_LINESPACING;
+			if (textPoint.y >= rect.bottom) {
+				return;
+			}
+			w_total = 0;
+			len_total = 0;
+			wc = 0;
+			measurePointer = searchPointer;
+			startPointer = searchPointer;
+		} else {
+			// Word will fit ok
+			w_total += w;
+			len_total += len;
+			wc++;
+			if (foundPointer == NULL) {
+				// Since word hit NULL but fit, we are done
+				textPoint2.x = textPoint.x - (w_total / 2);
+				textPoint2.y = textPoint.y;
+				draw(fontId, ds, startPointer, len_total, textPoint2, color,
+					effectColor, flags);
+				return;
+			}
+			searchPointer = measurePointer + 1;
+		}
+	}
 }
 
 } // End of namespace Saga

Index: font.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/font.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- font.h	9 Jul 2005 16:23:44 -0000	1.13
+++ font.h	14 Jul 2005 17:46:19 -0000	1.14
@@ -26,6 +26,7 @@
 #ifndef SAGA_FONT_H__
 #define SAGA_FONT_H__
 
+#include "saga/list.h"
 #include "saga/gfx.h"
 
 namespace Saga {
@@ -48,80 +49,98 @@
 
 #define SAGA_FONT_HEADER_LEN 6
 
-enum FONT_ID {
-	SMALL_FONT_ID,
-	MEDIUM_FONT_ID,
-	BIG_FONT_ID
+#define TEXT_CENTERLIMIT 50
+#define TEXT_MARGIN 10
+#define TEXT_LINESPACING 2
+
+struct TextListEntry {
+	int display;
+//	int id;
+	Common::Point point;
+	int color;
+	int effectColor;
+	FontEffectFlags flags;
+	FontId fontId;
+	const char *text;
+	TextListEntry() {
+		memset(this, 0, sizeof(*this)); 
+	}
 };
 
-enum FONT_EFFECT_FLAGS {
-	FONT_NORMAL   = 0,
-	FONT_OUTLINE  = 1 << 0,
-	FONT_SHADOW   = 1 << 1,
-	FONT_BOLD     = 1 << 2,
-	FONT_CENTERED = 1 << 3,
-	FONT_DONTMAP  = 1 << 4
+class TextList: public SortedList<TextListEntry> {
+public:
+
+	TextListEntry *addEntry(const TextListEntry &entry) {
+		return pushBack(entry).operator->();
+	}
 };
 
-struct FONT_HEADER {
-	int c_height;
-	int c_width;
-	int row_length;
+
+struct FontHeader {
+	int charHeight;
+	int charWidth;
+	int rowLength;
 };
 
-struct FONT_CHAR_ENTRY {
+struct FontCharEntry {
 	int index;
-	int byte_width;
+	int byteWidth;
 	int width;
 	int flag;
 	int tracking;
 };
 
-struct FONT_STYLE {
-	FONT_HEADER hdr;
-	FONT_CHAR_ENTRY fce[256];
-	byte *font_free_p;
-	byte *font_p;
+struct FontStyle {
+	FontHeader header;
+	FontCharEntry fontCharEntry[256];
+	byte *font;
 };
 
-struct FONT {
-	uint32 font_rn;
-	int font_id;
-
-	int normal_loaded;
-	FONT_STYLE *normal;
-	int outline_loaded;
-	FONT_STYLE *outline;
-
-	byte *res_data;
-	size_t res_len;
+struct FontData {
+	FontStyle normal;
+	FontStyle outline;
 };
 
 class Font {
  public:
 	Font(SagaEngine *vm);
 	~Font(void);
-	int draw(int font_id, Surface *ds, const char *draw_str, size_t draw_str_len,
-				  int text_x, int text_y, int color, int effect_color, int flags);
-	int getStringWidth(int font_id, const char *test_str, size_t test_str_ct, int flags);
-	int getHeight(int font_id);
+	int getStringWidth(FontId fontId, const char *text, size_t count, FontEffectFlags flags);
+	int getHeight(FontId fontId);
+	int getHeight(FontId fontId, const char *text, int width, FontEffectFlags flags);
 
+	void textDraw(FontId fontId, Surface *ds, const char *string, const Common::Point &point, int color, int effectColor, FontEffectFlags flags);
+	void textDrawRect(FontId fontId, Surface *ds, const char *text, const Common::Rect &rect, int color, int effectColor, FontEffectFlags flags);
+	
+	void validate(FontId fontId) {
+		if ((fontId < 0) || (fontId >= _loadedFonts)) {
+			error("Font::validate: Invalid font id.");
+		}
+	}
  private:
 
-	int loadFont(uint32 fontResourceId);
-	FONT_STYLE *createOutline(FONT_STYLE * src_font);
-	int outFont(FONT_STYLE *font, Surface *ds, const char *draw_str, size_t draw_str_ct,
-				int text_x, int text_y, int color, int flags);
-	int getByteLen(int num_bits);
+	void loadFont(uint32 fontResourceId);
+	void createOutline(FontData *font);
+	void draw(FontId fontId, Surface *ds, const char *text, size_t count, const Common::Point &point, int color, int effectColor, FontEffectFlags flags);
+	void outFont(const FontStyle &drawFont, Surface *ds, const char *text, size_t count, const Common::Point &point, int color, FontEffectFlags flags);
+	int getByteLen(int numBits) const {
+		int byteLength = numBits / 8;
+
+		if (numBits % 8) {
+			byteLength++;
+		}
+
+		return byteLength;
+	}
+
 
 	static const int _charMap[256];
 	SagaEngine *_vm;
 
 	bool _initialized;
-	RSCFILE_CONTEXT *_fontContext;
 
-	int _nFonts;
-	FONT **_fonts;
+	int _loadedFonts;
+	FontData **_fonts;
 };
 
 } // End of namespace Saga

Index: image.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/image.cpp,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- image.cpp	11 Jan 2005 21:10:19 -0000	1.22
+++ image.cpp	14 Jul 2005 17:46:19 -0000	1.23
@@ -48,7 +48,7 @@
 
 int SagaEngine::decodeBGImage(const byte *image_data, size_t image_size,
 					byte **output_buf, size_t *output_buf_len, int *w, int *h) {
-	IMAGE_HEADER hdr;
+	ImageHeader hdr;
 	int modex_height;
 	const byte *RLE_data_ptr;
 	size_t RLE_data_len;

Index: interface.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/interface.cpp,v
retrieving revision 1.115
retrieving revision 1.116
diff -u -d -r1.115 -r1.116
--- interface.cpp	12 Jul 2005 18:31:47 -0000	1.115
+++ interface.cpp	14 Jul 2005 17:46:19 -0000	1.116
@@ -644,16 +644,20 @@
 	const char *text;
 	int textWidth;
 	Rect rect;
+	Point textPoint;
 
 	text = _vm->getTextString(panelButton->id);
 	panel->calcPanelButtonRect(panelButton, rect);
 	if (panelButton->xOffset < 0) {
-		textWidth = _vm->_font->getStringWidth(MEDIUM_FONT_ID, text, 0, 0);
+		textWidth = _vm->_font->getStringWidth(kMediumFont, text, 0, kFontNormal);
 		rect.left += 2 + (panel->imageWidth - 1 - textWidth) / 2;
 	}
 
-	_vm->_font->draw(MEDIUM_FONT_ID, ds, text, 0, rect.left , rect.top + 1,
-		_vm->getDisplayInfo().verbTextColor, _vm->getDisplayInfo().verbTextShadowColor, FONT_SHADOW);
+	textPoint.x = rect.left;
+	textPoint.y = rect.top + 1;
+	
+	_vm->_font->textDraw(kMediumFont, ds, text, textPoint,
+		_vm->getDisplayInfo().verbTextColor, _vm->getDisplayInfo().verbTextShadowColor, kFontShadow);
 }
 
 void Interface::drawOption() {
@@ -667,6 +671,7 @@
 	Rect rect;
 	Rect rect2;
 	PanelButton *panelButton;
+	Point textPoint;
 
 	backBuffer = _vm->_gfx->getBackBuffer();
 
@@ -696,7 +701,7 @@
 	_optionPanel.calcPanelButtonRect(_optionSaveFilePanel, rect);
 	rect.top++;
 	rect2 = rect;
-	fontHeight = _vm->_font->getHeight(SMALL_FONT_ID);
+	fontHeight = _vm->_font->getHeight(kSmallFont);
 	for (j = 0; j < _vm->getDisplayInfo().optionSaveFileVisible; j++) {
 		bgColor = kITEColorDarkGrey0C;
 		fgColor = kITEColorBrightWhite;
@@ -710,8 +715,9 @@
 			rect2.bottom = rect2.top + fontHeight;
 			backBuffer->fillRect(rect2, bgColor);
 			text = _vm->getSaveFile(idx)->name;
-			_vm->_font->draw(SMALL_FONT_ID, backBuffer, text, 0,
-				 rect.left + 1, rect2.top, fgColor, 0, 0);
+			textPoint.x = rect.left + 1;
+			textPoint.y = rect2.top;
+			_vm->_font->textDraw(kSmallFont, backBuffer, text, textPoint, fgColor, 0, kFontNormal);
 		}
 	}
 
@@ -918,8 +924,8 @@
 			(ascii == ' ')) {
 			if (_textInputStringLength < SAVE_TITLE_SIZE - 1) {
 				ch[0] = ascii;
-				tempWidth = _vm->_font->getStringWidth(SMALL_FONT_ID, ch, 0, 0);
-				tempWidth += _vm->_font->getStringWidth(SMALL_FONT_ID, _textInputString, 0, 0);
+				tempWidth = _vm->_font->getStringWidth(kSmallFont, ch, 0, kFontNormal);
+				tempWidth += _vm->_font->getStringWidth(kSmallFont, _textInputString, 0, kFontNormal);
 				if (tempWidth > _textInputMaxWidth) {
 									break;
 				}
@@ -945,6 +951,7 @@
 }
 
 void Interface::drawTextInput(Surface *ds, InterfacePanel *panel, PanelButton *panelButton) {
+	Point textPoint;
 	Rect rect;
 	char ch[2];
 	int fgColor;
@@ -955,24 +962,26 @@
 	drawButtonBox(ds, rect, kEdit, _textInput);
 	rect.left += 4; 
 	rect.top += 4;
-	rect.setHeight(_vm->_font->getHeight(SMALL_FONT_ID));
+	rect.setHeight(_vm->_font->getHeight(kSmallFont));
 
 	i = 0;	
 	while ((ch[0] = _textInputString[i++]) != 0) {
-		rect.setWidth(_vm->_font->getStringWidth(SMALL_FONT_ID, ch, 0, 0));
+		rect.setWidth(_vm->_font->getStringWidth(kSmallFont, ch, 0, kFontNormal));
 		if ((i == _textInputPos) && _textInput) {
 			fgColor = kITEColorBlack;	
 			ds->fillRect(rect, kITEColorWhite);
 		} else {
 			fgColor = kITEColorWhite;	
 		}
-		_vm->_font->draw(SMALL_FONT_ID, ds, ch, 0, rect.left, 
-			rect.top + 1, fgColor, 0, 0); 
+		textPoint.x = rect.left;
+		textPoint.y = rect.top + 1;
+
+		_vm->_font->textDraw(kSmallFont, ds, ch, textPoint, fgColor, 0, kFontNormal); 
 		rect.left += rect.width();
 	}
 	if (_textInput && (_textInputPos >= i)) {
 		ch[0] = ' ';
-		rect.setWidth(_vm->_font->getStringWidth(SMALL_FONT_ID, ch, 0, 0));
+		rect.setWidth(_vm->_font->getStringWidth(kSmallFont, ch, 0, kFontNormal));
 		ds->fillRect(rect, kITEColorWhite);
 	}
 }
@@ -1141,7 +1150,7 @@
 	} else {
 		if (_optionPanel.currentButton == _optionSaveFilePanel) {
 			_optionPanel.calcPanelButtonRect(_optionSaveFilePanel, rect);
-			_optionSaveFileTitleNumber = (mousePoint.y - rect.top) / (_vm->_font->getHeight(SMALL_FONT_ID) + 1);
+			_optionSaveFileTitleNumber = (mousePoint.y - rect.top) / (_vm->_font->getHeight(kSmallFont) + 1);
 			
 			if (_optionSaveFileTitleNumber >= _vm->getDisplayInfo().optionSaveFileVisible) {
 				_optionSaveFileTitleNumber = _vm->getDisplayInfo().optionSaveFileVisible - 1;
@@ -1315,8 +1324,8 @@
 void Interface::drawStatusBar() {
 	Surface *backBuffer;
 	Rect rect;
-
-	int string_w;
+	Point textPoint;
+	int stringWidth;
 	int color;
 
 	backBuffer = _vm->_gfx->getBackBuffer();
@@ -1337,15 +1346,16 @@
 
 	backBuffer->drawRect(rect, _vm->getDisplayInfo().statusBGColor);
 
-	string_w = _vm->_font->getStringWidth(SMALL_FONT_ID, _statusText, 0, 0);
+	stringWidth = _vm->_font->getStringWidth(kSmallFont, _statusText, 0, kFontNormal);
 
 	if (_statusOnceColor == -1)
 		color = _vm->getDisplayInfo().statusTextColor;
 	else
 		color = _statusOnceColor;
 
-	_vm->_font->draw(SMALL_FONT_ID, backBuffer, _statusText, 0, _vm->getDisplayInfo().statusXOffset + (_vm->getDisplayInfo().statusWidth - string_w) / 2,
-			_vm->getDisplayInfo().statusYOffset + _vm->getDisplayInfo().statusTextY, color, 0, 0);
+	textPoint.x = _vm->getDisplayInfo().statusXOffset + (_vm->getDisplayInfo().statusWidth - stringWidth) / 2;
+	textPoint.y = _vm->getDisplayInfo().statusYOffset + _vm->getDisplayInfo().statusTextY;
+	_vm->_font->textDraw(kSmallFont, backBuffer, _statusText, textPoint, color, 0, kFontNormal);
 
 	if (_saveReminderState > 0) {
 		rect.left = _vm->getDisplayInfo().saveReminderXOffset;
@@ -1701,8 +1711,8 @@
 	}
 	text = _vm->getTextString(textId);
 
-	textWidth = _vm->_font->getStringWidth(MEDIUM_FONT_ID, text, 0, 0);
-	textHeight = _vm->_font->getHeight(MEDIUM_FONT_ID);
+	textWidth = _vm->_font->getStringWidth(kMediumFont, text, 0, kFontNormal);
+	textHeight = _vm->_font->getHeight(kMediumFont);
 
 	point.x = panel->x + panelButton->xOffset + (panelButton->width / 2) - (textWidth / 2);
 	point.y = panel->y + panelButton->yOffset + (panelButton->height / 2) - (textHeight / 2);
@@ -1716,8 +1726,8 @@
 	panel->calcPanelButtonRect(panelButton, rect);
 	drawButtonBox(ds, rect, kButton, panelButton->state > 0);
 
-	_vm->_font->draw(MEDIUM_FONT_ID, ds, text, 0, point.x , point.y, 
-		textColor, _vm->getDisplayInfo().verbTextShadowColor, FONT_SHADOW);
+	_vm->_font->textDraw(kMediumFont, ds, text, point, 
+		textColor, _vm->getDisplayInfo().verbTextShadowColor, kFontShadow);
 }
 
 void Interface::drawPanelButtonArrow(Surface *ds, InterfacePanel *panel, PanelButton *panelButton) {
@@ -1753,12 +1763,12 @@
 
 	text = _vm->getTextString(textId);
 	
-	textWidth = _vm->_font->getStringWidth(SMALL_FONT_ID, text, 0, 0);
+	textWidth = _vm->_font->getStringWidth(kSmallFont, text, 0, kFontNormal);
 
 	point.x = _mainPanel.x + panelButton->xOffset + 1 + (panelButton->width - 1 - textWidth) / 2;
 	point.y = _mainPanel.y + panelButton->yOffset + 1;
 
-	_vm->_font->draw(SMALL_FONT_ID, ds, text, 0, point.x , point.y, textColor, textShadowColor, (textShadowColor != 0) ? FONT_SHADOW : 0);
+	_vm->_font->textDraw(kSmallFont, ds, text, point, textColor, textShadowColor, (textShadowColor != 0) ? kFontShadow : kFontNormal);
 }
 	
 
@@ -1804,10 +1814,9 @@
 		for (i = len; i >= 0; i--) {
 			c = _converseWorkString[i];
 
-			if ((c == ' ' || c == '\0')
-				&& _vm->_font->getStringWidth(SMALL_FONT_ID, _converseWorkString, i, 0) 
-					<= CONVERSE_MAX_TEXT_WIDTH)
+			if ((c == ' ' || c == '\0') && (_vm->_font->getStringWidth(kSmallFont, _converseWorkString, i, kFontNormal) <= CONVERSE_MAX_TEXT_WIDTH)) {
 				break;
+			}				
 		}
 		if (i < 0) {
 			return true;
@@ -1877,6 +1886,7 @@
 		(char)0xb7, 0 
 	};
 	Rect rect(8, CONVERSE_TEXT_LINES * CONVERSE_TEXT_HEIGHT);
+	Point textPoint;
 	
 	assert(_conversePanel.buttonsCount >= 6);
 
@@ -1910,11 +1920,14 @@
 		str = _converseText[relPos].text;
 
 		if (_converseText[relPos].textNum == 0) { // first entry
-			_vm->_font->draw(SMALL_FONT_ID, ds, bullet, 1,
-				rect.left - 6, rect.top, bulletForegnd, bulletBackgnd, FONT_SHADOW | FONT_DONTMAP);
+			textPoint.x = rect.left - 6;
+			textPoint.y = rect.top;
+
+			_vm->_font->textDraw(kSmallFont, ds, bullet, textPoint, bulletForegnd, bulletBackgnd, (FontEffectFlags)(kFontShadow | kFontDontmap));
 		}
-		_vm->_font->draw(SMALL_FONT_ID, ds, str, strlen(str),
-			rect.left + 1, rect.top, foregnd, kITEColorBlack, FONT_SHADOW);
+		textPoint.x = rect.left + 1;
+		textPoint.y = rect.top;
+		_vm->_font->textDraw(kSmallFont, ds, str, textPoint, foregnd, kITEColorBlack, kFontShadow);
 	}
 
 	if (_converseStartPos != 0) {

Index: ite_introproc.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/ite_introproc.cpp,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- ite_introproc.cpp	9 Jul 2005 23:07:46 -0000	1.58
+++ ite_introproc.cpp	14 Jul 2005 17:46:20 -0000	1.59
@@ -32,7 +32,6 @@
 #include "saga/font.h"
 #include "saga/rscfile_mod.h"
 #include "saga/sndres.h"
-#include "saga/text.h"
 #include "saga/palanim.h"
 #include "saga/music.h"
 
@@ -86,29 +85,29 @@
 }
 
 EVENT *Scene::ITEQueueDialogue(EVENT *q_event, int n_dialogues, const INTRO_DIALOGUE dialogue[]) {
-	TEXTLIST_ENTRY text_entry;
-	TEXTLIST_ENTRY *entry_p;
+	TextListEntry textEntry;
+	TextListEntry *entry;
 	EVENT event;
 	int voice_len;
 	int i;
 
 	// Queue narrator dialogue list
-	text_entry.color = 255;
-	text_entry.effect_color = 0;
-	text_entry.text_x = 320 / 2;
-	text_entry.text_y = (_vm->getFeatures() & GF_LANG_DE) ? INTRO_DE_CAPTION_Y : INTRO_CAPTION_Y;
-	text_entry.font_id = MEDIUM_FONT_ID;
-	text_entry.flags = FONT_OUTLINE | FONT_CENTERED;
+	textEntry.color = 255;
+	textEntry.effectColor = 0;
+	textEntry.point.x = 320 / 2;
+	textEntry.point.y = (_vm->getFeatures() & GF_LANG_DE) ? INTRO_DE_CAPTION_Y : INTRO_CAPTION_Y;
+	textEntry.fontId = kMediumFont;
+	textEntry.flags = (FontEffectFlags)(kFontOutline | kFontCentered);
 
 	for (i = 0; i < n_dialogues; i++) {
-		text_entry.string = dialogue[i].i_str;
-		entry_p = _vm->textAddEntry(_textList, &text_entry);
+		textEntry.text = dialogue[i].i_str;
+		entry = _vm->_scene->_textList.addEntry(textEntry);
 
 		// Display text
 		event.type = ONESHOT_EVENT;
 		event.code = TEXT_EVENT;
 		event.op = EVENT_DISPLAY;
-		event.data = entry_p;
+		event.data = entry;
 		event.time = (i == 0) ? 0 : VOICE_PAD;
 
 		q_event = _vm->_events->chain(q_event, &event);
@@ -131,7 +130,7 @@
 		event.type = ONESHOT_EVENT;
 		event.code = TEXT_EVENT;
 		event.op = EVENT_REMOVE;
-		event.data = entry_p;
+		event.data = entry;
 		event.time = voice_len;
 
 		q_event = _vm->_events->chain(q_event, &event);
@@ -182,7 +181,7 @@
 
 	int line_spacing = 0;
 	int paragraph_spacing;
-	int font = 0;
+	FontId font = kSmallFont;
 	int i;
 
 	int n_paragraphs = 0;
@@ -199,12 +198,12 @@
 
 		switch (credits[i].type) {
 		case kCHeader:
-			font = SMALL_FONT_ID;
+			font = kSmallFont;
 			line_spacing = 4;
 			n_paragraphs++;
 			break;
 		case kCText:
-			font = MEDIUM_FONT_ID;
+			font = kMediumFont;
 			line_spacing = 2;
 			break;
 		default:
@@ -219,15 +218,15 @@
 
 	int y = paragraph_spacing;
 
-	TEXTLIST_ENTRY text_entry;
-	TEXTLIST_ENTRY *entry_p;
+	TextListEntry textEntry;
+	TextListEntry *entry;
 	EVENT event;
 	EVENT *q_event = NULL;
 
-	text_entry.color = 255;
-	text_entry.effect_color = 0;
-	text_entry.flags = FONT_OUTLINE | FONT_CENTERED;
-	text_entry.text_x = 160;
+	textEntry.color = 255;
+	textEntry.effectColor = 0;
+	textEntry.flags = (FontEffectFlags)(kFontOutline | kFontCentered);
+	textEntry.point.x = 160;
 
 	for (i = 0; i < n_credits; i++) {
 		if (credits[i].lang != lang && credits[i].lang != UNK_LANG) {
@@ -240,29 +239,29 @@
 
 		switch (credits[i].type) {
 		case kCHeader:
-			font = SMALL_FONT_ID;
+			font = kSmallFont;
 			line_spacing = 4;
 			y += paragraph_spacing;
 			break;
 		case kCText:
-			font = MEDIUM_FONT_ID;
+			font = kMediumFont;
 			line_spacing = 2;
 			break;
 		default:
 			break;
 		}
 
-		text_entry.string = credits[i].string;
-		text_entry.font_id = font;
-		text_entry.text_y = y;
+		textEntry.text = credits[i].string;
+		textEntry.fontId = font;
+		textEntry.point.y = y;
 
-		entry_p = _vm->textAddEntry(_textList, &text_entry);
+		entry = _vm->_scene->_textList.addEntry(textEntry);
 
 		// Display text
 		event.type = ONESHOT_EVENT;
 		event.code = TEXT_EVENT;
 		event.op = EVENT_DISPLAY;
-		event.data = entry_p;
+		event.data = entry;
 		event.time = delta_time;
 
 		q_event = _vm->_events->queue(&event);
@@ -271,7 +270,7 @@
 		event.type = ONESHOT_EVENT;
 		event.code = TEXT_EVENT;
 		event.op = EVENT_REMOVE;
-		event.data = entry_p;
+		event.data = entry;
 		event.time = duration;
 
 		q_event = _vm->_events->chain(q_event, &event);

Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/module.mk,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- module.mk	9 Jul 2005 17:11:41 -0000	1.26
+++ module.mk	14 Jul 2005 17:46:20 -0000	1.27
@@ -28,7 +28,6 @@
 	saga/sndres.o \
 	saga/sprite.o \
 	saga/sthread.o \
-	saga/text.o \
 	saga/input.o \
 	saga/music.o \
 	saga/sound.o

Index: objectmap.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/objectmap.cpp,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- objectmap.cpp	9 Jul 2005 16:23:44 -0000	1.41
+++ objectmap.cpp	14 Jul 2005 17:46:20 -0000	1.42
@@ -219,6 +219,7 @@
 	int hitZoneIndex;
 	char txtBuf[32];
 	Point pickPoint;
+	Point textPoint;
 	Location pickLocation;
 	pickPoint = testPoint;
 	if (_vm->_scene->getFlags() & kSceneFlagISO) {
@@ -236,9 +237,9 @@
 
 	if (hitZoneIndex != -1) {		
 		snprintf(txtBuf, sizeof(txtBuf), "hitZone %d", hitZoneIndex);
-		_vm->_font->draw(SMALL_FONT_ID, ds, txtBuf, 0, 2, 2,
-			kITEColorBrightWhite, kITEColorBlack, FONT_OUTLINE);
-
+		textPoint.x = 2;
+		textPoint.y = 2;
+		_vm->_font->textDraw(kSmallFont, ds, txtBuf, textPoint, kITEColorBrightWhite, kITEColorBlack, kFontOutline);
 	}
 }
 

Index: puzzle.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/puzzle.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- puzzle.cpp	9 Jul 2005 16:23:44 -0000	1.10
+++ puzzle.cpp	14 Jul 2005 17:46:20 -0000	1.11
@@ -165,6 +165,10 @@
 	_puzzlePiece = -1;
 	_newPuzzle = true;
 	_sliding = false;
+	_hintBox.left = 70;
+	_hintBox.top = 105;
+	_hintBox.setWidth(240);
+	_hintBox.setHeight(30);
 
 	initPieceInfo( 0, 268,  18,  0, 0,  0 + PUZZLE_X_OFFSET,   0 + PUZZLE_Y_OFFSET, 0, 3,
 		  Point(0, 1),  Point(0, 62), Point(15, 31), Point(0, 0), Point(0, 0), Point(0,0));
@@ -480,7 +484,7 @@
 		if (_hintOffer >= NUM_SOLICIT_REPLIES)
 			_hintOffer = 0;
 
-		_vm->_actor->nonActorSpeech(&solicitStr[_lang][i], 1, 0);
+		_vm->_actor->nonActorSpeech(_hintBox, &solicitStr[_lang][i], 1, 0);
 
 		//	Determine which of the journeymen will offer then
 		//	hint, and then show that character's portrait.
@@ -503,7 +507,7 @@
 
 	case kRQHintRequested:
 		i = _vm->_rnd.getRandomNumber(NUM_SAKKA - 1);
-		_vm->_actor->nonActorSpeech(&sakkaStr[_lang][i], 1, 0);
+		_vm->_actor->nonActorSpeech(_hintBox, &sakkaStr[_lang][i], 1, 0);
 
 		_vm->_interface->setRightPortrait(RID_ITE_SAKKA_APPRAISING);
 
@@ -520,7 +524,7 @@
 	case kRQHintRequestedStage2:
 		if (_vm->_rnd.getRandomNumber(1)) {			//	Skip Reply part
 			i = _vm->_rnd.getRandomNumber(NUM_WHINES - 1);
-			_vm->_actor->nonActorSpeech(&whineStr[_lang][i], 1, 0);
+			_vm->_actor->nonActorSpeech(_hintBox, &whineStr[_lang][i], 1, 0);
 		}
 
 		_vm->_interface->setRightPortrait(_hintGiver);
@@ -588,7 +592,7 @@
 	_vm->_actor->setSpeechColor(1, kITEColorBlack);
 
 	if (_hintCount < 3) {
-		_vm->_actor->nonActorSpeech(&hintStr[_lang][_hintCount], 1, 0 );
+		_vm->_actor->nonActorSpeech(_hintBox, &hintStr[_lang][_hintCount], 1, 0 );
 	} else {
 		int piece = 0;
 
@@ -607,11 +611,11 @@
 			const char *hintPtr = hintBuf;
 			sprintf(hintBuf, optionsStr[_lang][kROHint], pieceNames[piece]);
 
-			_vm->_actor->nonActorSpeech(&hintPtr, 1, 0);
+			_vm->_actor->nonActorSpeech(_hintBox, &hintPtr, 1, 0);
 		}
 		else {
 				//	If no pieces are in the wrong place
-			_vm->_actor->nonActorSpeech(&hintStr[_lang][3], 1, 0);
+			_vm->_actor->nonActorSpeech(_hintBox, &hintStr[_lang][3], 1, 0);
 		}
 	}
 	_hintCount++;

Index: puzzle.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/puzzle.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- puzzle.h	31 May 2005 01:03:13 -0000	1.3
+++ puzzle.h	14 Jul 2005 17:46:20 -0000	1.4
@@ -102,6 +102,7 @@
 
 	PieceInfo _pieceInfo[PUZZLE_PIECES];
 	int _slidePointX, _slidePointY;
+	Rect _hintBox;
 };
 
 } // End of namespace Saga

Index: render.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/render.cpp,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -d -r1.66 -r1.67
--- render.cpp	9 Jul 2005 16:23:44 -0000	1.66
+++ render.cpp	14 Jul 2005 17:46:20 -0000	1.67
@@ -32,7 +32,6 @@
 #include "saga/puzzle.h"
 #include "saga/render.h"
 #include "saga/scene.h"
-#include "saga/text.h"
 
 #include "common/timer.h"
 #include "common/system.h"
@@ -40,6 +39,7 @@
 namespace Saga {
 
 const char *test_txt = "The quick brown fox jumped over the lazy dog. She sells sea shells down by the sea shore.";
+const char *pauseString = "PAWS GAME";
 
 Render::Render(SagaEngine *vm, OSystem *system) {
 	_vm = vm;
@@ -69,9 +69,9 @@
 
 void Render::drawScene() {
 	Surface *backBufferSurface;
-	char txt_buf[20];
-	int fps_width;
-	Point mouse_pt;
+	char txtBuffer[20];
+	Point mousePoint;
+	Point textPoint;
 
 	assert(_initialized);
 
@@ -80,7 +80,7 @@
 	backBufferSurface = _vm->_gfx->getBackBuffer();
 
 	// Get mouse coordinates
-	mouse_pt = _vm->mousePos();
+	mousePoint = _vm->mousePos();
 
 	if (/*_vm->_interface->getMode() != kPanelPlacard*/!(_flags & (RF_PLACARD | RF_MAP))) {
 		// Display scene background
@@ -88,7 +88,7 @@
 
 		if (_vm->_interface->getFadeMode() != kFadeOut) {
 			if (_vm->_puzzle->isActive()) {
-				_vm->_puzzle->movePiece(mouse_pt);
+				_vm->_puzzle->movePiece(mousePoint);
 				_vm->_actor->drawSpeech();
 			} else {
 				// Draw queued actors
@@ -98,9 +98,9 @@
 
 			if (getFlags() & RF_OBJECTMAP_TEST) {
 				if (_vm->_scene->_objectMap)
-					_vm->_scene->_objectMap->draw(backBufferSurface, mouse_pt, kITEColorBrightWhite, kITEColorBlack);
+					_vm->_scene->_objectMap->draw(backBufferSurface, mousePoint, kITEColorBrightWhite, kITEColorBlack);
 				if (_vm->_scene->_actionMap)
-					_vm->_scene->_actionMap->draw(backBufferSurface, mouse_pt, kITEColorRed, kITEColorBlack);
+					_vm->_scene->_actionMap->draw(backBufferSurface, mousePoint, kITEColorRed, kITEColorBlack);
 			}
 			if (getFlags() & RF_ACTOR_PATH_TEST) {
 				_vm->_actor->drawPathTest();
@@ -129,35 +129,36 @@
 	}
 
 	// Draw queued text strings
-	_vm->textDrawList(_vm->_scene->_textList, backBufferSurface);
+	_vm->_scene->drawTextList(backBufferSurface);
 
 	// Handle user input
 	_vm->processInput();
 
 	// Display rendering information
 	if (_flags & RF_SHOW_FPS) {
-		sprintf(txt_buf, "%d", _fps);
-		fps_width = _vm->_font->getStringWidth(SMALL_FONT_ID, txt_buf, 0, FONT_NORMAL);
-		_vm->_font->draw(SMALL_FONT_ID, backBufferSurface, txt_buf, 0, backBufferSurface->w - fps_width, 2,
-					kITEColorBrightWhite, kITEColorBlack, FONT_OUTLINE);
+		sprintf(txtBuffer, "%d", _fps);
+		textPoint.x = backBufferSurface->w - _vm->_font->getStringWidth(kSmallFont, txtBuffer, 0, kFontOutline); 
+		textPoint.y = 2;
+
+		_vm->_font->textDraw(kSmallFont, backBufferSurface, txtBuffer, textPoint, kITEColorBrightWhite, kITEColorBlack, kFontOutline);
 	}
 
 	// Display "paused game" message, if applicable
 	if (_flags & RF_RENDERPAUSE) {
-		int msg_len = strlen(PAUSEGAME_MSG);
-		int msg_w = _vm->_font->getStringWidth(BIG_FONT_ID, PAUSEGAME_MSG, msg_len, FONT_OUTLINE);
-		_vm->_font->draw(BIG_FONT_ID, backBufferSurface, PAUSEGAME_MSG, msg_len,
-				(backBufferSurface->w - msg_w) / 2, 90, kITEColorBrightWhite, kITEColorBlack, FONT_OUTLINE);
+		textPoint.x = (backBufferSurface->w - _vm->_font->getStringWidth(kBigFont, pauseString, 0, kFontOutline)) / 2; 
+		textPoint.y = 90;
+
+		_vm->_font->textDraw(kBigFont, backBufferSurface, pauseString, textPoint, kITEColorBrightWhite, kITEColorBlack, kFontOutline);
 	}
 
 	// Update user interface
-
-	_vm->_interface->update(mouse_pt, UPDATE_MOUSEMOVE);
+	_vm->_interface->update(mousePoint, UPDATE_MOUSEMOVE);
 
 	// Display text formatting test, if applicable
 	if (_flags & RF_TEXT_TEST) {
-		_vm->textDraw(MEDIUM_FONT_ID, backBufferSurface, test_txt, mouse_pt.x, mouse_pt.y,
-				kITEColorBrightWhite, kITEColorBlack, FONT_OUTLINE | FONT_CENTERED);
+		Rect rect(mousePoint.x, mousePoint.y, mousePoint.x + 100, mousePoint.y + 50);
+		_vm->_font->textDrawRect(kMediumFont, backBufferSurface, test_txt, rect,
+				kITEColorBrightWhite, kITEColorBlack, (FontEffectFlags)(kFontOutline | kFontCentered));
 	}
 
 	// Display palette test, if applicable

Index: render.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/render.h,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- render.h	9 Jul 2005 16:23:45 -0000	1.25
+++ render.h	14 Jul 2005 17:46:21 -0000	1.26
@@ -30,7 +30,6 @@
 
 namespace Saga {
 
-#define PAUSEGAME_MSG "PAWS GAME"
 enum RENDER_FLAGS {
 	RF_SHOW_FPS = (1 << 0),
 	RF_PALETTE_TEST = (1 << 1),

Index: saga.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/saga.h,v
retrieving revision 1.105
retrieving revision 1.106
diff -u -d -r1.105 -r1.106
--- saga.h	9 Jul 2005 17:11:41 -0000	1.105
+++ saga.h	14 Jul 2005 17:46:21 -0000	1.106
@@ -33,7 +33,6 @@
 #include "common/stream.h"
 #include "common/rect.h"
 
-#include "saga/text.h"
 #include "saga/gfx.h"
 #include "saga/list.h"
 
@@ -215,7 +214,7 @@
 	kTextEnterSaveGameName
 };
 
-struct IMAGE_HEADER {
+struct ImageHeader {
 	int width;
 	int height;
 };
@@ -311,6 +310,21 @@
 	GF_CD_FX             = 1 << 6
 };
 
+enum FontId {
+	kSmallFont,
+	kMediumFont,
+	kBigFont
+};
+
+enum FontEffectFlags {
+	kFontNormal   = 0,
+	kFontOutline  = 1 << 0,
+	kFontShadow   = 1 << 1,
+	kFontBold     = 1 << 2,
+	kFontCentered = 1 << 3,
+	kFontDontmap  = 1 << 4
+};
+
 struct GameSoundInfo {
 	int res_type;
 	long freq;
@@ -574,17 +588,6 @@
 
 	const char *getObjectName(uint16 objectId);
 public:
-	TEXTLIST *textCreateList();
-	void textDestroyList(TEXTLIST *textlist);
-	void textClearList(TEXTLIST *textlist);
-	int textDrawList(TEXTLIST *textlist, Surface *ds);
-	TEXTLIST_ENTRY *textAddEntry(TEXTLIST *textlist, TEXTLIST_ENTRY *entry);
-	int textDeleteEntry(TEXTLIST *textlist, TEXTLIST_ENTRY *entry);
-	int textSetDisplay(TEXTLIST_ENTRY *entry, int val);
-	int textDraw(int font_id, Surface *ds, const char *string, int text_x, int text_y, int color,
-				  int effect_color, int flags);
-	int textProcessList(TEXTLIST *textlist, long ms);
-
 	int processInput(void);
 	const Point &mousePos() const {
 		return _mousePos;

Index: scene.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/scene.cpp,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -d -r1.120 -r1.121
--- scene.cpp	9 Jul 2005 16:23:45 -0000	1.120
+++ scene.cpp	14 Jul 2005 17:46:21 -0000	1.121
@@ -36,7 +36,6 @@
 #include "saga/render.h"
 #include "saga/rscfile_mod.h"
 #include "saga/script.h"
-#include "saga/text.h"
 #include "saga/sound.h"
 #include "saga/music.h"
 
@@ -95,15 +94,7 @@
 
 	debug(3, "First scene set to %d.", _firstScene);
 
-	debug(3, "LUT has %d entries.", _sceneCount);
-
-	// Create scene module text list
-	_textList = _vm->textCreateList();
-
-	if (_textList == NULL) {
-		warning("Scene::Scene(): Error: Couldn't create scene text list");
-		return;
-	}
+	debug(3, "LUT has %d entries.", _sceneCount);		
 
 	_sceneLoaded = false;
 	_sceneNumber = 0;
@@ -129,6 +120,18 @@
 	}
 }
 
+void Scene::drawTextList(Surface *ds) {
+	TextListEntry *entry;
+
+	for (TextList::iterator textIterator = _textList.begin(); textIterator != _textList.end(); ++textIterator) {
+		entry = (TextListEntry *)textIterator.operator->();
+		if (entry->display != 0) {
+			_vm->_font->textDraw(entry->fontId, ds, entry->text, entry->point, entry->color, entry->effectColor, entry->flags);
+		}
+	}
+}
+
+
 void Scene::startScene() {
 	SceneQueueList::iterator queueIterator;
 	LoadSceneParams *sceneQueue;
@@ -953,7 +956,7 @@
 	_vm->_isoMap->freeMem();
 
 	_vm->_events->clearList();
-	_vm->textClearList(_textList);
+	_textList.clear();
 
 	_sceneLoaded = false;
 

Index: scene.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/scene.h,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -d -r1.61 -r1.62
--- scene.h	9 Jul 2005 16:23:45 -0000	1.61
+++ scene.h	14 Jul 2005 17:46:21 -0000	1.62
@@ -26,7 +26,7 @@
 #ifndef SAGA_SCENE_H
 #define SAGA_SCENE_H
 
-#include "saga/text.h"
+#include "saga/font.h"
 #include "saga/list.h"
 #include "saga/actor.h"
 
@@ -263,6 +263,7 @@
 	int getOutsetSceneNumber() const { return _outsetSceneNumber; }
 	int currentSceneResourceId() const { return _sceneResourceId; }
 
+	void drawTextList(Surface *ds);
  private:
 	void loadScene(LoadSceneParams *loadSceneParams);
 	int loadSceneDescriptor(uint32 res_number);
@@ -301,7 +302,7 @@
 	ObjectMap *_objectMap;
 	SceneEntryList _entryList;
 	StringsTable _sceneStrings;
-	TEXTLIST *_textList;
+	TextList _textList;
 
  private:
 	int IHNMStartProc();

Index: script.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/script.h,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -d -r1.92 -r1.93
--- script.h	3 Jul 2005 20:02:56 -0000	1.92
+++ script.h	14 Jul 2005 17:46:21 -0000	1.93
@@ -26,7 +26,7 @@
 #ifndef SAGA_SCRIPT_H
 #define SAGA_SCRIPT_H
 
-#include "saga/text.h"
+#include "saga/font.h"
 #include "saga/list.h"
 
 namespace Saga {
@@ -390,6 +390,7 @@
 	uint16 _modulesLUTEntryLen;
 	ModuleData *_modules;
 	int _modulesCount;
+	TextListEntry *_placardTextEntry;
 
 protected:
 	friend class SagaEngine;
@@ -424,7 +425,6 @@
 	int _dbg_singlestep;
 	int _dbg_dostep;
 	ScriptThread *_dbg_thread;
-	TEXTLIST_ENTRY *_dbg_txtentry;
 
 public:
 	ScriptThread *createThread(uint16 scriptModuleNumber, uint16 scriptEntryPointNumber);

Index: sfuncs.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/sfuncs.cpp,v
retrieving revision 1.137
retrieving revision 1.138
diff -u -d -r1.137 -r1.138
--- sfuncs.cpp	9 Jul 2005 16:23:45 -0000	1.137
+++ sfuncs.cpp	14 Jul 2005 17:46:21 -0000	1.138
@@ -1186,7 +1186,6 @@
 	thread->wait(kWaitTypeSpeech);
 }
 
-static TEXTLIST_ENTRY *placardTextEntry;
 
 // Script function #48 (0x30)
 // Param1: string rid
@@ -1253,22 +1252,22 @@
 	// It doesn't end up in exactly the same spot as the original did it,
 	// but it's close enough for now at least.
 
-	TEXTLIST_ENTRY text_entry;
+	TextListEntry textEntry;
 
-	text_entry.color = kITEColorBrightWhite;
-	text_entry.effect_color = kITEColorBlack;
-	text_entry.text_x = _vm->getDisplayWidth() / 2;
-	text_entry.text_y = (_vm->getSceneHeight() - _vm->_font->getHeight(MEDIUM_FONT_ID)) / 2;
-	text_entry.font_id = MEDIUM_FONT_ID;
-	text_entry.flags = FONT_OUTLINE | FONT_CENTERED;
-	text_entry.string = thread->_strings->getString(stringId);
+	textEntry.color = kITEColorBrightWhite;
+	textEntry.effectColor = kITEColorBlack;
+	textEntry.point.x = _vm->getDisplayWidth() / 2;
+	textEntry.point.y = (_vm->getSceneHeight() - _vm->_font->getHeight(kMediumFont)) / 2;
+	textEntry.fontId = kMediumFont;
+	textEntry.flags = (FontEffectFlags)(kFontOutline | kFontCentered);
+	textEntry.text = thread->_strings->getString(stringId);
 
-	placardTextEntry = _vm->textAddEntry(_vm->_scene->_textList, &text_entry);
+	_placardTextEntry = _vm->_scene->_textList.addEntry(textEntry);
 
 	event.type = ONESHOT_EVENT;
 	event.code = TEXT_EVENT;
 	event.op = EVENT_DISPLAY;
-	event.data = placardTextEntry;
+	event.data = _placardTextEntry;
 
 	q_event = _vm->_events->chain(q_event, &event);
 
@@ -1324,7 +1323,7 @@
 	event.type = ONESHOT_EVENT;
 	event.code = TEXT_EVENT;
 	event.op = EVENT_REMOVE;
-	event.data = placardTextEntry;
+	event.data = _placardTextEntry;
 
 	q_event = _vm->_events->chain(q_event, &event);
 
@@ -1520,13 +1519,26 @@
 void Script::sfScriptText(SCRIPTFUNC_PARAMS) {
 	int16 stringId;
 	int16 flags;
+	Rect rect;
+	int color;
 	Point point;
+	int width;
+	const char*text;
 	stringId = thread->pop();
 	flags = thread->pop();
+	color = thread->pop();
 	point.x = thread->pop();
 	point.y = thread->pop();
-//TODO: do it!!!
 
+	text = thread->_strings->getString(stringId);
+	width = _vm->_font->getStringWidth(kMediumFont, text, 0, kFontOutline);
+	rect.top = point.y - 6;
+	rect.setHeight(12);	
+	rect.left = point.x - width / 2;
+	rect.setWidth(width);
+
+	_vm->_actor->setSpeechColor(color, kITEColorBlack);
+	_vm->_actor->nonActorSpeech(rect, &text, 1, flags);
 }
 
 // Script function #60 (0x3C)

Index: sprite.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/sprite.cpp,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- sprite.cpp	9 Jul 2005 21:29:54 -0000	1.58
+++ sprite.cpp	14 Jul 2005 17:46:21 -0000	1.59
@@ -28,7 +28,6 @@
 #include "saga/scene.h"
 #include "saga/rscfile_mod.h"
 
-#include "saga/text.h"
 #include "saga/font.h"
 
 #include "saga/sprite.h"





More information about the Scummvm-git-logs mailing list