[Scummvm-cvs-logs] SF.net SVN: scummvm: [26516] scummvm/trunk/engines/scumm
cyx at users.sourceforge.net
cyx at users.sourceforge.net
Sun Apr 15 22:36:45 CEST 2007
Revision: 26516
http://scummvm.svn.sourceforge.net/scummvm/?rev=26516&view=rev
Author: cyx
Date: 2007-04-15 13:36:44 -0700 (Sun, 15 Apr 2007)
Log Message:
-----------
Added code for decodeParseString.SO_PRINT_WRAP and rewrote the CHARSET_1 function in order to match the original V8 interpreter. This should fix bugs #1036707 and #1662610 (subtitles word wrapping issues).
Modified Paths:
--------------
scummvm/trunk/engines/scumm/actor.cpp
scummvm/trunk/engines/scumm/charset.cpp
scummvm/trunk/engines/scumm/charset.h
scummvm/trunk/engines/scumm/intern.h
scummvm/trunk/engines/scumm/saveload.cpp
scummvm/trunk/engines/scumm/saveload.h
scummvm/trunk/engines/scumm/script_v8.cpp
scummvm/trunk/engines/scumm/scumm.h
scummvm/trunk/engines/scumm/string.cpp
Modified: scummvm/trunk/engines/scumm/actor.cpp
===================================================================
--- scummvm/trunk/engines/scumm/actor.cpp 2007-04-15 19:03:25 UTC (rev 26515)
+++ scummvm/trunk/engines/scumm/actor.cpp 2007-04-15 20:36:44 UTC (rev 26516)
@@ -1850,6 +1850,7 @@
#ifndef DISABLE_SCUMM_7_8
void ScummEngine_v7::actorTalk(const byte *msg) {
Actor *a;
+ bool stringWrap;
convertMessageToString(msg, _charsetBuffer, sizeof(_charsetBuffer));
@@ -1882,9 +1883,15 @@
if (_game.version == 7)
VAR(VAR_HAVE_MSG) = 0xFF;
_haveActorSpeechMsg = true;
+ if (_game.version == 8) {
+ stringWrap = _string[0].wrapping;
+ _string[0].wrapping = true;
+ }
CHARSET_1();
- if (_game.version == 8)
+ if (_game.version == 8) {
VAR(VAR_HAVE_MSG) = (_string[0].no_talk_anim) ? 2 : 1;
+ _string[0].wrapping = stringWrap;
+ }
}
#endif
Modified: scummvm/trunk/engines/scumm/charset.cpp
===================================================================
--- scummvm/trunk/engines/scumm/charset.cpp 2007-04-15 19:03:25 UTC (rev 26515)
+++ scummvm/trunk/engines/scumm/charset.cpp 2007-04-15 20:36:44 UTC (rev 26516)
@@ -348,6 +348,44 @@
return width;
}
+int CharsetRenderer::getStringHeight(const byte *text) {
+ int pos = 0;
+ int height = 0;
+ byte chr;
+ int oldID = getCurID();
+
+ while ((chr = text[pos++]) != 0) {
+ if (chr == '\n' || chr == '\r')
+ break;
+ if (chr == '@')
+ continue;
+ if (chr == 255 || (_vm->_game.version <= 6 && chr == 254)) {
+ chr = text[pos++];
+ if (chr == 3) { // 'WAIT'
+ height += getFontHeight();
+ break;
+ }
+ if (chr == 10 || chr == 21 || chr == 12 || chr == 13) {
+ pos += 2;
+ continue;
+ }
+ if (chr == 9 || chr == 1 || chr == 2) { // 'Newline'
+ height += getFontHeight();
+ continue;
+ }
+ if (chr == 14) {
+ int set = text[pos] | (text[pos + 1] << 8);
+ pos += 2;
+ setCurID(set);
+ continue;
+ }
+ }
+ }
+
+ setCurID(oldID);
+ return height + getFontHeight();
+}
+
void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
int lastspace = -1;
int curw = 1;
Modified: scummvm/trunk/engines/scumm/charset.h
===================================================================
--- scummvm/trunk/engines/scumm/charset.h 2007-04-15 19:03:25 UTC (rev 26515)
+++ scummvm/trunk/engines/scumm/charset.h 2007-04-15 20:36:44 UTC (rev 26516)
@@ -73,6 +73,7 @@
virtual void drawChar(int chr, const Graphics::Surface &s, int x, int y) {}
int getStringWidth(int a, const byte *str);
+ int getStringHeight(const byte *text);
void addLinebreaks(int a, byte *str, int pos, int maxwidth);
void translateColor();
Modified: scummvm/trunk/engines/scumm/intern.h
===================================================================
--- scummvm/trunk/engines/scumm/intern.h 2007-04-15 19:03:25 UTC (rev 26515)
+++ scummvm/trunk/engines/scumm/intern.h 2007-04-15 20:36:44 UTC (rev 26516)
@@ -972,6 +972,7 @@
virtual const char *getOpcodeDesc(byte i);
virtual void printString(int m, const byte *msg);
+ virtual void CHARSET_1();
virtual void scummLoop_handleSaveLoad();
Modified: scummvm/trunk/engines/scumm/saveload.cpp
===================================================================
--- scummvm/trunk/engines/scumm/saveload.cpp 2007-04-15 19:03:25 UTC (rev 26515)
+++ scummvm/trunk/engines/scumm/saveload.cpp 2007-04-15 20:36:44 UTC (rev 26516)
@@ -834,6 +834,8 @@
MKLINE(StringTab, _default.overhead, sleByte, VER(8)),
MKLINE(StringTab, no_talk_anim, sleByte, VER(8)),
MKLINE(StringTab, _default.no_talk_anim, sleByte, VER(8)),
+ MKLINE(StringTab, wrapping, sleByte, VER(71)),
+ MKLINE(StringTab, _default.wrapping, sleByte, VER(71)),
MKEND()
};
Modified: scummvm/trunk/engines/scumm/saveload.h
===================================================================
--- scummvm/trunk/engines/scumm/saveload.h 2007-04-15 19:03:25 UTC (rev 26515)
+++ scummvm/trunk/engines/scumm/saveload.h 2007-04-15 20:36:44 UTC (rev 26516)
@@ -47,7 +47,7 @@
* only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently.
*/
-#define CURRENT_VER 70
+#define CURRENT_VER 71
/**
* An auxillary macro, used to specify savegame versions. We use this instead
Modified: scummvm/trunk/engines/scumm/script_v8.cpp
===================================================================
--- scummvm/trunk/engines/scumm/script_v8.cpp 2007-04-15 19:03:25 UTC (rev 26515)
+++ scummvm/trunk/engines/scumm/script_v8.cpp 2007-04-15 20:36:44 UTC (rev 26516)
@@ -488,7 +488,7 @@
_string[m].charset = pop();
break;
case 0xCE: // SO_PRINT_LEFT
- _string[m].center = false;
+ _string[m].wrapping = false;
_string[m].overhead = false;
break;
case 0xCF: // SO_PRINT_OVERHEAD
@@ -503,7 +503,8 @@
_scriptPointer += resStrLen(_scriptPointer) + 1;
break;
case 0xD2: // SO_PRINT_WRAP Set print wordwrap
- //debug(0, "decodeParseString: SO_PRINT_WRAP");
+ _string[m].wrapping = true;
+ _string[m].overhead = false;
break;
default:
error("decodeParseString: default case 0x%x", b);
Modified: scummvm/trunk/engines/scumm/scumm.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm.h 2007-04-15 19:03:25 UTC (rev 26515)
+++ scummvm/trunk/engines/scumm/scumm.h 2007-04-15 20:36:44 UTC (rev 26516)
@@ -243,6 +243,7 @@
bool center;
bool overhead;
bool no_talk_anim;
+ bool wrapping;
};
struct StringTab : StringSlot {
@@ -1169,7 +1170,7 @@
virtual void printString(int m, const byte *msg);
virtual bool handleNextCharsetCode(Actor *a, int *c);
- void CHARSET_1();
+ virtual void CHARSET_1();
void drawString(int a, const byte *msg);
void debugMessage(const byte *msg);
void showMessageDialog(const byte *msg);
Modified: scummvm/trunk/engines/scumm/string.cpp
===================================================================
--- scummvm/trunk/engines/scumm/string.cpp 2007-04-15 19:03:25 UTC (rev 26515)
+++ scummvm/trunk/engines/scumm/string.cpp 2007-04-15 20:36:44 UTC (rev 26516)
@@ -437,7 +437,7 @@
if (getTalkingActor() != 0xFF)
a = derefActorSafe(getTalkingActor(), "CHARSET_1");
- if (a && _string[0].overhead != 0) {
+ if (a && _string[0].overhead) {
int s;
_string[0].xpos = a->getPos().x - virtscr[0].xstart;
@@ -490,8 +490,7 @@
return;
if ((_game.version <= 6 && _haveMsg == 1) ||
- (_game.version == 7 && _haveMsg != 1) ||
- (_game.version == 8 && VAR(VAR_HAVE_MSG))) {
+ (_game.version == 7 && _haveMsg != 1)) {
if (_game.heversion >= 60) {
if (_sound->isSoundRunning(1) == 0)
@@ -644,6 +643,164 @@
#endif
}
+#ifndef DISABLE_SCUMM_7_8
+void ScummEngine_v8::CHARSET_1() {
+ byte subtitleBuffer[2048];
+ byte *subtitleLine = subtitleBuffer;
+ Common::Point subtitlePos;
+
+ processSubtitleQueue();
+
+ if (!_haveMsg)
+ return;
+
+ Actor *a = NULL;
+ if (getTalkingActor() != 0xFF)
+ a = derefActorSafe(getTalkingActor(), "CHARSET_1");
+
+ StringTab saveStr = _string[0];
+ if (a && _string[0].overhead) {
+ int s;
+
+ _string[0].xpos = a->getPos().x - virtscr[0].xstart;
+ s = a->_scalex * a->_talkPosX / 255;
+ _string[0].xpos += (a->_talkPosX - s) / 2 + s;
+
+ _string[0].ypos = a->getPos().y - a->getElevation() - _screenTop;
+ s = a->_scaley * a->_talkPosY / 255;
+ _string[0].ypos += (a->_talkPosY - s) / 2 + s;
+ }
+
+ _charset->setColor(_charsetColor);
+
+ if (a && a->_charset)
+ _charset->setCurID(a->_charset);
+ else
+ _charset->setCurID(_string[0].charset);
+
+ if (_talkDelay)
+ return;
+
+ if (VAR(VAR_HAVE_MSG)) {
+ if ((_sound->_sfxMode & 2) == 0) {
+ stopTalk();
+ }
+ return;
+ }
+
+ if (a && !_string[0].no_talk_anim) {
+ a->runActorTalkScript(a->_talkStartFrame);
+ }
+
+ if (!_keepText) {
+ clearSubtitleQueue();
+ _nextLeft = _string[0].xpos;
+ _nextTop = _string[0].ypos + _screenTop;
+ }
+
+ _charset->_disableOffsX = _charset->_firstChar = !_keepText;
+
+ _talkDelay = VAR(VAR_DEFAULT_TALK_DELAY);
+ for (int i = _charsetBufPos; _charsetBuffer[i]; ++i) {
+ _talkDelay += VAR(VAR_CHARINC);
+ }
+
+ if (_string[0].wrapping) {
+ _charset->addLinebreaks(0, _charsetBuffer, _charsetBufPos, _screenWidth - 20);
+
+ struct { int pos, w; } substring[10];
+ int count = 0;
+ int maxLineWidth = 0;
+ int lastPos = 0;
+ int code = 0;
+ while (handleNextCharsetCode(a, &code)) {
+ if (code == 13 || code == 0) {
+ *subtitleLine++ = '\0';
+ assert(count < 10);
+ substring[count].w = _charset->getStringWidth(0, subtitleBuffer + lastPos);
+ if (maxLineWidth < substring[count].w) {
+ maxLineWidth = substring[count].w;
+ }
+ substring[count].pos = lastPos;
+ ++count;
+ lastPos = subtitleLine - subtitleBuffer;
+ } else {
+ *subtitleLine++ = code;
+ *subtitleLine = '\0';
+ }
+ if (code == 0) {
+ break;
+ }
+ }
+
+ int h = count * _charset->getFontHeight();
+ h += _charset->getFontHeight() / 2;
+ subtitlePos.y = _string[0].ypos;
+ if (subtitlePos.y + h > _screenHeight - 10) {
+ subtitlePos.y = _screenHeight - 10 - h;
+ }
+ if (subtitlePos.y < 10) {
+ subtitlePos.y = 10;
+ }
+
+ for (int i = 0; i < count; ++i) {
+ subtitlePos.x = _string[0].xpos;
+ if (_string[0].center) {
+ if (subtitlePos.x + maxLineWidth / 2 > _screenWidth - 10) {
+ subtitlePos.x = _screenWidth - 10 - maxLineWidth / 2;
+ }
+ if (subtitlePos.x - maxLineWidth / 2 < 10) {
+ subtitlePos.x = 10 + maxLineWidth / 2;
+ }
+ subtitlePos.x -= substring[i].w / 2;
+ } else {
+ if (subtitlePos.x + maxLineWidth > _screenWidth - 10) {
+ subtitlePos.x = _screenWidth - 10 - maxLineWidth;
+ }
+ if (subtitlePos.x - maxLineWidth < 10) {
+ subtitlePos.x = 10;
+ }
+ }
+ if (subtitlePos.y < _screenHeight - 10) {
+ ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer + substring[i].pos, subtitlePos, _charsetColor, _charset->getCurID());
+ }
+ subtitlePos.y += _charset->getFontHeight();
+ }
+ } else {
+ int code = 0;
+ subtitlePos.y = _string[0].ypos;
+ if (subtitlePos.y < 10) {
+ subtitlePos.y = 10;
+ }
+ while (handleNextCharsetCode(a, &code)) {
+ if (code == 13 || code == 0) {
+ subtitlePos.x = _string[0].xpos;
+ if (_string[0].center) {
+ subtitlePos.x -= _charset->getStringWidth(0, subtitleBuffer) / 2;
+ }
+ if (subtitlePos.x < 10) {
+ subtitlePos.x = 10;
+ }
+ if (subtitlePos.y < _screenHeight - 10) {
+ ((ScummEngine_v7 *)this)->addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID());
+ subtitlePos.y += _charset->getFontHeight();
+ }
+ subtitleLine = subtitleBuffer;
+ } else {
+ *subtitleLine++ = code;
+ }
+ *subtitleLine = '\0';
+ if (code == 0) {
+ break;
+ }
+ }
+ }
+ _haveMsg = 2;
+ _keepText = false;
+ _string[0] = saveStr;
+}
+#endif
+
void ScummEngine::drawString(int a, const byte *msg) {
byte buf[270];
byte *space;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list