aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/graphics/cache.cpp10
-rw-r--r--engines/sci/graphics/font.cpp16
-rw-r--r--engines/sci/graphics/font.h29
-rw-r--r--engines/sci/graphics/fontsjis.cpp80
-rw-r--r--engines/sci/graphics/fontsjis.h62
-rw-r--r--engines/sci/graphics/frameout.cpp2
-rw-r--r--engines/sci/graphics/screen.cpp7
-rw-r--r--engines/sci/graphics/screen.h3
-rw-r--r--engines/sci/graphics/text16.cpp37
-rw-r--r--engines/sci/module.mk1
10 files changed, 213 insertions, 34 deletions
diff --git a/engines/sci/graphics/cache.cpp b/engines/sci/graphics/cache.cpp
index ef8538349f..81bdab80ea 100644
--- a/engines/sci/graphics/cache.cpp
+++ b/engines/sci/graphics/cache.cpp
@@ -32,6 +32,7 @@
#include "sci/engine/selector.h"
#include "sci/graphics/cache.h"
#include "sci/graphics/font.h"
+#include "sci/graphics/fontsjis.h"
#include "sci/graphics/view.h"
namespace Sci {
@@ -67,8 +68,13 @@ GfxFont *GfxCache::getFont(GuiResourceId fontId) {
if (_cachedFonts.size() >= MAX_CACHED_FONTS)
purgeFontCache();
- if (!_cachedFonts.contains(fontId))
- _cachedFonts[fontId] = new GfxFont(_resMan, _screen, fontId);
+ if (!_cachedFonts.contains(fontId)) {
+ // Create special SJIS font in japanese games, when font 900 is selected
+ if ((fontId == 900) && (g_sci->getLanguage() == Common::JA_JPN))
+ _cachedFonts[fontId] = new GfxFontSjis(_screen, fontId);
+ else
+ _cachedFonts[fontId] = new GfxFontFromResource(_resMan, _screen, fontId);
+ }
return _cachedFonts[fontId];
}
diff --git a/engines/sci/graphics/font.cpp b/engines/sci/graphics/font.cpp
index 4bfe8f87dd..91cf01c912 100644
--- a/engines/sci/graphics/font.cpp
+++ b/engines/sci/graphics/font.cpp
@@ -30,7 +30,7 @@
namespace Sci {
-GfxFont::GfxFont(ResourceManager *resMan, GfxScreen *screen, GuiResourceId resourceId)
+GfxFontFromResource::GfxFontFromResource(ResourceManager *resMan, GfxScreen *screen, GuiResourceId resourceId)
: _resourceId(resourceId), _screen(screen), _resMan(resMan) {
assert(resourceId != -1);
@@ -56,29 +56,29 @@ GfxFont::GfxFont(ResourceManager *resMan, GfxScreen *screen, GuiResourceId resou
}
}
-GfxFont::~GfxFont() {
+GfxFontFromResource::~GfxFontFromResource() {
delete []_chars;
_resMan->unlockResource(_resource);
}
-GuiResourceId GfxFont::getResourceId() {
+GuiResourceId GfxFontFromResource::getResourceId() {
return _resourceId;
}
-byte GfxFont::getHeight() {
+byte GfxFontFromResource::getHeight() {
return _fontHeight;
}
-byte GfxFont::getCharWidth(byte chr) {
+byte GfxFontFromResource::getCharWidth(uint16 chr) {
return chr < _numChars ? _chars[chr].w : 0;
}
-byte GfxFont::getCharHeight(byte chr) {
+byte GfxFontFromResource::getCharHeight(uint16 chr) {
return chr < _numChars ? _chars[chr].h : 0;
}
-byte *GfxFont::getCharData(byte chr) {
+byte *GfxFontFromResource::getCharData(uint16 chr) {
return chr < _numChars ? _resourceData + _chars[chr].offset + 2 : 0;
}
-void GfxFont::draw(int16 chr, int16 top, int16 left, byte color, bool greyedOutput) {
+void GfxFontFromResource::draw(uint16 chr, int16 top, int16 left, byte color, bool greyedOutput) {
int charWidth = MIN<int>(getCharWidth(chr), _screen->getWidth() - left);
int charHeight = MIN<int>(getCharHeight(chr), _screen->getHeight() - top);
byte b = 0, mask = 0xFF;
diff --git a/engines/sci/graphics/font.h b/engines/sci/graphics/font.h
index 975b7e712a..c405f5a0a0 100644
--- a/engines/sci/graphics/font.h
+++ b/engines/sci/graphics/font.h
@@ -30,23 +30,38 @@
namespace Sci {
+class GfxFont {
+public:
+ GfxFont() {};
+ virtual ~GfxFont() {};
+
+ virtual GuiResourceId getResourceId() { return 0; };
+ virtual byte getHeight() { return 0; };
+ virtual bool isDoubleByte(uint16 chr) { return false; };
+ virtual byte getCharWidth(uint16 chr) { return 0; };
+ virtual byte getCharHeight(uint16 chr) { return 0; };
+ virtual void draw(uint16 chr, int16 top, int16 left, byte color, bool greyedOutput) {};
+};
+
+
/**
* Font class, handles loading of font resources and drawing characters to screen
* every font resource has its own instance of this class
*/
-class GfxFont {
+class GfxFontFromResource : public GfxFont {
public:
- GfxFont(ResourceManager *resMan, GfxScreen *screen, GuiResourceId resourceId);
- ~GfxFont();
+ GfxFontFromResource(ResourceManager *resMan, GfxScreen *screen, GuiResourceId resourceId);
+ ~GfxFontFromResource();
GuiResourceId getResourceId();
byte getHeight();
- byte getCharWidth(byte chr);
- byte getCharHeight(byte chr);
- byte *getCharData(byte chr);
- void draw(int16 chr, int16 top, int16 left, byte color, bool greyedOutput);
+ byte getCharWidth(uint16 chr);
+ byte getCharHeight(uint16 chr);
+ void draw(uint16 chr, int16 top, int16 left, byte color, bool greyedOutput);
private:
+ byte *getCharData(uint16 chr);
+
ResourceManager *_resMan;
GfxScreen *_screen;
diff --git a/engines/sci/graphics/fontsjis.cpp b/engines/sci/graphics/fontsjis.cpp
new file mode 100644
index 0000000000..3e2d5217f7
--- /dev/null
+++ b/engines/sci/graphics/fontsjis.cpp
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "sci/sci.h"
+#include "sci/engine/state.h"
+#include "sci/graphics/screen.h"
+#include "sci/graphics/font.h"
+#include "sci/graphics/fontsjis.h"
+
+namespace Sci {
+
+GfxFontSjis::GfxFontSjis(GfxScreen *screen, GuiResourceId resourceId)
+ : _resourceId(resourceId), _screen(screen) {
+ assert(resourceId != -1);
+
+ if (!_screen->getUpscaledHires())
+ error("I don't want to initialize, when not being in upscaled hires mode");
+
+ _commonFont = Graphics::FontSJIS::createFont(Common::kPlatformPC98);
+
+ if (!_commonFont)
+ error("Could not load ScummVM's 'SJIS.FNT'");
+}
+
+GfxFontSjis::~GfxFontSjis() {
+}
+
+GuiResourceId GfxFontSjis::getResourceId() {
+ return _resourceId;
+}
+
+// Returns true for first byte of double byte characters
+bool GfxFontSjis::isDoubleByte(uint16 chr) {
+ if ((chr == 0x5C) || (chr == 0x7E) || ((chr >= 0x81) && (chr <= 0x9F)) || ((chr >= 0xE0) && (chr <= 0xEF)))
+ return true;
+ return false;
+}
+
+// We can do >>1, because returned char width/height is 8 or 16 exclusively. Font returns hires size, we need lowres
+byte GfxFontSjis::getHeight() {
+ return _commonFont->getFontHeight() >> 1;
+}
+
+byte GfxFontSjis::getCharWidth(uint16 chr) {
+ return _commonFont->getCharWidth(chr) >> 1;
+
+}
+byte GfxFontSjis::getCharHeight(uint16 chr) {
+ return _commonFont->getFontHeight() >> 1;
+}
+
+void GfxFontSjis::draw(uint16 chr, int16 top, int16 left, byte color, bool greyedOutput) {
+ // TODO: Check, if character fits on screen - if it doesn't we need to skip it
+ // Normally SCI cuts the character and draws the part that fits, but the common SJIS doesn't support that
+ _screen->putKanjiChar(_commonFont, left, top, chr, color);
+}
+
+} // End of namespace Sci
diff --git a/engines/sci/graphics/fontsjis.h b/engines/sci/graphics/fontsjis.h
new file mode 100644
index 0000000000..4330342331
--- /dev/null
+++ b/engines/sci/graphics/fontsjis.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef SCI_GRAPHICS_FONTSJIS_H
+#define SCI_GRAPHICS_FONTSJIS_H
+
+#include "graphics/sjis.h"
+
+#include "sci/graphics/helpers.h"
+
+namespace Sci {
+
+/**
+ * Special Font class, handles SJIS inside sci games, uses ScummVM SJIS support
+ */
+class GfxFontSjis : public GfxFont {
+public:
+ GfxFontSjis(GfxScreen *screen, GuiResourceId resourceId);
+ ~GfxFontSjis();
+
+ GuiResourceId getResourceId();
+ byte getHeight();
+ bool isDoubleByte(uint16 chr);
+ byte getCharWidth(uint16 chr);
+ byte getCharHeight(uint16 chr);
+ void draw(uint16 chr, int16 top, int16 left, byte color, bool greyedOutput);
+
+private:
+ GfxScreen *_screen;
+ GuiResourceId _resourceId;
+
+ Graphics::FontSJIS *_commonFont;
+
+ byte _lastForDoubleByteWidth;
+ byte _lastForDoubleByteDraw;
+};
+
+} // End of namespace Sci
+
+#endif
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index 79cbc6c669..e401798233 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -243,7 +243,7 @@ void GfxFrameout::kernelFrameout() {
if (lookup_selector(_segMan, itemEntry->object, kernel->_selectorCache.text, NULL, NULL) == kSelectorVariable) {
Common::String text = _segMan->getString(GET_SEL32(_segMan, itemEntry->object, SELECTOR(text)));
int16 fontRes = GET_SEL32V(_segMan, itemEntry->object, SELECTOR(font));
- GfxFont *font = new GfxFont(_resMan, _screen, fontRes);
+ GfxFont *font = new GfxFontFromResource(_resMan, _screen, fontRes);
bool dimmed = GET_SEL32V(_segMan, itemEntry->object, SELECTOR(dimmed));
uint16 foreColor = GET_SEL32V(_segMan, itemEntry->object, SELECTOR(fore));
uint16 curX = itemEntry->x;
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 4d39ca45e3..21f9b0afdd 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -234,6 +234,13 @@ void GfxScreen::drawLine(Common::Point startPoint, Common::Point endPoint, byte
}
}
+// We put hires kanji chars onto upscaled background, so we need to adjust coordinates. Caller gives use low-res ones
+void GfxScreen::putKanjiChar(Graphics::FontSJIS *commonFont, int16 x, int16 y, uint16 chr, byte color) {
+ byte *displayPtr = _displayScreen + y * _displayWidth * 2 + x * 2;
+ // we don't use outline, so color 0 is actually not used
+ commonFont->drawChar(displayPtr, chr, _displayWidth, 1, color, 0);
+}
+
byte GfxScreen::getVisual(int x, int y) {
return _visualScreen[y * _width + x];
}
diff --git a/engines/sci/graphics/screen.h b/engines/sci/graphics/screen.h
index 6d8b6f7c9a..3316b53c69 100644
--- a/engines/sci/graphics/screen.h
+++ b/engines/sci/graphics/screen.h
@@ -29,6 +29,8 @@
#include "sci/sci.h"
#include "sci/graphics/helpers.h"
+#include "graphics/sjis.h"
+
namespace Sci {
#define SCI_SCREEN_MAXHEIGHT 400
@@ -75,6 +77,7 @@ public:
bool getUpscaledHires() {
return _upscaledHires;
}
+ void putKanjiChar(Graphics::FontSJIS *commonFont, int16 x, int16 y, uint16 chr, byte color);
byte getVisual(int x, int y);
byte getPriority(int x, int y);
byte getControl(int x, int y);
diff --git a/engines/sci/graphics/text16.cpp b/engines/sci/graphics/text16.cpp
index 9f39725692..efbfbde666 100644
--- a/engines/sci/graphics/text16.cpp
+++ b/engines/sci/graphics/text16.cpp
@@ -153,7 +153,7 @@ int16 GfxText16::CodeProcessing(const char *&text, GuiResourceId orgFontId, int1
// return max # of chars to fit maxwidth with full words
int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgFontId) {
- char curChar;
+ uint16 curChar;
int16 maxChars = 0, curCharCount = 0;
uint16 width = 0;
GuiResourceId oldFontId = GetFontId();
@@ -164,7 +164,11 @@ int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgF
return 0;
while (width <= maxWidth) {
- curChar = *text++;
+ curChar = (*(unsigned char *)text++);
+ if (_font->isDoubleByte(curChar)) {
+ curChar |= (*(unsigned char *)text++) << 8;
+ curCharCount++;
+ }
switch (curChar) {
case 0x7C:
if (getSciVersion() >= SCI_VERSION_1_1) {
@@ -193,8 +197,9 @@ int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgF
curCharCount++;
}
if (maxChars == 0) {
- // Is Kanji
- maxChars = curCharCount - 1;
+ // Text w/o space, supposingly kanji - we don't adjust back to last char here strangely. If we do, we don't
+ // get the same text cutting like in sierra sci
+ maxChars = curCharCount;
}
SetFont(oldFontId);
_ports->penColor(oldPenColor);
@@ -202,7 +207,7 @@ int16 GfxText16::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgF
}
void GfxText16::Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight) {
- unsigned char curChar;
+ uint16 curChar;
GuiResourceId oldFontId = GetFontId();
int16 oldPenColor = _ports->_curPort->penClr;
@@ -212,7 +217,11 @@ void GfxText16::Width(const char *text, int16 from, int16 len, GuiResourceId org
if (_font) {
text += from;
while (len--) {
- curChar = *text++;
+ curChar = (*(unsigned char *)text++);
+ if (_font->isDoubleByte(curChar)) {
+ curChar |= (*(unsigned char *)text++) << 8;
+ len--;
+ }
switch (curChar) {
case 0x0A:
case 0x0D:
@@ -266,10 +275,6 @@ int16 GfxText16::Size(Common::Rect &rect, const char *str, GuiResourceId fontId,
rect.right = (maxWidth ? maxWidth : 192);
const char*p = str;
while (*p) {
- //if (*p == 0xD || *p == 0xA) {
- // p++;
- // continue;
- //}
charCount = GetLongest(p, rect.right, oldFontId);
if (charCount == 0)
break;
@@ -288,7 +293,7 @@ int16 GfxText16::Size(Common::Rect &rect, const char *str, GuiResourceId fontId,
// returns maximum font height used
void GfxText16::Draw(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor) {
- int16 curChar, charWidth;
+ uint16 curChar, charWidth;
Common::Rect rect;
GetFont();
@@ -299,7 +304,11 @@ void GfxText16::Draw(const char *text, int16 from, int16 len, GuiResourceId orgF
rect.bottom = rect.top + _ports->_curPort->fontHeight;
text += from;
while (len--) {
- curChar = (*text++);
+ curChar = (*(unsigned char *)text++);
+ if (_font->isDoubleByte(curChar)) {
+ curChar |= (*(unsigned char *)text++) << 8;
+ len--;
+ }
switch (curChar) {
case 0x0A:
case 0x0D:
@@ -349,10 +358,6 @@ void GfxText16::Box(const char *text, int16 bshow, const Common::Rect &rect, Tex
SetFont(fontId);
while (*text) {
-// if (*text == 0xD || *text == 0xA) {
-// text++;
-// continue;
-// }
charCount = GetLongest(text, rect.width(), orgFontId);
if (charCount == 0)
break;
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 0a110f2aa1..852f97b225 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -41,6 +41,7 @@ MODULE_OBJS := \
graphics/coordadjuster.o \
graphics/cursor.o \
graphics/font.o \
+ graphics/fontsjis.o \
graphics/gui.o \
graphics/menu.o \
graphics/paint.o \