Ticket #3075: 1036707-2.diff

File 1036707-2.diff, 9.8 KB (added by cyxx, 13 years ago)
  • scumm/intern.h

     
    972972        virtual const char *getOpcodeDesc(byte i);
    973973
    974974        virtual void printString(int m, const byte *msg);
     975        virtual void CHARSET_1();
    975976
    976977        virtual void scummLoop_handleSaveLoad();
    977978
  • scumm/actor.cpp

     
    18501850#ifndef DISABLE_SCUMM_7_8
    18511851void ScummEngine_v7::actorTalk(const byte *msg) {
    18521852        Actor *a;
     1853        bool stringWrap;
    18531854
    18541855        convertMessageToString(msg, _charsetBuffer, sizeof(_charsetBuffer));
    18551856
     
    18821883        if (_game.version == 7)
    18831884                VAR(VAR_HAVE_MSG) = 0xFF;
    18841885        _haveActorSpeechMsg = true;
     1886        if (_game.version == 8) {
     1887                stringWrap = _string[0].wrapping;
     1888                _string[0].wrapping = true;
     1889        }
    18851890        CHARSET_1();
    1886         if (_game.version == 8)
     1891        if (_game.version == 8) {
    18871892                VAR(VAR_HAVE_MSG) = (_string[0].no_talk_anim) ? 2 : 1;
     1893                _string[0].wrapping = stringWrap;
     1894        }
    18881895}
    18891896#endif
    18901897
  • scumm/charset.h

     
    7373        virtual void drawChar(int chr, const Graphics::Surface &s, int x, int y) {}
    7474
    7575        int getStringWidth(int a, const byte *str);
     76        int getStringHeight(const byte *text);
    7677        void addLinebreaks(int a, byte *str, int pos, int maxwidth);
    7778        void translateColor();
    7879
  • scumm/string.cpp

     
    437437        if (getTalkingActor() != 0xFF)
    438438                a = derefActorSafe(getTalkingActor(), "CHARSET_1");
    439439
    440         if (a && _string[0].overhead != 0) {
     440        if (a && _string[0].overhead) {
    441441                int s;
    442442
    443443                _string[0].xpos = a->getPos().x - virtscr[0].xstart;
     
    490490                return;
    491491
    492492        if ((_game.version <= 6 && _haveMsg == 1) ||
    493             (_game.version == 7 && _haveMsg != 1) ||
    494             (_game.version == 8 && VAR(VAR_HAVE_MSG))) {
     493            (_game.version == 7 && _haveMsg != 1)) {
    495494
    496495                if (_game.heversion >= 60) {
    497496                        if (_sound->isSoundRunning(1) == 0)
     
    644643#endif
    645644}
    646645
     646#ifndef DISABLE_SCUMM_7_8
     647void ScummEngine_v8::CHARSET_1() {
     648        byte subtitleBuffer[2048];
     649        byte *subtitleLine = subtitleBuffer;
     650        Common::Point subtitlePos;
     651
     652        processSubtitleQueue();
     653
     654        if (!_haveMsg)
     655                return;
     656
     657        Actor *a = NULL;
     658        if (getTalkingActor() != 0xFF)
     659                a = derefActorSafe(getTalkingActor(), "CHARSET_1");
     660
     661        StringTab saveStr = _string[0];
     662        if (a && _string[0].overhead) {
     663                int s;
     664
     665                _string[0].xpos = a->getPos().x - virtscr[0].xstart;
     666                s = a->_scalex * a->_talkPosX / 255;
     667                _string[0].xpos += (a->_talkPosX - s) / 2 + s;
     668
     669                _string[0].ypos = a->getPos().y - a->getElevation() - _screenTop;
     670                s = a->_scaley * a->_talkPosY / 255;
     671                _string[0].ypos += (a->_talkPosY - s) / 2 + s;
     672        }
     673
     674        _charset->setColor(_charsetColor);
     675
     676        if (a && a->_charset)
     677                _charset->setCurID(a->_charset);
     678        else
     679                _charset->setCurID(_string[0].charset);
     680
     681        if (_talkDelay)
     682                return;
     683
     684        if (VAR(VAR_HAVE_MSG)) {
     685                if ((_sound->_sfxMode & 2) == 0) {
     686                        stopTalk();
     687                }
     688                return;
     689        }
     690
     691        if (a && !_string[0].no_talk_anim) {
     692                a->runActorTalkScript(a->_talkStartFrame);
     693        }
     694
     695        if (!_keepText) {
     696                clearSubtitleQueue();
     697                _nextLeft = _string[0].xpos;
     698                _nextTop = _string[0].ypos + _screenTop;
     699        }
     700
     701        _charset->_disableOffsX = _charset->_firstChar = !_keepText;
     702
     703        _talkDelay = VAR(VAR_DEFAULT_TALK_DELAY);
     704        for (int i = _charsetBufPos; _charsetBuffer[i]; ++i) {
     705                _talkDelay += VAR(VAR_CHARINC);
     706        }
     707
     708        if (_string[0].wrapping) {
     709                _charset->addLinebreaks(0, _charsetBuffer, _charsetBufPos, _screenWidth - 20);
     710
     711                struct { int pos, w; } substring[10];
     712                int count = 0;
     713                int maxLineWidth = 0;
     714                int lastPos = 0;
     715                int code = 0;
     716                while (handleNextCharsetCode(a, &code)) {
     717                        if (code == 13 || code == 0) {
     718                                *subtitleLine++ = '\0';
     719                                assert(count < 10);
     720                                substring[count].w = _charset->getStringWidth(0, subtitleBuffer + lastPos);
     721                                if (maxLineWidth < substring[count].w) {
     722                                        maxLineWidth = substring[count].w;
     723                                }
     724                                substring[count].pos = lastPos;
     725                                ++count;
     726                                lastPos = subtitleLine - subtitleBuffer;
     727                        } else {
     728                                *subtitleLine++ = code;
     729                                *subtitleLine = '\0';
     730                        }
     731                        if (code == 0) {
     732                                break;
     733                        }
     734                }
     735
     736                int h = count * _charset->getFontHeight();
     737                h += _charset->getFontHeight() / 2;
     738                subtitlePos.y = _string[0].ypos;
     739                if (subtitlePos.y + h > _screenHeight - 10) {
     740                        subtitlePos.y = _screenHeight - 10 - h;
     741                }
     742                if (subtitlePos.y < 10) {
     743                        subtitlePos.y = 10;
     744                }
     745
     746                for (int i = 0; i < count; ++i) {
     747                        subtitlePos.x = _string[0].xpos;
     748                        if (_string[0].center) {
     749                                if (subtitlePos.x + maxLineWidth / 2 > _screenWidth - 10) {
     750                                        subtitlePos.x = _screenWidth - 10 - maxLineWidth / 2;
     751                                }
     752                                if (subtitlePos.x - maxLineWidth / 2 < 10) {
     753                                        subtitlePos.x = 10 + maxLineWidth / 2;
     754                                }
     755                                subtitlePos.x -= substring[i].w / 2;
     756                        } else {
     757                                if (subtitlePos.x + maxLineWidth > _screenWidth - 10) {
     758                                        subtitlePos.x = _screenWidth - 10 - maxLineWidth;
     759                                }
     760                                if (subtitlePos.x - maxLineWidth < 10) {
     761                                        subtitlePos.x = 10;
     762                                }
     763                        }
     764                        if (subtitlePos.y < _screenHeight - 10) {
     765                                ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer + substring[i].pos, subtitlePos, _charsetColor, _charset->getCurID());
     766                        }
     767                        subtitlePos.y += _charset->getFontHeight();
     768                }
     769        } else {
     770                int code = 0;
     771                subtitlePos.y = _string[0].ypos;
     772                if (subtitlePos.y < 10) {
     773                        subtitlePos.y = 10;
     774                }
     775                while (handleNextCharsetCode(a, &code)) {
     776                        if (code == 13 || code == 0) {
     777                                subtitlePos.x = _string[0].xpos;
     778                                if (_string[0].center) {
     779                                        subtitlePos.x -= _charset->getStringWidth(0, subtitleBuffer) / 2;
     780                                }
     781                                if (subtitlePos.x < 10) {
     782                                        subtitlePos.x = 10;
     783                                }
     784                                if (subtitlePos.y < _screenHeight - 10) {
     785                                        ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID());
     786                                        subtitlePos.y += _charset->getFontHeight();
     787                                }
     788                                subtitleLine = subtitleBuffer;
     789                        } else {
     790                                *subtitleLine++ = code;
     791                        }
     792                        *subtitleLine = '\0';
     793                        if (code == 0) {
     794                                break;
     795                        }
     796                }
     797        }
     798        _haveMsg = 2;
     799        _keepText = false;
     800        _string[0] = saveStr;
     801}
     802#endif
     803
    647804void ScummEngine::drawString(int a, const byte *msg) {
    648805        byte buf[270];
    649806        byte *space;
  • scumm/scumm.h

     
    243243        bool center;
    244244        bool overhead;
    245245        bool no_talk_anim;
     246        bool wrapping;
    246247};
    247248
    248249struct StringTab : StringSlot {
     
    11691170        virtual void printString(int m, const byte *msg);
    11701171
    11711172        virtual bool handleNextCharsetCode(Actor *a, int *c);
    1172         void CHARSET_1();
     1173        virtual void CHARSET_1();
    11731174        void drawString(int a, const byte *msg);
    11741175        void debugMessage(const byte *msg);
    11751176        void showMessageDialog(const byte *msg);
  • scumm/charset.cpp

     
    348348        return width;
    349349}
    350350
     351int CharsetRenderer::getStringHeight(const byte *text) {
     352        int pos = 0;
     353        int height = 0;
     354        byte chr;
     355        int oldID = getCurID();
     356
     357        while ((chr = text[pos++]) != 0) {
     358                if (chr == '\n' || chr == '\r')
     359                        break;
     360                if (chr == '@')
     361                        continue;
     362                if (chr == 255 || (_vm->_game.version <= 6 && chr == 254)) {
     363                        chr = text[pos++];
     364                        if (chr == 3) { // 'WAIT'
     365                                height += getFontHeight();
     366                                break;
     367                        }
     368                        if (chr == 10 || chr == 21 || chr == 12 || chr == 13) {
     369                                pos += 2;
     370                                continue;
     371                        }
     372                        if (chr == 9 || chr == 1 || chr == 2) { // 'Newline'
     373                                height += getFontHeight();
     374                                continue;
     375                        }
     376                        if (chr == 14) {
     377                                int set = text[pos] | (text[pos + 1] << 8);
     378                                pos += 2;
     379                                setCurID(set);
     380                                continue;
     381                        }
     382                }
     383        }
     384
     385        setCurID(oldID);
     386        return height + getFontHeight();
     387}
     388
    351389void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
    352390        int lastspace = -1;
    353391        int curw = 1;
  • scumm/saveload.cpp

     
    834834                MKLINE(StringTab, _default.overhead, sleByte, VER(8)),
    835835                MKLINE(StringTab, no_talk_anim, sleByte, VER(8)),
    836836                MKLINE(StringTab, _default.no_talk_anim, sleByte, VER(8)),
     837                MKLINE(StringTab, wrapping, sleByte, VER(71)),
     838                MKLINE(StringTab, _default.wrapping, sleByte, VER(71)),
    837839                MKEND()
    838840        };
    839841
  • scumm/script_v8.cpp

     
    488488                _string[m].charset = pop();
    489489                break;
    490490        case 0xCE:              // SO_PRINT_LEFT
    491                 _string[m].center = false;
     491                _string[m].wrapping = false;
    492492                _string[m].overhead = false;
    493493                break;
    494494        case 0xCF:              // SO_PRINT_OVERHEAD
     
    503503                _scriptPointer += resStrLen(_scriptPointer) + 1;
    504504                break;
    505505        case 0xD2:              // SO_PRINT_WRAP Set print wordwrap
    506                 //debug(0, "decodeParseString: SO_PRINT_WRAP");
     506                _string[m].wrapping = true;
     507                _string[m].overhead = false;
    507508                break;
    508509        default:
    509510                error("decodeParseString: default case 0x%x", b);
  • scumm/saveload.h

     
    4747 * only saves/loads those which are valid for the version of the savegame
    4848 * which is being loaded/saved currently.
    4949 */
    50 #define CURRENT_VER 70
     50#define CURRENT_VER 71
    5151
    5252/**
    5353 * An auxillary macro, used to specify savegame versions. We use this instead