SCUMM: COMI: Fix string wrapping when wrap flag is active
This commit is contained in:
parent
378cf3a953
commit
359a9718e7
3 changed files with 85 additions and 1 deletions
|
@ -532,6 +532,33 @@ int CharsetRenderer::getStringWidth(int arg, const byte *text, uint strLenMax) {
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CharsetRenderer::getStringHeight(const char *str, uint numBytesMax) {
|
||||||
|
assert(str);
|
||||||
|
int totalHeight = 0;
|
||||||
|
int lineHeight = 0;
|
||||||
|
|
||||||
|
if (!numBytesMax)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (*str && numBytesMax) {
|
||||||
|
// No treatment of the ^ commands here, since they're handled/removed in handleTextResource().
|
||||||
|
if (*str == '\n') {
|
||||||
|
totalHeight += (lineHeight ? lineHeight : getFontHeight()) + 1;
|
||||||
|
lineHeight = 0;
|
||||||
|
} else if (*str != '\r' && *str != _vm->_newLineCharacter) {
|
||||||
|
lineHeight = MAX<int>(lineHeight, getCharHeight(*str));
|
||||||
|
if (is2ByteCharacter(_vm->_language, *str)) {
|
||||||
|
++str;
|
||||||
|
--numBytesMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++str;
|
||||||
|
--numBytesMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalHeight + (lineHeight ? lineHeight : getFontHeight()) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
|
void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
|
||||||
int lastKoreanLineBreak = -1;
|
int lastKoreanLineBreak = -1;
|
||||||
int origPos = pos;
|
int origPos = pos;
|
||||||
|
|
|
@ -96,7 +96,8 @@ public:
|
||||||
virtual void printChar(int chr, bool ignoreCharsetMask) = 0;
|
virtual void printChar(int chr, bool ignoreCharsetMask) = 0;
|
||||||
virtual void drawChar(int chr, Graphics::Surface &s, int x, int y) {}
|
virtual void drawChar(int chr, Graphics::Surface &s, int x, int y) {}
|
||||||
|
|
||||||
virtual int getStringWidth(int arg, const byte *text, uint strLenMax = 100000);
|
virtual int getStringWidth(int arg, const byte *text uint strLenMax = 100000);
|
||||||
|
int getStringHeight(const char *str, uint strLenMax = 100000);
|
||||||
void addLinebreaks(int a, byte *str, int pos, int maxwidth);
|
void addLinebreaks(int a, byte *str, int pos, int maxwidth);
|
||||||
void translateColor();
|
void translateColor();
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,62 @@ void ScummEngine_v6::enqueueText(const byte *text, int x, int y, byte color, byt
|
||||||
|
|
||||||
clipHeight = clipHeight + clipHeight / 2;
|
clipHeight = clipHeight + clipHeight / 2;
|
||||||
y = MIN<int>(y, 470 - clipHeight);
|
y = MIN<int>(y, 470 - clipHeight);
|
||||||
|
|
||||||
|
// HACK: Wrap the text when it's too long.
|
||||||
|
// The original does this by drawing word by word and adjusting x and y for each step of the pipeline.
|
||||||
|
// This, instead, is a mixture of code from SmushFont::drawStringWrap() and CHARSET_1(), which is just
|
||||||
|
// enough to split the full line into more smaller lines, which are treated as different blastText in
|
||||||
|
// the queue. Anyway this shouldn't generate more than 2 lines total but it's generalized just in case.
|
||||||
|
_charset->addLinebreaks(0, (byte *) bt.text, 0, _screenWidth - 20);
|
||||||
|
int16 substrPos[200];
|
||||||
|
memset(substrPos, 0, sizeof(substrPos));
|
||||||
|
int16 substrLen[200];
|
||||||
|
memset(substrLen, 0, sizeof(substrLen));
|
||||||
|
|
||||||
|
int len = (int) strlen((char *) bt.text);
|
||||||
|
int curPos = -1;
|
||||||
|
int numLines = 1;
|
||||||
|
|
||||||
|
// Save splitting information (position of the substring and its length)
|
||||||
|
while (curPos <= len) {
|
||||||
|
if (bt.text[curPos] == '\r') {
|
||||||
|
substrPos[numLines] = curPos + 1;
|
||||||
|
substrLen[numLines - 1] -= 1;
|
||||||
|
numLines++;
|
||||||
|
} else {
|
||||||
|
substrLen[numLines - 1] += 1;
|
||||||
|
}
|
||||||
|
curPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have found more than one line, then we split the lines and
|
||||||
|
// draw them from top to bottom
|
||||||
|
if (numLines > 1) {
|
||||||
|
int lastLineY = 0;
|
||||||
|
for (int i = 1; i < numLines; i++) {
|
||||||
|
BlastText &bt_secondary = _blastTextQueue[_blastTextQueuePos++];
|
||||||
|
strncpy((char*)bt_secondary.text, (char*)(bt.text + substrPos[i]), substrLen[i]);
|
||||||
|
bt_secondary.xpos = x;
|
||||||
|
bt_secondary.ypos = lastLineY = y + (numLines - i) * _charset->getStringHeight((char*)bt_secondary.text);
|
||||||
|
bt_secondary.color = color;
|
||||||
|
bt_secondary.charset = charset;
|
||||||
|
bt_secondary.center = center;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncate the first substring accordingly
|
||||||
|
bt.text[substrLen[0]] = '\0';
|
||||||
|
|
||||||
|
// Now correct the vertical placement for the last line, and compensate bottom-up
|
||||||
|
int diffY = lastLineY - MIN<int>(lastLineY, 470 - clipHeight);
|
||||||
|
|
||||||
|
for (int i = 1; i < numLines; i++) {
|
||||||
|
BlastText &bt_compensation = _blastTextQueue[_blastTextQueuePos - i];
|
||||||
|
bt_compensation.ypos -= diffY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also adjust the first line
|
||||||
|
y -= diffY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bt.xpos = x;
|
bt.xpos = x;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue