continously opening and closing the language.bnd file is rather inefficient. It's about 400k, though...
svn-id: r8158
This commit is contained in:
parent
877ca1b859
commit
3efdd3ad6b
2 changed files with 26 additions and 38 deletions
|
@ -254,7 +254,7 @@ enum MouseButtonStatus {
|
||||||
msClicked = 2
|
msClicked = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
struct langIndexNode {
|
struct LangIndexNode {
|
||||||
char tag[9];
|
char tag[9];
|
||||||
int32 offset;
|
int32 offset;
|
||||||
};
|
};
|
||||||
|
@ -1064,7 +1064,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
bool _existLanguageFile;
|
bool _existLanguageFile;
|
||||||
char *_languageBuffer;
|
char *_languageBuffer;
|
||||||
struct langIndexNode *_languageIndex;
|
LangIndexNode *_languageIndex;
|
||||||
int _languageStrCount;
|
int _languageStrCount;
|
||||||
byte _transText[500];
|
byte _transText[500];
|
||||||
|
|
||||||
|
|
|
@ -745,8 +745,8 @@ void Scumm::initCharset(int charsetno) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int indexCompare(const void *p1, const void *p2) {
|
int indexCompare(const void *p1, const void *p2) {
|
||||||
const struct langIndexNode *i1 = (const struct langIndexNode *) p1;
|
const LangIndexNode *i1 = (const LangIndexNode *) p1;
|
||||||
const struct langIndexNode *i2 = (const struct langIndexNode *) p2;
|
const LangIndexNode *i2 = (const LangIndexNode *) p2;
|
||||||
|
|
||||||
return strcmp(i1->tag, i2->tag);
|
return strcmp(i1->tag, i2->tag);
|
||||||
}
|
}
|
||||||
|
@ -797,23 +797,32 @@ void Scumm::loadLanguageBundle() {
|
||||||
// instead, but the extra overhead in the node structure would
|
// instead, but the extra overhead in the node structure would
|
||||||
// easily have doubled the memory consumption of the index.
|
// easily have doubled the memory consumption of the index.
|
||||||
|
|
||||||
_languageIndex = (struct langIndexNode *) malloc(_languageStrCount * sizeof(struct langIndexNode));
|
_languageIndex = (LangIndexNode *)calloc(_languageStrCount, sizeof(LangIndexNode));
|
||||||
|
|
||||||
ptr = _languageBuffer;
|
ptr = _languageBuffer;
|
||||||
|
|
||||||
for (i = 0; i < _languageStrCount; i++) {
|
for (i = 0; i < _languageStrCount; i++) {
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = 0; j < 8 && !isspace(ptr[j]); j++)
|
// First 8 chars in the line give the string ID / 'tag'
|
||||||
_languageIndex[i].tag[j] = toupper(ptr[j]);
|
for (j = 0; j < 8 && !isspace(*ptr); j++, ptr++)
|
||||||
|
_languageIndex[i].tag[j] = toupper(*ptr);
|
||||||
_languageIndex[i].tag[j] = 0;
|
_languageIndex[i].tag[j] = 0;
|
||||||
ptr += (j + 1);
|
|
||||||
|
// After that follows a single space which we skip
|
||||||
|
assert(isspace(*ptr));
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
// Then comes the translated string: we record an offset to that.
|
||||||
_languageIndex[i].offset = ptr - _languageBuffer;
|
_languageIndex[i].offset = ptr - _languageBuffer;
|
||||||
|
|
||||||
|
//skip:
|
||||||
|
// Skip over newlines (and turn them into null bytes)
|
||||||
ptr = strpbrk(ptr, "\n\r");
|
ptr = strpbrk(ptr, "\n\r");
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
break;
|
break;
|
||||||
while (*ptr == '\n' || *ptr == '\r')
|
while (*ptr == '\n' || *ptr == '\r')
|
||||||
ptr++;
|
*ptr++ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conceptually, it may be more elegant to construct the
|
// Conceptually, it may be more elegant to construct the
|
||||||
|
@ -821,8 +830,7 @@ void Scumm::loadLanguageBundle() {
|
||||||
// start. However, this is less error-prone and likely to be
|
// start. However, this is less error-prone and likely to be
|
||||||
// much more optimized than anything I might implement.
|
// much more optimized than anything I might implement.
|
||||||
|
|
||||||
qsort(_languageIndex, _languageStrCount, sizeof(struct langIndexNode), indexCompare);
|
qsort(_languageIndex, _languageStrCount, sizeof(LangIndexNode), indexCompare);
|
||||||
free(_languageBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_existLanguageFile = true;
|
_existLanguageFile = true;
|
||||||
|
@ -833,8 +841,8 @@ void Scumm::translateText(const byte *text, byte *trans_buff) {
|
||||||
|
|
||||||
if ((text[0] == '/') && _existLanguageFile) {
|
if ((text[0] == '/') && _existLanguageFile) {
|
||||||
if (_gameId == GID_CMI) {
|
if (_gameId == GID_CMI) {
|
||||||
struct langIndexNode target;
|
LangIndexNode target;
|
||||||
struct langIndexNode *found = NULL;
|
LangIndexNode *found = NULL;
|
||||||
|
|
||||||
// copy name from text /..../
|
// copy name from text /..../
|
||||||
for (l = 0; (l < 8) && (text[l + 1] != '/'); l++)
|
for (l = 0; (l < 8) && (text[l + 1] != '/'); l++)
|
||||||
|
@ -849,41 +857,21 @@ void Scumm::translateText(const byte *text, byte *trans_buff) {
|
||||||
// we can't find translations for these.
|
// we can't find translations for these.
|
||||||
|
|
||||||
if (strcmp(target.tag, "PU_M001") != 0 && strcmp(target.tag, "PU_M002") != 0)
|
if (strcmp(target.tag, "PU_M001") != 0 && strcmp(target.tag, "PU_M002") != 0)
|
||||||
found = (struct langIndexNode *)bsearch(&target, _languageIndex, _languageStrCount, sizeof(struct langIndexNode), indexCompare);
|
found = (LangIndexNode *)bsearch(&target, _languageIndex, _languageStrCount, sizeof(LangIndexNode), indexCompare);
|
||||||
if (found != NULL) {
|
if (found != NULL) {
|
||||||
File file;
|
strcpy((char *)trans_buff, _languageBuffer + found->offset);
|
||||||
|
return;
|
||||||
file.open("language.tab", getGameDataPath());
|
|
||||||
if (file.isOpen()) {
|
|
||||||
byte *ptr = trans_buff;
|
|
||||||
byte c;
|
|
||||||
|
|
||||||
file.seek(found->offset, SEEK_SET);
|
|
||||||
for (;;) {
|
|
||||||
c = file.readByte();
|
|
||||||
if (c == 10 || c == 13) {
|
|
||||||
*ptr = 0;
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
*ptr++ = c;
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// Some evil person removed the language file?
|
|
||||||
_existLanguageFile = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (_gameId == GID_DIG) {
|
} else if (_gameId == GID_DIG) {
|
||||||
// FIXME: This code really could stand a rewrite
|
// FIXME: This code really could stand a rewrite
|
||||||
// It's rather inefficient and if a string isn't found it'll read past the
|
// It's rather inefficient and if a string isn't found it'll read past the
|
||||||
// end of the _languageBuffer.
|
// end of the _languageBuffer.
|
||||||
char name[20], tmp[500], tmp2[20], num_s[20], number[4], enc;
|
char name[12+1], tmp[500], tmp2[20], num_s[20], number[4], enc;
|
||||||
int32 num, j, k, r, pos = 0;
|
int32 num, j, k, r, pos = 0;
|
||||||
char *buf = _languageBuffer;
|
char *buf = _languageBuffer;
|
||||||
|
|
||||||
// copy name from text /..../
|
// copy name from text /..../
|
||||||
for (l = 0; (l < 20) && (text[l + 1] != '.'); l++) {
|
for (l = 0; (l < 12) && (text[l + 1] != '.'); l++) {
|
||||||
name[l] = text[l + 1];
|
name[l] = text[l + 1];
|
||||||
}
|
}
|
||||||
name[l] = 0;
|
name[l] = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue