aboutsummaryrefslogtreecommitdiff
path: root/scumm/smush
diff options
context:
space:
mode:
authorMax Horn2003-06-08 00:39:08 +0000
committerMax Horn2003-06-08 00:39:08 +0000
commitfaadbcafa70365bf3ee1b48efff5b94d62fcece2 (patch)
tree5d248ffca0c9c224ac2c3f5476171c29d7388f19 /scumm/smush
parentf273c4195b77ce699520071cdec410fcfa54bdb8 (diff)
downloadscummvm-rg350-faadbcafa70365bf3ee1b48efff5b94d62fcece2.tar.gz
scummvm-rg350-faadbcafa70365bf3ee1b48efff5b94d62fcece2.tar.bz2
scummvm-rg350-faadbcafa70365bf3ee1b48efff5b94d62fcece2.zip
cleanup; got rid of the split function and rather work in place (so instead of allocating dozens of small goblets of memory, we only need to duplicate the string once); fixed some text positioning bugs (but again, to get a real accurate implementation, I'll need to study screen shots of the Dig/FT/COMI videos and compare them to our results)
svn-id: r8388
Diffstat (limited to 'scumm/smush')
-rw-r--r--scumm/smush/smush_font.cpp237
-rw-r--r--scumm/smush/smush_font.h8
-rw-r--r--scumm/smush/smush_player.cpp8
3 files changed, 99 insertions, 154 deletions
diff --git a/scumm/smush/smush_font.cpp b/scumm/smush/smush_font.cpp
index 841d4270bc..38d6ffaa6b 100644
--- a/scumm/smush/smush_font.cpp
+++ b/scumm/smush/smush_font.cpp
@@ -33,6 +33,7 @@ SmushFont::SmushFont(bool use_original_colors, bool new_colors) :
}
int SmushFont::getStringWidth(const char *str) {
+ assert(str);
if (!_loaded) {
warning("SmushFont::getStringWidth() Font is not loaded");
return 0;
@@ -46,6 +47,7 @@ int SmushFont::getStringWidth(const char *str) {
}
int SmushFont::getStringHeight(const char *str) {
+ assert(str);
if (!_loaded) {
warning("SmushFont::getStringHeight() Font is not loaded");
return 0;
@@ -134,30 +136,6 @@ int SmushFont::draw2byte(byte *buffer, int dst_width, int x, int y, int idx) {
return w + 1;
}
-static char **split(const char *str, char sep) {
- char **ret = new char *[62];
- int n = 0;
- const char *i = str;
- char *j = strchr(i, sep);
-
- while (j != NULL) {
- assert(n < 60);
- ret[n] = new char[j - i + 1];
- memcpy(ret[n], i, j - i);
- ret[n++][j - i] = 0;
- i = j + 1;
- j = strchr(i, sep);
- }
-
- int len = strlen(i);
- ret[n] = new char[len + 1];
- memcpy(ret[n], i, len);
- ret[n++][len] = 0;
- ret[n] = 0;
-
- return ret;
-}
-
void SmushFont::drawSubstring(const char *str, byte *buffer, int dst_width, int x, int y) {
for (int i = 0; str[i] != 0; i++) {
if ((byte)str[i] >= 0x80 && _vm->_CJKMode) {
@@ -168,6 +146,9 @@ void SmushFont::drawSubstring(const char *str, byte *buffer, int dst_width, int
}
}
+#define MAX_WORDS 60
+
+
void SmushFont::drawStringAbsolute(const char *str, byte *buffer, int dst_width, int x, int y) {
debug(9, "SmushFont::drawStringAbsolute(%s, %d, %d)", str, x, y);
@@ -187,138 +168,116 @@ void SmushFont::drawStringAbsolute(const char *str, byte *buffer, int dst_width,
}
}
-void SmushFont::drawStringCentered(const char *str, byte *buffer, int dst_width, int dst_height, int y, int xmin, int width, int offset) {
- debug(9, "SmushFont::drawStringCentered(%s, %d, %d)", str, xmin, y);
+void SmushFont::drawStringCentered(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right) {
+ debug(9, "SmushFont::drawStringCentered(%s, %d, %d, %d, %d)", str, x, y, left, right);
- char *z = strchr(str, '\n');
- if (z != 0) {
- // FIXME: this is actually evil, because it silently modifes the
- // string 'str' passed to us, despite it being declared const.
- warning("drawStringCentered: got input string containing \\n");
- *z = 0;
- }
- char **words = split(str, ' ');
+ const int width = right - left;
+ char *s = strdup(str);
+ char *words[MAX_WORDS];
int word_count = 0;
- while (words[word_count])
- word_count++;
+ char *tmp = s;
+ while (tmp) {
+ assert(word_count < MAX_WORDS);
+ words[word_count++] = tmp;
+ tmp = strpbrk(tmp, " \t\r\n");
+ if (tmp == 0)
+ break;
+ *tmp++ = 0;
+ }
int i = 0, max_width = 0, height = 0, line_count = 0;
- char **substrings = new char *[word_count];
- int *substr_widths = new int[word_count];
- int space_width = getCharWidth(' ');
+ char *substrings[MAX_WORDS];
+ int substr_widths[MAX_WORDS];
+ const int space_width = getCharWidth(' ');
i = 0;
while (i < word_count) {
- int substr_width = getStringWidth(words[i]);
- char *substr = new char[1000];
- strcpy(substr, words[i]);
- int j = i + 1;
+ char *substr = words[i++];
+ int substr_width = getStringWidth(substr);
- while (j < word_count) {
- int word_width = getStringWidth(words[j]);
+ while (i < word_count) {
+ int word_width = getStringWidth(words[i]);
if ((substr_width + space_width + word_width) >= width)
break;
substr_width += word_width + space_width;
- j++;
- }
-
- for (int k = i + 1; k < j; k++) {
- strcat(substr, " ");
- strcat(substr, words[k]);
+ *(words[i]-1) = ' '; // Convert 0 byte back to space
+ i++;
}
substrings[line_count] = substr;
substr_widths[line_count++] = substr_width;
- if (substr_width > max_width)
+ if (max_width < substr_width)
max_width = substr_width;
- i = j;
height += getStringHeight(substr);
}
- for (i = 0; i < word_count; i++) {
- delete[] words[i];
- }
- delete[] words;
-
if (y > dst_height - height) {
y = dst_height - height;
}
max_width = (max_width + 1) >> 1;
- int x = xmin + width / 2 + offset - dst_width / 2;
+ x = left + width / 2;
- if (x < max_width)
- x = max_width;
- if (x > dst_width - max_width)
- x = dst_width - max_width;
+ if (x < left + max_width)
+ x = left + max_width;
+ if (x > right - max_width)
+ x = right - max_width;
for (i = 0; i < line_count; i++) {
drawSubstring(substrings[i], buffer, dst_width, x - substr_widths[i] / 2, y);
y += getStringHeight(substrings[i]);
- delete[] substrings[i];
}
-
- delete[] substr_widths;
- delete[] substrings;
+
+ free(s);
}
-void SmushFont::drawStringWrap(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width) {
- debug(9, "SmushFont::drawStringWrap(%s, %d, %d)", str, x, y);
+void SmushFont::drawStringWrap(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right) {
+ debug(9, "SmushFont::drawStringWrap(%s, %d, %d, %d, %d)", str, x, y, left, right);
- char *z = strchr(str, '\n');
- if (z != 0) {
- // FIXME: this is actually evil, because it silently modifes the
- // string 'str' passed to us, despite it being declared const.
- warning("drawStringWrap: got input string containing \\n");
- *z = 0;
- }
- char **words = split(str, ' ');
+ const int width = right - left;
+ char *s = strdup(str);
+ char *words[MAX_WORDS];
int word_count = 0;
- while (words[word_count])
- word_count++;
+ char *tmp = s;
+ while (tmp) {
+ assert(word_count < MAX_WORDS);
+ words[word_count++] = tmp;
+ tmp = strpbrk(tmp, " \t\r\n");
+ if (tmp == 0)
+ break;
+ *tmp++ = 0;
+ }
int i = 0, max_width = 0, height = 0, line_count = 0;
- char **substrings = new char *[word_count];
- int *substr_widths = new int[word_count];
- int space_width = getCharWidth(' ');
+ char *substrings[MAX_WORDS];
+ int substr_widths[MAX_WORDS];
+ const int space_width = getCharWidth(' ');
i = 0;
while (i < word_count) {
- int substr_width = getStringWidth(words[i]);
- char *substr = new char[1000];
- strcpy(substr, words[i]);
- int j = i + 1;
+ char *substr = words[i++];
+ int substr_width = getStringWidth(substr);
- while (j < word_count) {
- int word_width = getStringWidth(words[j]);
+ while (i < word_count) {
+ int word_width = getStringWidth(words[i]);
if ((substr_width + space_width + word_width) >= width)
break;
substr_width += word_width + space_width;
- j++;
- }
-
- for (int k = i + 1; k < j; k++) {
- strcat(substr, " ");
- strcat(substr, words[k]);
+ *(words[i]-1) = ' '; // Convert 0 byte back to space
+ i++;
}
substrings[line_count] = substr;
substr_widths[line_count++] = substr_width;
if (max_width < substr_width)
max_width = substr_width;
- i = j;
height += getStringHeight(substr);
}
- for (i = 0; i < word_count; i++) {
- delete[] words[i];
- }
- delete[] words;
-
if (y > dst_height - height) {
y = dst_height - height;
}
@@ -329,86 +288,72 @@ void SmushFont::drawStringWrap(const char *str, byte *buffer, int dst_width, int
for (i = 0; i < line_count; i++) {
drawSubstring(substrings[i], buffer, dst_width, x, y);
y += getStringHeight(substrings[i]);
- delete[] substrings[i];
}
-
- delete[] substr_widths;
- delete[] substrings;
+
+ free(s);
}
-void SmushFont::drawStringWrapCentered(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width) {
- debug(9, "SmushFont::drawStringWrapCentered(%s, %d, %d)", str, x, y);
+void SmushFont::drawStringWrapCentered(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right) {
+ debug(9, "SmushFont::drawStringWrapCentered(%s, %d, %d, %d, %d)", str, x, y, left, right);
- char *z = strchr(str, '\n');
- if (z != 0) {
- // FIXME: this is actually evil, because it silently modifes the
- // string 'str' passed to us, despite it being declared const.
- warning("drawStringWrapCentered: got input string containing \\n");
- *z = 0;
- }
- char **words = split(str, ' ');
+ const int width = right - left;
+ char *s = strdup(str);
+ char *words[MAX_WORDS];
int word_count = 0;
- while (words[word_count])
- word_count++;
+ char *tmp = s;
+ while (tmp) {
+ assert(word_count < MAX_WORDS);
+ words[word_count++] = tmp;
+ tmp = strpbrk(tmp, " \t\r\n");
+ if (tmp == 0)
+ break;
+ *tmp++ = 0;
+ }
int i = 0, max_width = 0, height = 0, line_count = 0;
- char **substrings = new char *[word_count];
- int *substr_widths = new int[word_count];
- int space_width = getCharWidth(' ');
+ char *substrings[MAX_WORDS];
+ int substr_widths[MAX_WORDS];
+ const int space_width = getCharWidth(' ');
i = 0;
- width = MIN(width, dst_width);
while (i < word_count) {
- int substr_width = getStringWidth(words[i]);
- char *substr = new char[1000];
- strcpy(substr, words[i]);
- int j = i + 1;
+ char *substr = words[i++];
+ int substr_width = getStringWidth(substr);
- while (j < word_count) {
- int word_width = getStringWidth(words[j]);
+ while (i < word_count) {
+ int word_width = getStringWidth(words[i]);
if ((substr_width + space_width + word_width) >= width)
break;
substr_width += word_width + space_width;
- j++;
- }
-
- for (int k = i + 1; k < j; k++) {
- strcat(substr, " ");
- strcat(substr, words[k]);
+ *(words[i]-1) = ' '; // Convert 0 byte back to space
+ i++;
}
substrings[line_count] = substr;
substr_widths[line_count++] = substr_width;
if (max_width < substr_width)
max_width = substr_width;
- i = j;
height += getStringHeight(substr);
}
- for (i = 0; i < word_count; i++) {
- delete[] words[i];
- }
- delete[] words;
-
if (y > dst_height - height) {
y = dst_height - height;
}
max_width = (max_width + 1) >> 1;
+ x = left + width / 2;
- if (x < max_width)
- x = max_width;
- if (x > dst_width - max_width)
- x = dst_width - max_width;
+ if (x < left + max_width)
+ x = left + max_width;
+ if (x > right - max_width)
+ x = right - max_width;
for (i = 0; i < line_count; i++) {
drawSubstring(substrings[i], buffer, dst_width, x - substr_widths[i] / 2, y);
y += getStringHeight(substrings[i]);
- delete[] substrings[i];
}
-
- delete[] substr_widths;
- delete[] substrings;
+
+ free(s);
}
diff --git a/scumm/smush/smush_font.h b/scumm/smush/smush_font.h
index 540df96662..ae5932693a 100644
--- a/scumm/smush/smush_font.h
+++ b/scumm/smush/smush_font.h
@@ -43,10 +43,10 @@ public:
SmushFont(bool use_original_colors, bool new_colors);
void setColor(byte c) { _color = c; }
- void drawStringCentered(const char *str, byte *buffer, int dst_width, int dst_height, int y, int xmin, int width, int offset);
- void drawStringWrap(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width);
- void drawStringWrapCentered(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width);
- void drawStringAbsolute(const char *str, byte *buffer, int dst_width, int x, int y);
+ void drawStringAbsolute (const char *str, byte *buffer, int dst_width, int x, int y);
+ void drawStringCentered (const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right);
+ void drawStringWrap (const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right);
+ void drawStringWrapCentered(const char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int left, int right);
};
#endif
diff --git a/scumm/smush/smush_player.cpp b/scumm/smush/smush_player.cpp
index 311d375431..92fce74919 100644
--- a/scumm/smush/smush_player.cpp
+++ b/scumm/smush/smush_player.cpp
@@ -484,7 +484,7 @@ void SmushPlayer::handleTextResource(Chunk &b) {
int flags = b.getShort();
int left = b.getShort();
int top = b.getShort();
- int width = b.getShort();
+ int right = b.getShort();
/*int32 height =*/ b.getShort();
/*int32 unk2 =*/ b.getWord();
@@ -561,13 +561,13 @@ void SmushPlayer::handleTextResource(Chunk &b) {
sf->drawStringAbsolute(str, _data, _width, pos_x, pos_y);
break;
case 1:
- sf->drawStringCentered(str, _data, _width, _height, MAX(pos_y, top), left, width, pos_x);
+ sf->drawStringCentered(str, _data, _width, _height, pos_x, MAX(pos_y, top), left, right);
break;
case 8:
- sf->drawStringWrap(str, _data, _width, _height, pos_x, MAX(pos_y, top), width);
+ sf->drawStringWrap(str, _data, _width, _height, pos_x, MAX(pos_y, top), left, right);
break;
case 9:
- sf->drawStringWrapCentered(str, _data, _width, _height, pos_x, MAX(pos_y, top), width);
+ sf->drawStringWrapCentered(str, _data, _width, _height, pos_x, MAX(pos_y, top), left, right);
break;
default:
warning("SmushPlayer::handleTextResource. Not handled flags: %d", flags);