aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorFilippos Karapetis2011-10-08 17:16:58 +0300
committerFilippos Karapetis2011-10-08 17:19:00 +0300
commit4ad2ebd9959a8413c0d00cd7498ac4166edfe886 (patch)
treea663c3cae3cdecd205b38c950cb888a3b24e6db5 /engines/sci
parent2ffdd0d3b7d06d072c11db06cb4017d9948b205b (diff)
downloadscummvm-rg350-4ad2ebd9959a8413c0d00cd7498ac4166edfe886.tar.gz
scummvm-rg350-4ad2ebd9959a8413c0d00cd7498ac4166edfe886.tar.bz2
scummvm-rg350-4ad2ebd9959a8413c0d00cd7498ac4166edfe886.zip
SCI2+: Some groundwork for kTextSize()
The old behavior is currently hacked in inside kernelTextSize(), as the top of the subtitles frame is wrong if kTextWidth() is properly working...
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/kgraphics.cpp8
-rw-r--r--engines/sci/graphics/frameout.cpp10
-rw-r--r--engines/sci/graphics/text32.cpp94
-rw-r--r--engines/sci/graphics/text32.h7
4 files changed, 100 insertions, 19 deletions
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 2bf3f25930..83eb94195b 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -354,11 +354,9 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
textWidth = dest[3].toUint16(); textHeight = dest[2].toUint16();
#ifdef ENABLE_SCI32
- if (!g_sci->_gfxText16) {
- // TODO: Implement this
- textWidth = 0; textHeight = 0;
- warning("TODO: implement kTextSize for SCI32");
- } else
+ if (g_sci->_gfxText32)
+ g_sci->_gfxText32->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
+ else
#endif
g_sci->_gfxText16->kernelTextSize(g_sci->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index fcd22de7e1..e4d921a129 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -554,21 +554,13 @@ void GfxFrameout::kernelFrameout() {
TextEntry *textEntry = g_sci->_gfxText32->getTextEntry(itemEntry->object);
uint16 startX = ((textEntry->x * _screen->getWidth()) / scriptsRunningWidth) + it->planeRect.left;
uint16 startY = ((textEntry->y * _screen->getHeight()) / scriptsRunningHeight) + it->planeRect.top;
- // HACK. The plane sometimes doesn't contain the correct width. This
- // hack breaks the dialog options when speaking with Grace, but it's
- // the best we got up to now. This happens because of the unimplemented
- // kTextWidth function in SCI32.
- // TODO: Remove this once kTextWidth has been implemented.
- uint16 w = it->planeRect.width() >= 20 ? it->planeRect.width() : _screen->getWidth() - 10;
-
// Upscale the coordinates/width if the fonts are already upscaled
if (_screen->fontIsUpscaled()) {
startX = startX * _screen->getDisplayWidth() / _screen->getWidth();
startY = startY * _screen->getDisplayHeight() / _screen->getHeight();
- w = w * _screen->getDisplayWidth() / _screen->getWidth();
}
- g_sci->_gfxText32->drawTextBitmap(itemEntry->object, startX, startY, w);
+ g_sci->_gfxText32->drawTextBitmap(itemEntry->object, startX, startY, it->planeRect.width());
}
}
}
diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp
index 21372f1502..f13a56fa17 100644
--- a/engines/sci/graphics/text32.cpp
+++ b/engines/sci/graphics/text32.cpp
@@ -74,7 +74,7 @@ void GfxText32::createTextBitmap(reg_t textObject) {
}
// TODO: Finish this!
-void GfxText32::drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uint16 w) {
+void GfxText32::drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uint16 planeWidth) {
uint32 textId = (textObject.segment << 16) | textObject.offset;
if (!_textCache.contains(textId))
@@ -90,11 +90,19 @@ void GfxText32::drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uin
const char *txt = entry->text.c_str();
int16 charCount;
+ uint16 maxWidth = (planeWidth > 0) ? planeWidth : _screen->getWidth() - textX;
while (*txt) {
- charCount = GetLongest(txt, w, font);
- if (charCount == 0)
- break;
+ charCount = GetLongest(txt, maxWidth, font);
+ if (charCount == 0) {
+ // If the text does not fit inside the given plane, use the
+ // whole screen.
+ // TODO/FIXME: Is this really needed? Perhaps some other
+ // functionality is missing instead?
+ charCount = GetLongest(txt, _screen->getWidth() - textX, font);
+ if (charCount == 0)
+ break;
+ }
uint16 curX = textX;
@@ -235,4 +243,82 @@ int16 GfxText32::GetLongest(const char *text, int16 maxWidth, GfxFont *font) {
return maxChars;
}
+void GfxText32::kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight) {
+ Common::Rect rect(0, 0, 0, 0);
+ Size(rect, text, font, maxWidth);
+ *textWidth = rect.width();
+ *textHeight = rect.height();
+
+ // TODO: Setting textWidth properly changes the subtitle plane top to 0.
+ // I have no idea why, so we currently hack in the old behavior here.
+ *textWidth = 0;
+ *textHeight = 0;
+}
+
+void GfxText32::StringWidth(const char *str, GuiResourceId fontId, int16 &textWidth, int16 &textHeight) {
+ Width(str, 0, (int16)strlen(str), fontId, textWidth, textHeight, true);
+}
+
+void GfxText32::Width(const char *text, int16 from, int16 len, GuiResourceId fontId, int16 &textWidth, int16 &textHeight, bool restoreFont) {
+ uint16 curChar;
+ textWidth = 0; textHeight = 0;
+
+ GfxFont *font = _cache->getFont(fontId);
+
+ if (font) {
+ text += from;
+ while (len--) {
+ curChar = (*(const byte *)text++);
+ switch (curChar) {
+ case 0x0A:
+ case 0x0D:
+ case 0x9781: // this one is used by SQ4/japanese as line break as well
+ textHeight = MAX<int16> (textHeight, font->getHeight());
+ break;
+ case 0x7C:
+ warning("Code processing isn't implemented in SCI32");
+ break;
+ default:
+ textHeight = MAX<int16> (textHeight, font->getHeight());
+ textWidth += font->getCharWidth(curChar);
+ break;
+ }
+ }
+ }
+}
+
+int16 GfxText32::Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth) {
+ int16 charCount;
+ int16 maxTextWidth = 0, textWidth;
+ int16 totalHeight = 0, textHeight;
+
+ rect.top = rect.left = 0;
+ GfxFont *font = _cache->getFont(fontId);
+
+ if (maxWidth < 0) { // force output as single line
+ StringWidth(text, fontId, textWidth, textHeight);
+ rect.bottom = textHeight;
+ rect.right = textWidth;
+ } else {
+ // rect.right=found widest line with RTextWidth and GetLongest
+ // rect.bottom=num. lines * GetPointSize
+ rect.right = (maxWidth ? maxWidth : 192);
+ const char *curPos = text;
+ while (*curPos) {
+ charCount = GetLongest(curPos, rect.right, font);
+ if (charCount == 0)
+ break;
+ Width(curPos, 0, charCount, fontId, textWidth, textHeight, false);
+ maxTextWidth = MAX(textWidth, maxTextWidth);
+ totalHeight += textHeight;
+ curPos += charCount;
+ while (*curPos == ' ')
+ curPos++; // skip over breaking spaces
+ }
+ rect.bottom = totalHeight;
+ rect.right = maxWidth ? maxWidth : MIN(rect.right, maxTextWidth);
+ }
+ return rect.right;
+}
+
} // End of namespace Sci
diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h
index 39fe710a86..7f70afc880 100644
--- a/engines/sci/graphics/text32.h
+++ b/engines/sci/graphics/text32.h
@@ -52,12 +52,17 @@ public:
GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen);
~GfxText32();
void createTextBitmap(reg_t textObject);
- void drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uint16 w);
+ void drawTextBitmap(reg_t textObject, uint16 textX, uint16 textY, uint16 planeWidth);
int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font);
TextEntry *getTextEntry(reg_t textObject);
+ void kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight);
+
private:
TextEntry *createTextEntry(reg_t textObject);
+ int16 Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth);
+ void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont);
+ void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight);
void purgeCache();
SegManager *_segMan;