Ticket #8171: cmi-language.diff

File cmi-language.diff, 4.8 KB (added by eriktorbjorn, 21 years ago)

Patch against a February 7 CVS snapshot

  • scummvm/scumm/scumm.h

    diff -ur ScummVM-cvs20030207/scummvm/scumm/scumm.h ScummVM-cvs20030207+hack/scummvm/scumm/scumm.h
    old new  
    228228        msClicked = 2
    229229};
    230230
     231struct langIndexNode {
     232        char tag[8];
     233        int32 offset;
     234};
     235
    231236class Scumm : public Engine {
    232237        friend void NORETURN CDECL error(const char *s, ...);   // FIXME - ugly but error() accesses g_scumm...
    233238public:
     
    954959        bool _keepText;
    955960        bool _existLanguageFile;
    956961        char *_languageBuffer;
     962        struct langIndexNode *_languageIndex;
     963        int _languageStrCount;
    957964        void loadLanguageBundle();
    958965        void translateText(byte *text, byte *trans_buff);
    959966        byte _transText[500];
  • scummvm/scumm/string.cpp

    diff -ur ScummVM-cvs20030207/scummvm/scumm/string.cpp ScummVM-cvs20030207+hack/scummvm/scumm/string.cpp
    old new  
    812812                _charsetColorMap[i] = _charsetData[_charset->getCurID()][i];
    813813}
    814814
     815int indexCompare(const void *p1, const void *p2)
     816{
     817        struct langIndexNode *i1 = (struct langIndexNode *) p1;
     818        struct langIndexNode *i2 = (struct langIndexNode *) p2;
     819
     820        return strcmp(i1->tag, i2->tag);
     821}
     822
    815823void Scumm::loadLanguageBundle() {
    816824        File file;
     825        int32 size;
    817826
    818827        if (_gameId == GID_DIG) {
    819828                file.open("language.bnd", _gameDataPath);
     
    828837                return;
    829838        }
    830839
    831         _languageBuffer = (char*)malloc(file.size());
    832         file.read(_languageBuffer, file.size());
     840        size = file.size();
     841        _languageBuffer = (char*)malloc(size);
     842        file.read(_languageBuffer, size);
    833843        file.close();
     844
     845        // Create an index of the language file.
     846        // FIXME: Extend this mechanism to also cover The Dig?
     847
     848        if (_gameId == GID_CMI) {
     849                int32 i;
     850                char *ptr = _languageBuffer;
     851
     852                // Count the number of lines in the language file.
     853
     854                _languageStrCount = 0;
     855
     856                for (;;) {
     857                        ptr = strpbrk(ptr, "\n\r");
     858                        if (ptr == NULL)
     859                                break;
     860                        while (*ptr == '\n' || *ptr == '\r')
     861                                ptr++;
     862                        _languageStrCount++;
     863                }
     864
     865                // Fill the language file index. This is just an array of
     866                // tags and offsets. I did consider using a balanced tree
     867                // instead, but the extra overhead in the node structure would
     868                // easily have doubled the memory consumption of the index.
     869
     870                _languageIndex = (struct langIndexNode *) malloc(_languageStrCount * sizeof(struct langIndexNode));
     871
     872                ptr = _languageBuffer;
     873
     874                for (i = 0; i < _languageStrCount; i++) {
     875                        int j;
     876
     877                        for (j = 0; j < 7 && !isspace(ptr[j]); j++)
     878                                _languageIndex[i].tag[j] = toupper(ptr[j]);
     879                        _languageIndex[i].tag[j] = 0;
     880                        ptr += (j + 1);
     881                        _languageIndex[i].offset = ptr - _languageBuffer;
     882                        ptr = strpbrk(ptr, "\n\r");
     883                        if (ptr == NULL)
     884                                break;
     885                        while (*ptr == '\n' || *ptr == '\r')
     886                                ptr++;
     887                }
     888
     889                // Conceptually, it may be more elegant to construct the
     890                // index so that it is sorted, or otherwise ordered, from the
     891                // start. However, this is less error-prone and likely to be
     892                // much more optimized than anything I might implement.
     893
     894                qsort(_languageIndex, _languageStrCount, sizeof(struct langIndexNode), indexCompare);
     895                free(_languageBuffer);
     896        }
     897       
    834898        _existLanguageFile = true;
    835899}
    836900
     
    844908                pos = 0;
    845909
    846910                if (_gameId == GID_CMI) {
     911                        struct langIndexNode target;
     912                        struct langIndexNode *found;
     913
    847914                        // copy name from text /..../
    848                         for (l = 0; (l < 20) && (text[l + 1] != '/'); l++) {
    849                                 name[l] = text[l + 1];
    850                         }
    851                         name[l] = 0;
    852                         for (;;) {
    853                                 if(buf[pos] == 0) {
    854                                         trans_buff[0] = '\0';
    855                                         break;
    856                                 }
    857                                 l = 0;
    858                                 do {
    859                                         tmp[l++] = buf[pos++];
    860                                         assert(l < 499);
    861                                 } while((buf[pos] != 0) && (buf[pos] != 0x0d) && (buf[pos + 1] != 0x0a));
    862                                 tmp[l] = 0;
    863                                 pos += 2;
    864                                 l = 0;
    865                                 do {
    866                                         tmp2[l] = tmp[l];
    867                                         l++;
    868                                 } while((tmp[l] != 0) && (tmp[l] != 9) && (l < 19));
    869                                 tmp2[l] = 0;
    870                                 if (scumm_stricmp(tmp2, name) == 0) {
    871                                         strcpy((char*)trans_buff, &tmp[l + 1]);
     915                        for (l = 0; (l < 8) && (text[l + 1] != '/'); l++)
     916                                target.tag[l] = toupper(text[l + 1]);
     917                        target.tag[l] = 0;
     918
     919                        found = (struct langIndexNode *) bsearch(&target, _languageIndex, _languageStrCount, sizeof(struct langIndexNode), indexCompare);
     920
     921                        if (found != NULL) {
     922                                File file;
     923
     924                                file.open("language.tab", _gameDataPath);
     925                                if (file.isOpen()) {
     926                                        byte *ptr = trans_buff;
     927                                        byte c;
     928
     929                                        file.seek(found->offset, SEEK_SET);
     930                                        for (;;) {
     931                                                c = file.readByte();
     932                                                if (c == 10 || c == 13) {
     933                                                        *ptr = 0;
     934                                                        break;
     935                                                } else
     936                                                        *ptr++ = c;
     937                                        }
     938                                        file.close();
    872939                                        return;
    873940                                }
     941                                // Some evil person removed the language file?
     942                                _existLanguageFile = false;
    874943                        }
    875944                } else if (_gameId == GID_DIG) {
    876945                        // copy name from text /..../