[Scummvm-git-logs] scummvm master -> 7ebf5e4f6d24583008ad6f384928f1d22a871c17
AndywinXp
noreply at scummvm.org
Sat Dec 2 10:38:46 UTC 2023
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
7ebf5e4f6d SWORD1: Fix support for Korean translation
Commit: 7ebf5e4f6d24583008ad6f384928f1d22a871c17
https://github.com/scummvm/scummvm/commit/7ebf5e4f6d24583008ad6f384928f1d22a871c17
Author: AndywinXp (andywinxp at gmail.com)
Date: 2023-12-02T11:38:40+01:00
Commit Message:
SWORD1: Fix support for Korean translation
>From british-choi ScummVM fork
Changed paths:
engines/sword1/detection_tables.h
engines/sword1/resman.cpp
engines/sword1/resman.h
engines/sword1/sword1.cpp
engines/sword1/text.cpp
engines/sword1/text.h
diff --git a/engines/sword1/detection_tables.h b/engines/sword1/detection_tables.h
index fcaf1a2d024..f4db4531a17 100644
--- a/engines/sword1/detection_tables.h
+++ b/engines/sword1/detection_tables.h
@@ -502,6 +502,21 @@ static const ADGameDescription gameDescriptions[] = {
GUIO0()
},
+ { // Korean fan translation
+ "sword1",
+ "",
+ AD_ENTRY6s("clusters/scripts.clu", "72b10193714e8c6e4daca51791c0db0c", 1087240,
+ "clusters/swordres.rif", "d21d6321ee2dbb2d7d7ca2d2a940c34a", 58916,
+ "clusters/text.clu", "76f93f5feecc8915435105478f3c6615", 2704592,
+ "smackshi/intro.smk", "d82a7869ace8fcecaa519c04c4bfc483", 13233268,
+ "bs1k.fnt", NULL, 1222000,
+ "korean.clu", NULL, -1),
+ Common::KO_KOR,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+
{
"sword1",
"",
diff --git a/engines/sword1/resman.cpp b/engines/sword1/resman.cpp
index e0896268614..2b6b27a59eb 100644
--- a/engines/sword1/resman.cpp
+++ b/engines/sword1/resman.cpp
@@ -43,10 +43,11 @@ void guiFatalError(char *msg) {
#define MAX_PATH_LEN 260
-ResMan::ResMan(const char *fileName, bool isMacFile) {
+ResMan::ResMan(const char *fileName, bool isMacFile, bool isKorean) {
_openCluStart = _openCluEnd = nullptr;
_openClus = 0;
_isBigEndian = isMacFile;
+ _isKorTrs = isKorean;
_memMan = new MemMan();
loadCluDescript(fileName);
}
@@ -139,6 +140,25 @@ void ResMan::loadCluDescript(const char *fileName) {
if (_prj.clu[3].grp[5].noRes == 29)
for (uint8 cnt = 0; cnt < 29; cnt++)
_srIdList[cnt] = 0x04050000 | cnt;
+
+ if (_isKorTrs) {
+ Common::File *cluFile = new Common::File();
+ cluFile->open("korean.clu");
+ if (cluFile->isOpen()) {
+ for (uint32 resCnt = 0, resOffset = 0; resCnt < _prj.clu[2].grp[0].noRes; resCnt++) {
+ Header header;
+ cluFile->read(&header, sizeof(Header));
+ _prj.clu[2].grp[0].offset[resCnt] = resOffset;
+ _prj.clu[2].grp[0].length[resCnt] = header.comp_length;
+ resOffset += header.comp_length;
+ cluFile->seek(header.decomp_length, SEEK_CUR);
+ }
+ cluFile->close();
+ Common::strcpy_s(_prj.clu[2].label, "korean");
+ } else {
+ _isKorTrs = false;
+ }
+ }
}
void ResMan::freeCluDescript() {
@@ -255,14 +275,40 @@ void ResMan::resOpen(uint32 id) { // load resource ID into memory
if (!memHandle)
return;
if (memHandle->cond == MEM_FREED) { // memory has been freed
- uint32 size = resLength(id);
- _memMan->alloc(memHandle, size);
- Common::File *clusFile = resFile(id);
- assert(clusFile);
- clusFile->seek(resOffset(id));
- clusFile->read(memHandle->data, size);
- if (clusFile->err() || clusFile->eos()) {
- error("Can't read %d bytes from offset %d from cluster file %s\nResource ID: %d (%08X)", size, resOffset(id), _prj.clu[(id >> 24) - 1].label, id, id);
+ if (id == GAME_FONT && _isKorTrs) {
+ // Load Korean Font
+ uint32 size = resLength(id);
+ uint32 korFontSize = 0;
+ Common::File *korFontFile = NULL;
+
+ korFontFile = new Common::File();
+ korFontFile->open("bs1k.fnt");
+ if (korFontFile->isOpen()) {
+ korFontSize = korFontFile->size();
+ }
+ _memMan->alloc(memHandle, size + korFontSize);
+ Common::File *clusFile = resFile(id);
+ assert(clusFile);
+ clusFile->seek(resOffset(id));
+ clusFile->read(memHandle->data, size);
+ if (clusFile->err() || clusFile->eos()) {
+ error("Can't read %d bytes from offset %d from cluster file %s\nResource ID: %d (%08X)", size, resOffset(id), _prj.clu[(id >> 24) - 1].label, id, id);
+ }
+
+ if (korFontSize > 0) {
+ korFontFile->read((uint8 *)memHandle->data + size, korFontSize);
+ korFontFile->close();
+ }
+ } else {
+ uint32 size = resLength(id);
+ _memMan->alloc(memHandle, size);
+ Common::File *clusFile = resFile(id);
+ assert(clusFile);
+ clusFile->seek(resOffset(id));
+ clusFile->read(memHandle->data, size);
+ if (clusFile->err() || clusFile->eos()) {
+ error("Can't read %d bytes from offset %d from cluster file %s\nResource ID: %d (%08X)", size, resOffset(id), _prj.clu[(id >> 24) - 1].label, id, id);
+ }
}
} else
_memMan->setCondition(memHandle, MEM_DONT_FREE);
diff --git a/engines/sword1/resman.h b/engines/sword1/resman.h
index 0154e738748..999ed4da7c5 100644
--- a/engines/sword1/resman.h
+++ b/engines/sword1/resman.h
@@ -64,7 +64,7 @@ struct Prj {
class ResMan {
public:
- ResMan(const char *fileName, bool isMacFile);
+ ResMan(const char *fileName, bool isMacFile, bool isKorean);
~ResMan();
void flush();
void resClose(uint32 id);
@@ -126,6 +126,7 @@ private:
Clu *_openCluStart, *_openCluEnd;
int _openClus;
bool _isBigEndian;
+ bool _isKorTrs = false;
Common::Mutex _resourceAccessMutex;
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index 26347c5eff7..7bf03562525 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -93,7 +93,8 @@ Common::Error SwordEngine::init() {
checkCdFiles();
debug(5, "Starting resource manager");
- _resMan = new ResMan("swordres.rif", _systemVars.platform == Common::kPlatformMacintosh);
+ _resMan = new ResMan("swordres.rif", _systemVars.platform == Common::kPlatformMacintosh,
+ Common::parseLanguage(ConfMan.get("language")) == Common::KO_KOR);
debug(5, "Starting object manager");
_objectMan = new ObjectMan(_resMan);
_mouse = new Mouse(_system, _resMan, _objectMan);
diff --git a/engines/sword1/text.cpp b/engines/sword1/text.cpp
index 46ecd0f66aa..c7fea7aadd3 100644
--- a/engines/sword1/text.cpp
+++ b/engines/sword1/text.cpp
@@ -130,12 +130,18 @@ void Text::makeTextSprite(uint8 slot, const uint8 *text, uint16 maxWidth, uint8
curTextLine = (const uint8 *)textString.c_str();
}
for (uint16 pos = 0; pos < lines[lineCnt].length; pos++) {
- sprPtr += copyChar(*curTextLine++, sprPtr, sprWidth, pen);
-
- if (!SwordEngine::_systemVars.isDemo) {
- sprPtr -= OVERLAP;
+ if (isKoreanChar(*curTextLine, *(curTextLine + 1))) {
+ sprPtr += copyWChar(*curTextLine, *(curTextLine + 1), sprPtr, sprWidth, pen) - OVERLAP;
+ curTextLine += 2;
+ pos++;
} else {
- sprPtr -= DEMO_OVERLAP;
+ sprPtr += copyChar(*curTextLine++, sprPtr, sprWidth, pen);
+
+ if (!SwordEngine::_systemVars.isDemo) {
+ sprPtr -= OVERLAP;
+ } else {
+ sprPtr -= DEMO_OVERLAP;
+ }
}
}
@@ -167,16 +173,22 @@ uint16 Text::analyzeSentence(const uint8 *text, uint16 maxWidth, LineInfo *line)
uint16 wordLength = 0;
while ((*text != SPACE) && *text) {
- wordWidth += charWidth(*text);
-
- if (!SwordEngine::_systemVars.isDemo) {
- wordWidth -= OVERLAP;
+ if (isKoreanChar(*text, *(text + 1))) {
+ wordWidth += wCharWidth(*text, *(text + 1)) - OVERLAP;
+ wordLength += 2;
+ text += 2;
} else {
- wordWidth -= DEMO_OVERLAP;
- }
+ wordWidth += charWidth(*text);
- wordLength++;
- text++;
+ if (!SwordEngine::_systemVars.isDemo) {
+ wordWidth -= OVERLAP;
+ } else {
+ wordWidth -= DEMO_OVERLAP;
+ }
+
+ wordLength++;
+ text++;
+ }
}
if (*text == SPACE)
@@ -306,4 +318,43 @@ void Text::printDebugLine(uint8 *ascii, uint8 first, int x, int y) {
} while (*ascii);
}
+uint16 Text::wCharWidth(uint8 hi, uint8 lo) {
+ if (isKoreanChar(hi, lo)) {
+ return 20; // fixed width : 20
+ }
+ return charWidth(hi) + charWidth(lo);
+}
+
+uint16 Text::copyWChar(uint8 hi, uint8 lo, uint8 *sprPtr, uint16 sprWidth, uint8 pen) {
+ if (!isKoreanChar(hi, lo)) {
+ return copyChar(hi, sprPtr, sprWidth, pen) + copyChar(lo, sprPtr, sprWidth, pen);
+ }
+
+ uint16 frameWidth = 20;
+ uint16 frameHeight = 26;
+ FrameHeader *chFrame = _resMan->fetchFrame(_font, 0xFF - SPACE);
+ uint8 *dest = sprPtr;
+ uint8 *decChr = ((uint8 *)chFrame) + sizeof(FrameHeader) + chFrame->width * chFrame->height + ((hi - 0xB0) * 94 + (lo - 0xA1)) * frameWidth * frameHeight;
+
+ for (uint16 cnty = 0; cnty < frameHeight; cnty++) {
+ for (uint16 cntx = 0; cntx < frameWidth; cntx++) {
+ if (*decChr == LETTER_COL)
+ dest[cntx] = pen;
+ else if (((*decChr == BORDER_COL) || (*decChr == BORDER_COL_PSX)) && (!dest[cntx])) // don't do a border if there's already a color underneath (chars can overlap)
+ dest[cntx] = BORDER_COL;
+ decChr++;
+ }
+ dest += sprWidth;
+ }
+ return frameWidth;
+}
+
+bool Text::isKoreanChar(uint8 hi, uint8 lo) {
+ if (SwordEngine::_systemVars.realLanguage != Common::KO_KOR)
+ return false;
+ if (hi >= 0xB0 && hi <= 0xC8 && lo >= 0xA1 && lo <= 0xFE)
+ return true;
+ return false;
+}
+
} // End of namespace Sword1
diff --git a/engines/sword1/text.h b/engines/sword1/text.h
index 1cee43bba7b..39defa314e9 100644
--- a/engines/sword1/text.h
+++ b/engines/sword1/text.h
@@ -58,7 +58,10 @@ public:
private:
uint16 analyzeSentence(const uint8 *text, uint16 maxWidth, LineInfo *info);
uint16 charWidth(uint8 ch);
+ uint16 wCharWidth(uint8 hi, uint8 lo);
uint16 copyChar(uint8 ch, uint8 *sprPtr, uint16 sprWidth, uint8 pen);
+ uint16 copyWChar(uint8 hi, uint8 lo, uint8 *sprPtr, uint16 sprWidth, uint8 pen);
+ bool isKoreanChar(uint8 hi, uint8 lo);
uint8 *_font;
uint8 _textCount;
More information about the Scummvm-git-logs
mailing list