aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--saga/actor.cpp101
-rw-r--r--saga/actor.h13
-rw-r--r--saga/events.cpp7
-rw-r--r--saga/font.cpp662
-rw-r--r--saga/font.h111
-rw-r--r--saga/image.cpp2
-rw-r--r--saga/interface.cpp77
-rw-r--r--saga/ite_introproc.cpp59
-rw-r--r--saga/module.mk1
-rw-r--r--saga/objectmap.cpp7
-rw-r--r--saga/puzzle.cpp16
-rw-r--r--saga/puzzle.h1
-rw-r--r--saga/render.cpp43
-rw-r--r--saga/render.h1
-rw-r--r--saga/saga.h29
-rw-r--r--saga/scene.cpp25
-rw-r--r--saga/scene.h5
-rw-r--r--saga/script.h4
-rw-r--r--saga/sfuncs.cpp38
-rw-r--r--saga/sprite.cpp1
20 files changed, 721 insertions, 482 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp
index d8394c505d..e4c48c266a 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -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 @@ void Actor::handleSpeech(int msec) {
int i;
int talkspeed;
ActorData *actor;
+ int width, height, height2;
+ Point posPoint;
if (_activeSpeech.playing) {
_activeSpeech.playingTime -= msec;
@@ -817,13 +818,39 @@ void Actor::handleSpeech(int msec) {
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::drawActors() {
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 @@ void Actor::drawSpeech(void) {
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 @@ bool Actor::actorWalkTo(uint16 actorId, const Location &toLocation) {
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 @@ void Actor::actorSpeech(uint16 actorId, const char **strings, int stringsCount,
}
actor = getActor(actorId);
+ calcScreenPosition(actor);
for (i = 0; i < stringsCount; i++) {
_activeSpeech.strings[i] = strings[i];
}
@@ -1840,9 +1869,24 @@ void Actor::actorSpeech(uint16 actorId, const char **strings, int stringsCount,
_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 @@ void Actor::nonActorSpeech(const char **strings, int stringsCount, int speechFla
_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) {
diff --git a/saga/actor.h b/saga/actor.h
index 0f2b4255db..271d7a39dc 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -470,7 +470,8 @@ struct SpeechData {
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 @@ struct SpeechData {
SpeechData() {
memset(this, 0, sizeof(*this));
}
+
+ FontEffectFlags getFontFlags(int i) {
+ if (outlineColor[i] != 0) {
+ return kFontOutline;
+ } else {
+ return kFontNormal;
+ }
+ }
};
@@ -545,7 +554,7 @@ public:
// 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;
diff --git a/saga/events.cpp b/saga/events.cpp
index 5bc603751d..0b7ea0c4ca 100644
--- a/saga/events.cpp
+++ b/saga/events.cpp
@@ -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 @@ int Events::handleOneShot(EVENT *event) {
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;
diff --git a/saga/font.cpp b/saga/font.cpp
index c18f9f338f..4af061eb6d 100644
--- a/saga/font.cpp
+++ b/saga/font.cpp
@@ -36,19 +36,11 @@ Font::Font(SagaEngine *vm) : _vm(vm), _initialized(false) {
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(SagaEngine *vm) : _vm(vm), _initialized(false) {
}
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();
+ font->normal.header.charHeight = readS.readUint16();
+ font->normal.header.charWidth = readS.readUint16();
+ font->normal.header.rowLength = 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);
-
- // 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;
+ const byte *txt;
- if (!_initialized) {
- return FAILURE;
- }
+ validate(fontId);
- if ((font_id < 0) || (font_id >= _nFonts) || (_fonts[font_id] == NULL)) {
- error("Font::getStringWidth(): Invalid font id.");
- }
-
- 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 @@ int Font::outFont(FONT_STYLE * draw_font, Surface *ds, const char *draw_str, siz
// 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
+}
+
+
+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;
+ }
+ }
+}
- return SUCCESS;
+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
diff --git a/saga/font.h b/saga/font.h
index 5e1043aae4..5b5963b9b4 100644
--- a/saga/font.h
+++ b/saga/font.h
@@ -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 @@ namespace Saga {
#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
diff --git a/saga/image.cpp b/saga/image.cpp
index 379eae2cfc..2ca190c266 100644
--- a/saga/image.cpp
+++ b/saga/image.cpp
@@ -48,7 +48,7 @@ static int granulate(int value, int granularity) {
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;
diff --git a/saga/interface.cpp b/saga/interface.cpp
index 286e8460eb..cd3570ca58 100644
--- a/saga/interface.cpp
+++ b/saga/interface.cpp
@@ -644,16 +644,20 @@ void Interface::drawPanelText(Surface *ds, InterfacePanel *panel, PanelButton *p
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 @@ void Interface::drawOption() {
Rect rect;
Rect rect2;
PanelButton *panelButton;
+ Point textPoint;
backBuffer = _vm->_gfx->getBackBuffer();
@@ -696,7 +701,7 @@ void Interface::drawOption() {
_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 @@ void Interface::drawOption() {
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 @@ bool Interface::processTextInput(uint16 ascii) {
(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 @@ bool Interface::processTextInput(uint16 ascii) {
}
void Interface::drawTextInput(Surface *ds, InterfacePanel *panel, PanelButton *panelButton) {
+ Point textPoint;
Rect rect;
char ch[2];
int fgColor;
@@ -955,24 +962,26 @@ void Interface::drawTextInput(Surface *ds, InterfacePanel *panel, PanelButton *p
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 @@ void Interface::handleOptionClick(const Point& mousePoint) {
} 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::update(const Point& mousePoint, int updateFlag) {
void Interface::drawStatusBar() {
Surface *backBuffer;
Rect rect;
-
- int string_w;
+ Point textPoint;
+ int stringWidth;
int color;
backBuffer = _vm->_gfx->getBackBuffer();
@@ -1337,15 +1346,16 @@ void Interface::drawStatusBar() {
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 @@ void Interface::drawPanelButtonText(Surface *ds, InterfacePanel *panel, PanelBut
}
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 @@ void Interface::drawPanelButtonText(Surface *ds, InterfacePanel *panel, PanelBut
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 @@ void Interface::drawVerbPanelText(Surface *ds, PanelButton *panelButton, int tex
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 @@ bool Interface::converseAddText(const char *text, int replyId, byte replyFlags,
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 @@ void Interface::converseDisplayTextLines(Surface *ds) {
(char)0xb7, 0
};
Rect rect(8, CONVERSE_TEXT_LINES * CONVERSE_TEXT_HEIGHT);
+ Point textPoint;
assert(_conversePanel.buttonsCount >= 6);
@@ -1910,11 +1920,14 @@ void Interface::converseDisplayTextLines(Surface *ds) {
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) {
diff --git a/saga/ite_introproc.cpp b/saga/ite_introproc.cpp
index 7f3b0cd3ba..5da6b42cbe 100644
--- a/saga/ite_introproc.cpp
+++ b/saga/ite_introproc.cpp
@@ -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 @@ int Scene::ITEStartProc() {
}
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 *Scene::ITEQueueDialogue(EVENT *q_event, int n_dialogues, const INTRO_DIAL
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 @@ EVENT *Scene::ITEQueueCredits(int delta_time, int duration, int n_credits, const
int line_spacing = 0;
int paragraph_spacing;
- int font = 0;
+ FontId font = kSmallFont;
int i;
int n_paragraphs = 0;
@@ -199,12 +198,12 @@ EVENT *Scene::ITEQueueCredits(int delta_time, int duration, int n_credits, const
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 @@ EVENT *Scene::ITEQueueCredits(int delta_time, int duration, int n_credits, const
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 @@ EVENT *Scene::ITEQueueCredits(int delta_time, int duration, int n_credits, const
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 *Scene::ITEQueueCredits(int delta_time, int duration, int n_credits, const
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);
diff --git a/saga/module.mk b/saga/module.mk
index 3e28da3163..0f648fea48 100644
--- a/saga/module.mk
+++ b/saga/module.mk
@@ -28,7 +28,6 @@ MODULE_OBJS := \
saga/sndres.o \
saga/sprite.o \
saga/sthread.o \
- saga/text.o \
saga/input.o \
saga/music.o \
saga/sound.o
diff --git a/saga/objectmap.cpp b/saga/objectmap.cpp
index 2122bf72f3..32798e16b9 100644
--- a/saga/objectmap.cpp
+++ b/saga/objectmap.cpp
@@ -219,6 +219,7 @@ void ObjectMap::draw(Surface *ds, const Point& testPoint, int color, int color2)
int hitZoneIndex;
char txtBuf[32];
Point pickPoint;
+ Point textPoint;
Location pickLocation;
pickPoint = testPoint;
if (_vm->_scene->getFlags() & kSceneFlagISO) {
@@ -236,9 +237,9 @@ void ObjectMap::draw(Surface *ds, const Point& testPoint, int color, int color2)
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);
}
}
diff --git a/saga/puzzle.cpp b/saga/puzzle.cpp
index 3d932907e4..44cfde0a6c 100644
--- a/saga/puzzle.cpp
+++ b/saga/puzzle.cpp
@@ -165,6 +165,10 @@ Puzzle::Puzzle(SagaEngine *vm) : _vm(vm), _solved(false), _active(false) {
_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 @@ void Puzzle::solicitHint(void) {
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 @@ void Puzzle::solicitHint(void) {
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 @@ void Puzzle::solicitHint(void) {
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 @@ void Puzzle::giveHint(void) {
_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 @@ void Puzzle::giveHint(void) {
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++;
diff --git a/saga/puzzle.h b/saga/puzzle.h
index 0b61c00bc3..6210c5c389 100644
--- a/saga/puzzle.h
+++ b/saga/puzzle.h
@@ -102,6 +102,7 @@ private:
PieceInfo _pieceInfo[PUZZLE_PIECES];
int _slidePointX, _slidePointY;
+ Rect _hintBox;
};
} // End of namespace Saga
diff --git a/saga/render.cpp b/saga/render.cpp
index 8083ed2431..bd73296ff8 100644
--- a/saga/render.cpp
+++ b/saga/render.cpp
@@ -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 @@ bool Render::initialized() {
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 @@ void Render::drawScene() {
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 @@ void Render::drawScene() {
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 @@ void Render::drawScene() {
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 @@ void Render::drawScene() {
}
// 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
diff --git a/saga/render.h b/saga/render.h
index dee9d3579a..99d8d7b5a9 100644
--- a/saga/render.h
+++ b/saga/render.h
@@ -30,7 +30,6 @@
namespace Saga {
-#define PAUSEGAME_MSG "PAWS GAME"
enum RENDER_FLAGS {
RF_SHOW_FPS = (1 << 0),
RF_PALETTE_TEST = (1 << 1),
diff --git a/saga/saga.h b/saga/saga.h
index c845fe893e..1719e40409 100644
--- a/saga/saga.h
+++ b/saga/saga.h
@@ -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 @@ enum TextStringIds {
kTextEnterSaveGameName
};
-struct IMAGE_HEADER {
+struct ImageHeader {
int width;
int height;
};
@@ -311,6 +310,21 @@ enum GameFeatures {
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 @@ public:
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;
diff --git a/saga/scene.cpp b/saga/scene.cpp
index 753a758dbf..5f738b20e7 100644
--- a/saga/scene.cpp
+++ b/saga/scene.cpp
@@ -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 @@ Scene::Scene(SagaEngine *vm) : _vm(vm), _initialized(false) {
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 @@ Scene::~Scene() {
}
}
+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 @@ void Scene::endScene() {
_vm->_isoMap->freeMem();
_vm->_events->clearList();
- _vm->textClearList(_textList);
+ _textList.clear();
_sceneLoaded = false;
diff --git a/saga/scene.h b/saga/scene.h
index 2233b05874..ed621b649f 100644
--- a/saga/scene.h
+++ b/saga/scene.h
@@ -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 @@ class Scene {
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 @@ class Scene {
ObjectMap *_objectMap;
SceneEntryList _entryList;
StringsTable _sceneStrings;
- TEXTLIST *_textList;
+ TextList _textList;
private:
int IHNMStartProc();
diff --git a/saga/script.h b/saga/script.h
index 80cfc78ab5..d40b59cf21 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -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 @@ private:
uint16 _modulesLUTEntryLen;
ModuleData *_modules;
int _modulesCount;
+ TextListEntry *_placardTextEntry;
protected:
friend class SagaEngine;
@@ -424,7 +425,6 @@ public:
int _dbg_singlestep;
int _dbg_dostep;
ScriptThread *_dbg_thread;
- TEXTLIST_ENTRY *_dbg_txtentry;
public:
ScriptThread *createThread(uint16 scriptModuleNumber, uint16 scriptEntryPointNumber);
diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp
index 626791c60a..5ec1fa45dd 100644
--- a/saga/sfuncs.cpp
+++ b/saga/sfuncs.cpp
@@ -1186,7 +1186,6 @@ void Script::sfSimulSpeech2(SCRIPTFUNC_PARAMS) {
thread->wait(kWaitTypeSpeech);
}
-static TEXTLIST_ENTRY *placardTextEntry;
// Script function #48 (0x30)
// Param1: string rid
@@ -1253,22 +1252,22 @@ void Script::sfPlacard(SCRIPTFUNC_PARAMS) {
// 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 @@ void Script::sfPlacardOff(SCRIPTFUNC_PARAMS) {
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::sfSetActorZ(SCRIPTFUNC_PARAMS) {
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)
diff --git a/saga/sprite.cpp b/saga/sprite.cpp
index 2c469a3066..58ed711493 100644
--- a/saga/sprite.cpp
+++ b/saga/sprite.cpp
@@ -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"