diff options
-rw-r--r-- | common/util.cpp | 25 | ||||
-rw-r--r-- | common/util.h | 4 | ||||
-rw-r--r-- | scumm/resource.cpp | 2 | ||||
-rw-r--r-- | scumm/script.cpp | 56 | ||||
-rw-r--r-- | scumm/script_v5.cpp | 2 | ||||
-rw-r--r-- | scumm/script_v6.cpp | 51 | ||||
-rw-r--r-- | scumm/script_v8.cpp | 82 | ||||
-rw-r--r-- | scumm/scumm.h | 5 | ||||
-rw-r--r-- | scumm/string.cpp | 23 |
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); } |