Ticket #3075: 1036707.diff

File 1036707.diff, 10.0 KB (added by cyxx, 13 years ago)
  • 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

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

     
    409409
    410410void ScummEngine::CHARSET_1() {
    411411        Actor *a;
     412        StringTab saveStr;
    412413#ifndef DISABLE_SCUMM_7_8
    413         byte subtitleBuffer[200];
     414        byte subtitleBuffer[2048];
    414415        byte *subtitleLine = subtitleBuffer;
    415416        Common::Point subtitlePos;
    416417
     
    437438        if (getTalkingActor() != 0xFF)
    438439                a = derefActorSafe(getTalkingActor(), "CHARSET_1");
    439440
    440         if (a && _string[0].overhead != 0) {
    441                 int s;
     441        if (_game.version == 8) {
     442                saveStr = _string[0];
     443                if (a && _string[0].overhead) {
     444                        int s;
    442445
    443                 _string[0].xpos = a->getPos().x - virtscr[0].xstart;
    444                 _string[0].ypos = a->getPos().y - a->getElevation() - _screenTop;
     446                        _string[0].xpos = a->getPos().x - virtscr[0].xstart;
     447                        s = a->_scalex * a->_talkPosX / 255;
     448                        _string[0].xpos += (a->_talkPosX - s) / 2 + s;
    445449
    446                 if (_game.version <= 5) {
     450                        _string[0].ypos = a->getPos().y - a->getElevation() - _screenTop;
     451                        s = a->_scaley * a->_talkPosY / 255;
     452                        _string[0].ypos += (a->_talkPosY - s) / 2 + s;
     453                }
     454        } else {
     455                if (a && _string[0].overhead) {
     456                        int s;
    447457
    448                         if (VAR(VAR_V5_TALK_STRING_Y) < 0) {
    449                                 s = (a->_scaley * (int)VAR(VAR_V5_TALK_STRING_Y)) / 0xFF;
    450                                 _string[0].ypos += (int)(((VAR(VAR_V5_TALK_STRING_Y) - s) / 2) + s);
     458                        _string[0].xpos = a->getPos().x - virtscr[0].xstart;
     459                        _string[0].ypos = a->getPos().y - a->getElevation() - _screenTop;
     460
     461                        if (_game.version <= 5) {
     462
     463                                if (VAR(VAR_V5_TALK_STRING_Y) < 0) {
     464                                        s = (a->_scaley * (int)VAR(VAR_V5_TALK_STRING_Y)) / 0xFF;
     465                                        _string[0].ypos += (int)(((VAR(VAR_V5_TALK_STRING_Y) - s) / 2) + s);
     466                                } else {
     467                                        _string[0].ypos = (int)VAR(VAR_V5_TALK_STRING_Y);
     468                                }
     469
    451470                        } else {
    452                                 _string[0].ypos = (int)VAR(VAR_V5_TALK_STRING_Y);
     471                                s = a->_scalex * a->_talkPosX / 0xFF;
     472                                _string[0].xpos += ((a->_talkPosX - s) / 2) + s;
     473
     474                                s = a->_scaley * a->_talkPosY / 0xFF;
     475                                _string[0].ypos += ((a->_talkPosY - s) / 2) + s;
     476
     477                                if (_string[0].ypos > _screenHeight - 40)
     478                                        _string[0].ypos = _screenHeight - 40;
    453479                        }
    454480
    455                 } else {
    456                         s = a->_scalex * a->_talkPosX / 0xFF;
    457                         _string[0].xpos += ((a->_talkPosX - s) / 2) + s;
     481                        if (_string[0].ypos < 1)
     482                                _string[0].ypos = 1;
    458483
    459                         s = a->_scaley * a->_talkPosY / 0xFF;
    460                         _string[0].ypos += ((a->_talkPosY - s) / 2) + s;
    461 
    462                         if (_string[0].ypos > _screenHeight - 40)
    463                                 _string[0].ypos = _screenHeight - 40;
     484                        if (_string[0].xpos < 80)
     485                                _string[0].xpos = 80;
     486                        if (_string[0].xpos > _screenWidth - 80)
     487                                _string[0].xpos = _screenWidth - 80;
    464488                }
    465489
    466                 if (_string[0].ypos < 1)
    467                         _string[0].ypos = 1;
    468 
    469                 if (_string[0].xpos < 80)
    470                         _string[0].xpos = 80;
    471                 if (_string[0].xpos > _screenWidth - 80)
    472                         _string[0].xpos = _screenWidth - 80;
     490                _charset->_top = _string[0].ypos + _screenTop;
     491                _charset->_startLeft = _charset->_left = _string[0].xpos;
     492                _charset->_right = _string[0].right;
     493                _charset->_center = _string[0].center;
    473494        }
    474 
    475         _charset->_top = _string[0].ypos + _screenTop;
    476         _charset->_startLeft = _charset->_left = _string[0].xpos;
    477         _charset->_right = _string[0].right;
    478         _charset->_center = _string[0].center;
    479495        _charset->setColor(_charsetColor);
    480496
    481497        if (a && a->_charset)
     
    522538                }
    523539        }
    524540
     541        _charset->_disableOffsX = _charset->_firstChar = !_keepText;
     542
     543        // XXX turn CHARSET_1 into a virtual method and overload it for V8
     544        // XXX add StringTab.wrapping to the saveload data
     545        if (_game.version == 8) {
     546                if (_string[0].wrapping) {
     547
     548                        _charset->addLinebreaks(0, _charsetBuffer, _charsetBufPos, _screenWidth - 20);
     549
     550                        struct { int pos, w; } substring[10];
     551                        int count = 0;
     552                        int maxLineWidth = 0;
     553                        int lastPos = 0;
     554                        int code = 0;
     555                        while (handleNextCharsetCode(a, &code)) {
     556                                if (code == 13 || code == 0) {
     557                                        *subtitleLine++ = '\0';
     558                                        assert(count < 10);
     559                                        substring[count].w = _charset->getStringWidth(0, subtitleBuffer + lastPos);
     560                                        if (maxLineWidth < substring[count].w) {
     561                                                maxLineWidth = substring[count].w;
     562                                        }
     563                                        substring[count].pos = lastPos;
     564                                        ++count;
     565                                        lastPos = subtitleLine - subtitleBuffer;
     566                                } else {
     567                                        *subtitleLine++ = code;
     568                                        *subtitleLine = '\0';
     569                                }
     570                                if (code == 0) {
     571                                        break;
     572                                }
     573                        }
     574
     575                        int h = count * _charset->getFontHeight();
     576                        h += _charset->getFontHeight() / 2;
     577                        subtitlePos.y = _string[0].ypos;
     578                        if (subtitlePos.y + h > _screenHeight - 10) {
     579                                subtitlePos.y = _screenHeight - 10 - h;
     580                        }
     581                        if (subtitlePos.y < 10) {
     582                                subtitlePos.y = 10;
     583                        }
     584
     585                        for (int i = 0; i < count; ++i) {
     586                                subtitlePos.x = _string[0].xpos;
     587                                if (_string[0].center) {
     588                                        if (subtitlePos.x + maxLineWidth / 2 > _screenWidth - 10) {
     589                                                subtitlePos.x = _screenWidth - 10 - maxLineWidth / 2;
     590                                        }
     591                                        if (subtitlePos.x - maxLineWidth / 2 < 10) {
     592                                                subtitlePos.x = 10 + maxLineWidth / 2;
     593                                        }
     594                                        subtitlePos.x -= substring[i].w / 2;
     595                                } else {
     596                                        if (subtitlePos.x + maxLineWidth > _screenWidth - 10) {
     597                                                subtitlePos.x = _screenWidth - 10 - maxLineWidth;
     598                                        }
     599                                        if (subtitlePos.x - maxLineWidth < 10) {
     600                                                subtitlePos.x = 10;
     601                                        }
     602                                }
     603                                if (subtitlePos.y < _screenHeight - 10) {
     604                                        ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer + substring[i].pos, subtitlePos, _charsetColor, _charset->getCurID());
     605                                }
     606                                subtitlePos.y += _charset->getFontHeight();
     607                        }
     608                } else {
     609                        int code = 0;
     610                        subtitlePos.y = _string[0].ypos;
     611                        if (subtitlePos.y < 10) {
     612                                subtitlePos.y = 10;
     613                        }
     614                        while (handleNextCharsetCode(a, &code)) {
     615                                if (code == 13 || code == 0) {
     616                                        subtitlePos.x = _string[0].xpos;
     617                                        if (_string[0].center) {
     618                                                subtitlePos.x -= _charset->getStringWidth(0, subtitleBuffer) / 2;
     619                                        }
     620                                        if (subtitlePos.x < 10) {
     621                                                subtitlePos.x = 10;
     622                                        }
     623                                        if (subtitlePos.y < _screenHeight - 10) {
     624                                                ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID());
     625                                                subtitlePos.y += _charset->getFontHeight();
     626                                        }
     627                                        subtitleLine = subtitleBuffer;
     628                                } else {
     629                                        *subtitleLine++ = code;
     630                                }
     631                                *subtitleLine = '\0';
     632                                if (code == 0) {
     633                                        break;
     634                                }
     635                        }
     636                }
     637                _haveMsg = 2;
     638                _keepText = false;
     639                _string[0] = saveStr;
     640                return;
     641        }
     642
    525643        if (_game.version > 3) {
    526644                int maxwidth = _charset->_right - _string[0].xpos - 1;
    527645                if (_charset->_center) {
     
    539657                        _nextLeft = 0;
    540658        }
    541659
    542         _charset->_disableOffsX = _charset->_firstChar = !_keepText;
    543 
    544660        int c = 0;
    545661        while (handleNextCharsetCode(a, &c)) {
    546662                if (c == 0) {
  • scumm/scumm.h

     
    243243        bool center;
    244244        bool overhead;
    245245        bool no_talk_anim;
     246        bool wrapping;
    246247};
    247248
    248249struct StringTab : StringSlot {
  • 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/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);