aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/util.cpp25
-rw-r--r--common/util.h4
-rw-r--r--scumm/resource.cpp2
-rw-r--r--scumm/script.cpp56
-rw-r--r--scumm/script_v5.cpp2
-rw-r--r--scumm/script_v6.cpp51
-rw-r--r--scumm/script_v8.cpp82
-rw-r--r--scumm/scumm.h5
-rw-r--r--scumm/string.cpp23
9 files changed, 82 insertions, 168 deletions
diff --git a/common/util.cpp b/common/util.cpp
index 2423cd0af0..ef0e2fb7a0 100644
--- a/common/util.cpp
+++ b/common/util.cpp
@@ -133,31 +133,6 @@ void hexdump(const byte * data, int len)
printf("|\n");
}
-//
-// Given a pointer to a Scumm resource, this function returns the length
-// of the (string) data in that resource. To do so it understands certain
-// special chars starting with FF. The reason for this function is that
-// sometimes resource data will contain 0 bytes, thus we can't just use strlen.
-//
-int resStrLen(const char *src)
-{
- int num = 0;
- byte chr;
- while ((chr = *src++) != 0) {
- num++;
- if (chr == 255) {
- chr = *src++;
- num++;
-
- if (chr != 1 && chr != 2 && chr != 3 && chr != 8) {
- src += 2;
- num += 2;
- }
- }
- }
- return num;
-}
-
RandomSource::RandomSource(uint32 seed)
{
_randSeed = seed;
diff --git a/common/util.h b/common/util.h
index 3be8c556e0..ee03684410 100644
--- a/common/util.h
+++ b/common/util.h
@@ -47,10 +47,6 @@ void ClearBlendCache(byte *palette, int weight);
*/
void hexdump(const byte * data, int len);
-// Resource string length
-int resStrLen(const char *src);
-
-
class RandomSource {
private:
uint32 _randSeed;
diff --git a/scumm/resource.cpp b/scumm/resource.cpp
index 80433ba2ca..e2d4d77692 100644
--- a/scumm/resource.cpp
+++ b/scumm/resource.cpp
@@ -1477,7 +1477,7 @@ void Scumm::loadPtrToResource(int type, int resindex, byte *source)
nukeResource(type, resindex);
- len = getStringLen(source);
+ len = resStrLen(source) + 1;
if (len <= 0)
return;
diff --git a/scumm/script.cpp b/scumm/script.cpp
index 3f5d5edd9b..81e3d14501 100644
--- a/scumm/script.cpp
+++ b/scumm/script.cpp
@@ -1097,33 +1097,43 @@ int Scumm::getArrayId()
return -1;
}
-void Scumm::copyString(byte *dst, byte *src, int len)
+void Scumm::copyScriptString(byte *dst)
{
- if (!src) {
- while (--len >= 0)
- *dst++ = fetchScriptByte();
- } else {
- while (--len >= 0)
- *dst++ = *src++;
- }
+ int len = resStrLen(_scriptPointer) + 1;
+ while (len--)
+ *dst++ = fetchScriptByte();
}
-int Scumm::getStringLen(byte *ptr)
+//
+// Given a pointer to a Scumm string, this function returns the total byte length
+// of the string data in that resource. To do so it has to understand certain
+// special characters embedded into the string. The reason for this function is that
+// sometimes this embedded data contains zero bytes, thus we can't just use strlen.
+//
+int Scumm::resStrLen(const byte *src) const
{
- int len;
- byte c;
- if (!ptr)
- ptr = _scriptPointer;
- len = 0;
- do {
- c = *ptr++;
- if (!c)
- break;
- len++;
- if (c == 0xFF)
- ptr += 3, len += 3;
- } while (1);
- return len + 1;
+ int num = 0;
+ byte chr;
+ if (src == NULL)
+ src = _scriptPointer;
+ while ((chr = *src++) != 0) {
+ num++;
+ if (chr == 255) {
+ chr = *src++;
+ num++;
+
+ if (chr != 1 && chr != 2 && chr != 3 && chr != 8) {
+ if (_features & GF_AFTER_V8) {
+ src += 4;
+ num += 4;
+ } else {
+ src += 2;
+ num += 2;
+ }
+ }
+ }
+ }
+ return num;
}
void Scumm::exitCutscene()
diff --git a/scumm/script_v5.cpp b/scumm/script_v5.cpp
index f624eec045..6310f058f5 100644
--- a/scumm/script_v5.cpp
+++ b/scumm/script_v5.cpp
@@ -1827,7 +1827,7 @@ void Scumm_v5::o5_roomOps()
if (out) {
byte *ptr;
ptr = getResourceAddress(rtString, a);
- fwrite(ptr, getStringLen(ptr) + 1, 1, out);
+ fwrite(ptr, resStrLen(ptr) + 1, 1, out);
fclose(out);
}
break;
diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp
index 3271cf10d7..52508edc15 100644
--- a/scumm/script_v6.cpp
+++ b/scumm/script_v6.cpp
@@ -1952,54 +1952,46 @@ void Scumm_v6::o6_getVerbEntrypoint()
push(getVerbEntrypoint(v, e));
}
-void Scumm::arrayop_1(int a, byte *ptr)
-{
- ArrayHeader *ah;
- int r;
- int len = getStringLen(ptr);
-
- r = defineArray(a, 4, 0, len);
- ah = (ArrayHeader *)getResourceAddress(rtString, r);
- copyString(ah->data, ptr, len);
-}
-
void Scumm_v6::o6_arrayOps()
{
- int a, b, c, d, num;
+ byte subOp = fetchScriptByte();
+ int array = fetchScriptWord();
+ int b, c, d, len;
+ ArrayHeader *ah;
int list[128];
- switch (fetchScriptByte()) {
+ switch (subOp) {
case 205:
- a = fetchScriptWord();
- pop();
- arrayop_1(a, NULL);
+ b = pop();
+ len = resStrLen(_scriptPointer);
+ c = defineArray(array, 4, 0, len + 1);
+ ah = (ArrayHeader *)getResourceAddress(rtString, c);
+ copyScriptString(ah->data + b);
break;
case 208:
- a = fetchScriptWord();
b = pop();
c = pop();
- d = readVar(a);
+ d = readVar(array);
if (d == 0) {
- defineArray(a, 5, 0, b + c);
+ defineArray(array, 5, 0, b + c);
}
while (c--) {
- writeArray(a, 0, b + c, pop());
+ writeArray(array, 0, b + c, pop());
}
break;
case 212:
- a = fetchScriptWord();
b = pop();
- num = getStackList(list, sizeof(list) / sizeof(list[0]));
- d = readVar(a);
+ len = getStackList(list, sizeof(list) / sizeof(list[0]));
+ d = readVar(array);
if (d == 0)
error("Must DIM a two dimensional array before assigning");
c = pop();
- while (--num >= 0) {
- writeArray(a, c, b + num, list[num]);
+ while (--len >= 0) {
+ writeArray(array, c, b + len, list[len]);
}
break;
default:
- error("o6_arrayOps: default case");
+ error("o6_arrayOps: default case %d (array %d)", subOp, array);
}
}
@@ -2015,7 +2007,6 @@ void Scumm_v6::o6_saveRestoreVerbs()
byte subOp = fetchScriptByte();
if (_features & GF_AFTER_V8) {
subOp = (subOp - 141) + 0xB4;
- printf("o8_saveRestoreVerbs:%d\n", (int)subOp);
}
switch (subOp) {
@@ -2112,7 +2103,6 @@ void Scumm_v6::o6_wait()
return;
case 171:
- printf("wait for sentence");
if (_sentenceNum) {
if (_sentence[_sentenceNum - 1].freezeCount && !isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]))
return;
@@ -2290,8 +2280,9 @@ void Scumm_v6::o6_talkActor()
char pointer[20];
int i, j;
- _scriptPointer += resStrLen((char*)_scriptPointer) + 1;
+ _scriptPointer += resStrLen(_scriptPointer) + 1;
translateText(_messagePtr, _transText);
+
for (i = 0, j = 0; (_messagePtr[i] != '/' || j == 0) && j < 19; i++) {
if (_messagePtr[i] != '/')
pointer[j++] = _messagePtr[i];
@@ -2934,7 +2925,7 @@ void Scumm_v6::decodeParseString(int m, int n)
char pointer[20];
int i, j;
- _scriptPointer += resStrLen((char*)_scriptPointer)+ 1;
+ _scriptPointer += resStrLen(_scriptPointer)+ 1;
translateText(_messagePtr, _transText);
for (i = 0, j = 0; (_messagePtr[i] != '/' || j == 0) && j < 19; i++) {
if (_messagePtr[i] != '/')
diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp
index 53015d6361..f8df08dd34 100644
--- a/scumm/script_v8.cpp
+++ b/scumm/script_v8.cpp
@@ -512,16 +512,14 @@ void Scumm_v8::decodeParseString(int m, int n)
case 0xD0: // SO_PRINT_MUMBLE
error("decodeParseString: SO_PRINT_MUMBLE");
break;
- case 0xD1: {
-
-#if 1
+ case 0xD1:
_messagePtr = _scriptPointer;
if (_messagePtr[0] == '/') {
char pointer[20];
int i, j;
- _scriptPointer += resStrLen((char*)_scriptPointer)+ 1;
+ _scriptPointer += resStrLen(_scriptPointer) + 1;
translateText(_messagePtr, _transText);
for (i = 0, j = 0; (_messagePtr[i] != '/' || j == 0) && j < 19; i++) {
if (_messagePtr[i] != '/')
@@ -569,61 +567,7 @@ void Scumm_v8::decodeParseString(int m, int n)
_scriptPointer = _messagePtr;
return;
}
-#else
- char buffer[1024];
- _messagePtr = _scriptPointer;
-
- if (_messagePtr[0] == '/') {
- char pointer[20];
- int i, j;
-
- // Skip over the string
- _scriptPointer += resStrLen((char*)_scriptPointer) + 1;
-
- translateText(_messagePtr, _transText);
- for (i = 0, j = 0; (_messagePtr[i] != '/' || j == 0) && j < 19; i++) {
- if (_messagePtr[i] != '/')
- pointer[j++] = _messagePtr[i];
- }
- pointer[j] = 0;
-
- // Stop any talking that's still going on
- if (_sound->_talkChannel > -1)
- _mixer->stop(_sound->_talkChannel);
-
- // FIXME: no 'digvoice.bun' in COMI
- _sound->_talkChannel = _sound->playBundleSound(pointer);
-
- _messagePtr = _transText;
- _msgPtrToAdd = (byte *)buffer;
- _messagePtr = addMessageToStack(_messagePtr);
- } else {
- _msgPtrToAdd = (byte *)buffer;
- _scriptPointer = _messagePtr = addMessageToStack(_messagePtr);
- }
-
- if (_fr[_string[m].charset] == NULL) // FIXME: Put this elsewhere?
- loadCharset(_string[m].charset);
-
- if (_fr[_string[m].charset] != NULL) {
- int x = _string[m].xpos;
- // HACK - center mode. I call this a hack because we really should
- // not duplicate all the string code from string.cpp. Rather, maybe
- // abstract away the code in string.cpp from using the 'charset'
- // fonts, and allow it to work both with old and new fonts. To this
- // end, we should seperate the parts of Charset/_charset which are
- // for bookkeeping (like x_pos, center mode etc.) and those that are
- // for rendering. Then let the old (think printCharOld), medium (printChar),
- // new (NUT) style renderers be subclasses of a common base class (which
- // defines the API). This will clean up the code, and allow us to reuse
- // the string logic in string.cpp.
- if (_string[m].center)
- x -= _fr[_string[m].charset]->getStringWidth(buffer) / 2;
- _fr[_string[m].charset]->drawString(buffer, x, _string[m].ypos, _string[m].color, 0);
- }
-#endif
break;
- }
case 0xD2: // SO_PRINT_WRAP Set print wordwrap
error("decodeParseString: SO_PRINT_MUMBLE");
break;
@@ -746,23 +690,18 @@ void Scumm_v8::o8_arrayOps()
byte subOp = fetchScriptByte();
int array = fetchScriptWord();
int b, c, d, len;
+ ArrayHeader *ah;
int list[128];
switch (subOp) {
case 0x14: // SO_ASSIGN_STRING
- {
- int idx = pop();
- ArrayHeader *ah;
- int r;
- len = getStringLen(NULL);
-
- r = defineArray(array, 4, 0, len);
- ah = (ArrayHeader *)getResourceAddress(rtString, r);
- copyString(ah->data + idx, NULL, len);
- }
+ b = pop();
+ len = resStrLen(_scriptPointer);
+ c = defineArray(array, 4, 0, len + 1);
+ ah = (ArrayHeader *)getResourceAddress(rtString, c);
+ copyScriptString(ah->data + b);
break;
case 0x15: // SO_ASSIGN_SCUMMVAR_LIST
- // TODO / FIXME: is this right?
b = pop();
c = pop();
d = readVar(array);
@@ -774,7 +713,6 @@ void Scumm_v8::o8_arrayOps()
}
break;
case 0x16: // SO_ASSIGN_2DIM_LIST
- // TODO / FIXME: is this right?
b = pop();
len = getStackList(list, sizeof(list) / sizeof(list[0]));
d = readVar(array);
@@ -1333,7 +1271,7 @@ void Scumm_v8::o8_system()
void Scumm_v8::o8_startVideo()
{
- int len = resStrLen((char*)_scriptPointer);
+ int len = resStrLen(_scriptPointer);
warning("o8_startVideo(%s/%s)", getGameDataPath(), (char*)_scriptPointer);
@@ -1528,7 +1466,7 @@ void Scumm_v8::o8_getObjectImageHeight()
void Scumm_v8::o8_getStringWidth()
{
int charset = pop();
- int len = resStrLen((char*)_scriptPointer);
+ int len = resStrLen(_scriptPointer);
int oldID = _charset->getCurID();
int width;
diff --git a/scumm/scumm.h b/scumm/scumm.h
index 00956710d3..4692e5dbb4 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -457,7 +457,6 @@ public:
virtual void writeVar(uint var, int value);
void runHook(int i);
bool isScriptInUse(int script);
- int getStringLen(byte *ptr);
void freezeScripts(int scr);
void unfreezeScripts();
@@ -476,8 +475,8 @@ public:
void decreaseScriptDelay(int amount);
bool isScriptRunning(int script);
bool isRoomScriptRunning(int script);
- void arrayop_1(int a, byte *ptr);
- void copyString(byte *dst, byte *src, int len);
+ void copyScriptString(byte *dst);
+ int resStrLen(const byte *src) const;
void doSentence(int c, int b, int a);
void setStringVars(int i);
diff --git a/scumm/string.cpp b/scumm/string.cpp
index 2964960445..75b31e8ffd 100644
--- a/scumm/string.cpp
+++ b/scumm/string.cpp
@@ -494,7 +494,7 @@ void Scumm::drawString(int a)
}
for (i = 0; (chr = buf[i++]) != 0;) {
- if (chr == 254 || chr == 255) {
+ if (chr == 0xFE || chr == 0xFF) {
chr = buf[i++];
switch (chr) {
case 9:
@@ -650,6 +650,11 @@ byte *Scumm::addMessageToStack(byte *msg)
*_msgPtrToAdd++ = chr;
*_msgPtrToAdd++ = ptr[num++];
*_msgPtrToAdd++ = ptr[num++];
+ if (_features & GF_AFTER_V8) {
+ // FIXME - is this right?!?
+ *_msgPtrToAdd++ = ptr[num++];
+ *_msgPtrToAdd++ = ptr[num++];
+ }
break;
default:
debug(2, "addMessageToStack(): string escape sequence %d unknown", chr);
@@ -808,11 +813,11 @@ void Scumm::translateText(byte *text, byte *trans_buff) {
// skip translation if flag 'h' exist
if (*(buf + pos) == 'h') {
pos += 3;
- char *pointer = strchr((char*)text + 1, '/');
+ byte *pointer = (byte *)strchr((char*)text + 1, '/');
if (pointer != NULL)
- strcpy((char *)trans_buff, pointer + 1);
+ memcpy(trans_buff, pointer + 1, resStrLen(pointer + 1) + 1);
else
- strcpy((char *)trans_buff, "");
+ trans_buff[0] = '\0';
return;
}
@@ -868,14 +873,14 @@ void Scumm::translateText(byte *text, byte *trans_buff) {
}
if (text[0] == '/') {
- char *pointer = strchr((char*)text + 1, '/');
+ byte *pointer = (byte *)strchr((char*)text + 1, '/');
if (pointer != NULL)
- strcpy((char *)trans_buff, pointer + 1);
+ memcpy(trans_buff, pointer + 1, resStrLen(pointer + 1) + 1);
else
- strcpy((char *)trans_buff, "");
-
+ trans_buff[0] = '\0';
return;
}
- strcpy((char *)trans_buff, (char *)text);
+
+ memcpy(trans_buff, text, resStrLen(text) + 1);
}