mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-03 17:33:05 +00:00
d6347269eb
Rose Tattoo did different font char mapping for at least the German version of the game (can't verify anything else). RT seems to map 0xE1 only, but to a different character and other upper characters (>= 0x80) are not mapped at all. this fixes broken special characters in RT.
212 lines
5.2 KiB
C++
212 lines
5.2 KiB
C++
/* 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.
|
|
*
|
|
*/
|
|
|
|
#include "common/system.h"
|
|
#include "common/platform.h"
|
|
#include "sherlock/fonts.h"
|
|
#include "sherlock/image_file.h"
|
|
#include "sherlock/surface.h"
|
|
#include "sherlock/sherlock.h"
|
|
|
|
namespace Sherlock {
|
|
|
|
SherlockEngine *Fonts::_vm;
|
|
ImageFile *Fonts::_font;
|
|
int Fonts::_fontNumber;
|
|
int Fonts::_fontHeight;
|
|
int Fonts::_widestChar;
|
|
uint16 Fonts::_charCount;
|
|
byte Fonts::_yOffsets[255];
|
|
|
|
void Fonts::setVm(SherlockEngine *vm) {
|
|
_vm = vm;
|
|
_font = nullptr;
|
|
_charCount = 0;
|
|
}
|
|
|
|
void Fonts::free() {
|
|
delete _font;
|
|
}
|
|
|
|
void Fonts::setFont(int fontNum) {
|
|
_fontNumber = fontNum;
|
|
|
|
// Discard previous font
|
|
delete _font;
|
|
|
|
Common::String fontFilename;
|
|
|
|
if (_vm->getPlatform() != Common::kPlatform3DO) {
|
|
// PC
|
|
// use FONT[number].VGS, which is a regular sherlock graphic file
|
|
fontFilename = Common::String::format("FONT%d.VGS", fontNum + 1);
|
|
|
|
// load font data
|
|
_font = new ImageFile(fontFilename);
|
|
} else {
|
|
// 3DO
|
|
switch (fontNum) {
|
|
case 0:
|
|
case 1:
|
|
fontFilename = "helvetica14.font";
|
|
break;
|
|
case 2:
|
|
fontFilename = "darts.font";
|
|
break;
|
|
default:
|
|
error("setFont(): unsupported 3DO font number");
|
|
}
|
|
|
|
// load font data
|
|
_font = new ImageFile3DO(fontFilename, kImageFile3DOType_Font);
|
|
}
|
|
|
|
_charCount = _font->size();
|
|
|
|
// Iterate through the frames to find the widest and tallest font characters
|
|
_fontHeight = _widestChar = 0;
|
|
for (uint idx = 0; idx < _charCount; ++idx) {
|
|
_fontHeight = MAX((uint16)_fontHeight, (*_font)[idx]._frame.h);
|
|
_widestChar = MAX((uint16)_widestChar, (*_font)[idx]._frame.w);
|
|
}
|
|
|
|
// Initialize the Y offset table for the extended character set
|
|
for (int idx = 0; idx < 255; ++idx) {
|
|
_yOffsets[idx] = 0;
|
|
|
|
if (IS_ROSE_TATTOO) {
|
|
if ((idx >= 129 && idx < 135) || (idx >= 136 && idx < 143) || (idx >= 147 && idx < 155) ||
|
|
(idx >= 156 && idx < 165))
|
|
_yOffsets[idx] = 1;
|
|
else if ((idx >= 143 && idx < 146) || idx == 165)
|
|
_yOffsets[idx] = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline byte Fonts::translateChar(byte c) {
|
|
switch (c) {
|
|
case ' ':
|
|
return 0; // translate to first actual character
|
|
case 225:
|
|
// This was done in the German interpreter
|
|
// SH1: happens, when talking to the kid in the 2nd room
|
|
// SH2: happens, when looking at the newspaper right at the start in the backalley
|
|
// Special handling for 0xE1 (German Sharp-S character)
|
|
if (IS_ROSE_TATTOO) {
|
|
return 136; // it got translated to this for SH2
|
|
}
|
|
return 135; // and this for SH1
|
|
default:
|
|
if (IS_SERRATED_SCALPEL) {
|
|
if (c >= 0x80) { // German SH1 version did this, but not German SH2
|
|
c--;
|
|
}
|
|
// Spanish SH1 did this (reverse engineered code)
|
|
//if ((c >= 0xA0) && (c <= 0xAD) || (c == 0x82)) {
|
|
// c--;
|
|
//}
|
|
}
|
|
assert(c > 32); // anything above space is allowed
|
|
return c - 33;
|
|
}
|
|
}
|
|
|
|
void Fonts::writeString(Surface *surface, const Common::String &str,
|
|
const Common::Point &pt, int overrideColor) {
|
|
Common::Point charPos = pt;
|
|
|
|
if (!_font)
|
|
return;
|
|
|
|
for (const char *curCharPtr = str.c_str(); *curCharPtr; ++curCharPtr) {
|
|
byte curChar = *curCharPtr;
|
|
|
|
if (curChar == ' ') {
|
|
charPos.x += 5; // hardcoded space
|
|
continue;
|
|
}
|
|
curChar = translateChar(curChar);
|
|
|
|
assert(curChar < _charCount);
|
|
ImageFrame &frame = (*_font)[curChar];
|
|
surface->transBlitFrom(frame, Common::Point(charPos.x, charPos.y + _yOffsets[curChar]), false, overrideColor);
|
|
charPos.x += frame._frame.w + 1;
|
|
}
|
|
}
|
|
|
|
int Fonts::stringWidth(const Common::String &str) {
|
|
int width = 0;
|
|
|
|
if (!_font)
|
|
return 0;
|
|
|
|
for (const char *c = str.c_str(); *c; ++c)
|
|
width += charWidth(*c);
|
|
|
|
return width;
|
|
}
|
|
|
|
int Fonts::stringHeight(const Common::String &str) {
|
|
int height = 0;
|
|
|
|
if (!_font)
|
|
return 0;
|
|
|
|
for (const char *c = str.c_str(); *c; ++c)
|
|
height = MAX(height, charHeight(*c));
|
|
|
|
return height;
|
|
}
|
|
|
|
int Fonts::charWidth(unsigned char c) {
|
|
byte curChar;
|
|
|
|
if (!_font)
|
|
return 0;
|
|
|
|
if (c == ' ') {
|
|
return 5; // hardcoded space
|
|
}
|
|
curChar = translateChar(c);
|
|
|
|
if (curChar < _charCount)
|
|
return (*_font)[curChar]._frame.w + 1;
|
|
return 0;
|
|
}
|
|
|
|
int Fonts::charHeight(unsigned char c) {
|
|
byte curChar;
|
|
|
|
if (!_font)
|
|
return 0;
|
|
|
|
// Space is supposed to be handled like the first actual character (which is decimal 33)
|
|
curChar = translateChar(c);
|
|
|
|
assert(curChar < _charCount);
|
|
const ImageFrame &img = (*_font)[curChar];
|
|
return img._height + img._offset.y + 1;
|
|
}
|
|
|
|
} // End of namespace Sherlock
|