diff --git a/scumm/actor.cpp b/scumm/actor.cpp index 0422f11b734..d78536cc6ce 100644 --- a/scumm/actor.cpp +++ b/scumm/actor.cpp @@ -1096,9 +1096,9 @@ void Scumm::actorTalk() int oldact; Actor *a; - _msgPtrToAdd = _charset->_buffer; + _msgPtrToAdd = _charsetBuffer; _messagePtr = addMessageToStack(_messagePtr); - assert((int)(_msgPtrToAdd - _charset->_buffer) < (int)(sizeof(_charset->_buffer))); + assert((int)(_msgPtrToAdd - _charsetBuffer) < (int)(sizeof(_charsetBuffer))); if (_actorToPrintStrFor == 0xFF) { if (!_keepText) @@ -1129,7 +1129,7 @@ void Scumm::actorTalk() a = derefActorSafe(_vars[VAR_TALK_ACTOR], "actorTalk(2)"); _charsetColor = a->talkColor; } - _charset->_bufPos = 0; + _charsetBufPos = 0; _talkDelay = 0; _haveMsg = 0xFF; _vars[VAR_HAVE_MSG] = 0xFF; diff --git a/scumm/charset.cpp b/scumm/charset.cpp index 8efd33ad47c..c1989832fb6 100644 --- a/scumm/charset.cpp +++ b/scumm/charset.cpp @@ -22,45 +22,43 @@ #include "charset.h" #include "scumm.h" -void CharsetRenderer::setCurID(byte id) { - _curId = id; - _fontPtr = getFontPtr(id); -} - -byte *CharsetRenderer::getFontPtr(byte id) +void CharsetRendererCommon::setCurID(byte id) { - byte *ptr = _vm->getResourceAddress(rtCharset, id); - assert(ptr); + _vm->checkRange(_vm->_maxCharsets - 1, 0, _curId, "Printing with bad charset %d"); + + _curId = id; + + _fontPtr = _vm->getResourceAddress(rtCharset, id); + assert(_fontPtr); if (_vm->_features & GF_SMALL_HEADER) - ptr += 17; + _fontPtr += 17; else - ptr += 29; - return ptr; + _fontPtr += 29; } // do spacing for variable width old-style font -int CharsetRendererClassic::getSpacing(byte chr, byte *charset) +int CharsetRendererClassic::getCharWidth(byte chr) { int spacing = 0; - int offs = READ_LE_UINT32(charset + chr * 4 + 4); + int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); if (offs) { - spacing = charset[offs]; - if (charset[offs + 2] >= 0x80) { - spacing += charset[offs + 2] - 0x100; + spacing = _fontPtr[offs]; + if (_fontPtr[offs + 2] >= 0x80) { + spacing += _fontPtr[offs + 2] - 0x100; } else { - spacing += charset[offs + 2]; + spacing += _fontPtr[offs + 2]; } } return spacing; } -int CharsetRendererOld256::getSpacing(byte chr, byte *charset) +int CharsetRendererOld256::getCharWidth(byte chr) { int spacing = 0; - spacing = *(charset - 11 + chr); + spacing = *(_fontPtr - 11 + chr); // FIXME - this fixes the inventory icons in Zak256/Indy3 // see bug #613109. @@ -75,12 +73,9 @@ int CharsetRendererOld256::getSpacing(byte chr, byte *charset) int CharsetRenderer::getStringWidth(int arg, byte *text) { int pos = 0; - byte *ptr; - int width; + int width = 1; byte chr; - - width = 1; - ptr = _fontPtr; + int oldID = getCurID(); while ((chr = text[pos++]) != 0) { if (chr == 0xD) @@ -107,13 +102,15 @@ int CharsetRenderer::getStringWidth(int arg, byte *text) if (chr == 14) { int set = text[pos] | (text[pos + 1] << 8); pos += 2; - ptr = getFontPtr(set); + setCurID(set); continue; } } - width += getSpacing(chr, ptr); + width += getCharWidth(chr); } + setCurID(oldID); + return width; } @@ -121,10 +118,8 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) { int lastspace = -1; int curw = 1; - byte *ptr; byte chr; - - ptr = _fontPtr; + int oldID = getCurID(); while ((chr = str[pos++]) != 0) { if (chr == '@') @@ -157,7 +152,7 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) if (chr == 14) { int set = str[pos] | (str[pos + 1] << 8); pos += 2; - ptr = getFontPtr(set); + setCurID(set); continue; } } @@ -165,7 +160,7 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) if (chr == ' ') lastspace = pos - 1; - curw += getSpacing(chr, ptr); + curw += getCharWidth(chr); if (lastspace == -1) continue; if (curw > maxwidth) { @@ -175,6 +170,8 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) lastspace = -1; } } + + setCurID(oldID); } @@ -217,7 +214,7 @@ void CharsetRendererOld256::printChar(int chr) } // FIXME - _left += getSpacing(chr, _fontPtr); + _left += getCharWidth(chr); if (_left > _strRight) _strRight = _left; @@ -244,7 +241,7 @@ void CharsetRendererClassic::printChar(int chr) return; _bpp = *_fontPtr; - _colorMap[1] = _color; + _vm->_charsetColorMap[1] = _color; uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); @@ -372,7 +369,7 @@ void CharsetRendererClassic::drawBits(VirtScreen *vs, byte *dst, byte *mask, int if (useMask) { mask[maskpos] |= maskmask; } - *dst = _colorMap[color]; + *dst = _vm->_charsetColorMap[color]; } dst++; bits <<= _bpp; diff --git a/scumm/charset.h b/scumm/charset.h index 98388fd4719..15dc8ef4af6 100644 --- a/scumm/charset.h +++ b/scumm/charset.h @@ -36,7 +36,6 @@ public: int _right; byte _color; - byte _colorMap[16]; bool _center; bool _hasMask; @@ -45,58 +44,80 @@ public: bool _firstChar; bool _disableOffsX; - int _bufPos; - byte _buffer[512]; // TODO - would be really nice to get rid of this - protected: Scumm *_vm; - byte _curId; - byte *_fontPtr; - - byte *getFontPtr(byte id); - - virtual int getSpacing(byte chr, byte *charset) = 0; + virtual int getCharWidth(byte chr) = 0; public: CharsetRenderer(Scumm *vm) : _vm(vm) {} + virtual ~CharsetRenderer() {} virtual void printChar(int chr) = 0; int getStringWidth(int a, byte *str); void addLinebreaks(int a, byte *str, int pos, int maxwidth); + virtual void setCurID(byte id) = 0; + virtual int getCurID() = 0; + + virtual int getFontHeight() = 0; +}; + + +class CharsetRendererCommon : public CharsetRenderer { +protected: + byte _curId; + byte *_fontPtr; + +public: + CharsetRendererCommon(Scumm *vm) : CharsetRenderer(vm) {} + void setCurID(byte id); int getCurID() { return _curId; } int getFontHeight() { return _fontPtr[1]; } }; - -class CharsetRendererClassic : public CharsetRenderer { +class CharsetRendererClassic : public CharsetRendererCommon { protected: byte _bpp; byte *_charPtr; - int getSpacing(byte chr, byte *charset); + int getCharWidth(byte chr); void drawBits(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height); public: - CharsetRendererClassic(Scumm *vm) : CharsetRenderer(vm) {} + CharsetRendererClassic(Scumm *vm) : CharsetRendererCommon(vm) {} void printChar(int chr); }; -class CharsetRendererOld256 : public CharsetRenderer { +class CharsetRendererOld256 : public CharsetRendererCommon { protected: - int getSpacing(byte chr, byte *charset); + int getCharWidth(byte chr); public: - CharsetRendererOld256(Scumm *vm) : CharsetRenderer(vm) {} + CharsetRendererOld256(Scumm *vm) : CharsetRendererCommon(vm) {} void printChar(int chr); }; +/* +class CharsetRendererNUT : public CharsetRenderer { +protected: + int getCharWidth(byte chr); + + NutRenderer *_fr[4]; + +public: + CharsetRendererNUT(Scumm *vm) : CharsetRenderer(vm) {} + + void printChar(int chr); + + void setCurID(byte id); +}; +*/ #endif diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp index 965ea2958f1..ac00617a0ec 100644 --- a/scumm/saveload.cpp +++ b/scumm/saveload.cpp @@ -359,7 +359,7 @@ void Scumm::saveOrLoad(Serializer *s, uint32 savegameVersion) MKARRAY(Scumm, vm.localvar[0][0], sleUint16, NUM_SCRIPT_SLOT * 17, VER_V9), MKARRAY(Scumm, _resourceMapper[0], sleByte, 128, VER_V8), - MKARRAY(Scumm, _charset->_colorMap[0], sleByte, 16, VER_V8), + MKARRAY(Scumm, _charsetColorMap[0], sleByte, 16, VER_V8), // _charsetData grew from 10*16 to 15*16 bytes MKARRAY_OLD(Scumm, _charsetData[0][0], sleByte, 10 * 16, VER_V8, VER_V9), @@ -386,9 +386,9 @@ void Scumm::saveOrLoad(Serializer *s, uint32 savegameVersion) MKLINE(Scumm, _actorToPrintStrFor, sleByte, VER_V8), MKLINE(Scumm, _charsetColor, sleByte, VER_V8), - // charset._bufPos was changed from byte to int - MKLINE_OLD(Scumm, _charset->_bufPos, sleByte, VER_V8, VER_V9), - MKLINE(Scumm, _charset->_bufPos, sleInt16, VER_V10), + // _charsetBufPos was changed from byte to int + MKLINE_OLD(Scumm, _charsetBufPos, sleByte, VER_V8, VER_V9), + MKLINE(Scumm, _charsetBufPos, sleInt16, VER_V10), MKLINE(Scumm, _haveMsg, sleByte, VER_V8), MKLINE(Scumm, _useTalkAnims, sleByte, VER_V8), @@ -430,7 +430,7 @@ void Scumm::saveOrLoad(Serializer *s, uint32 savegameVersion) MKARRAY(Scumm, _proc_special_palette[0], sleByte, 256, VER_V8), - MKARRAY(Scumm, _charset->_buffer[0], sleByte, 256, VER_V8), + MKARRAY(Scumm, _charsetBuffer[0], sleByte, 256, VER_V8), MKLINE(Scumm, _egoPositioned, sleByte, VER_V8), diff --git a/scumm/script_v5.cpp b/scumm/script_v5.cpp index f98d57f0a8f..1f2afdd98fc 100644 --- a/scumm/script_v5.cpp +++ b/scumm/script_v5.cpp @@ -656,7 +656,7 @@ void Scumm_v5::o5_cursorCommand() case 14: /* unk */ getWordVararg(table); for (i = 0; i < 16; i++) - _charset->_colorMap[i] = _charsetData[_string[1].t_charset][i] = (unsigned char)table[i]; + _charsetColorMap[i] = _charsetData[_string[1].t_charset][i] = (unsigned char)table[i]; break; } diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp index f27c6fe18e6..088277ccd54 100644 --- a/scumm/script_v6.cpp +++ b/scumm/script_v6.cpp @@ -864,7 +864,7 @@ void Scumm_v6::o6_cursorCommand() case 0x9D: /* set charset colors */ getStackList(args, sizeof(args) / sizeof(args[0])); for (i = 0; i < 16; i++) - _charset->_colorMap[i] = _charsetData[_string[1].t_charset][i] = (unsigned char)args[i]; + _charsetColorMap[i] = _charsetData[_string[1].t_charset][i] = (unsigned char)args[i]; break; case 0xD6: makeCursorColorTransparent(pop()); @@ -2582,10 +2582,10 @@ void Scumm_v6::o6_miscOps() setStringVars(0); addMessageToStack(getStringAddressVar(VAR_STRING2DRAW)); if (strncmp("/SYSTEM.007/ /", (char *)buf, 14) == 0) { - translateText(buf + 13, _charset->_buffer); + translateText(buf + 13, _charsetBuffer); //description(); } else if (strncmp("/SYSTEM.007/ ", (char *)buf, 13) == 0) { - strcpy((char *)_charset->_buffer, (char *)buf + 13); + strcpy((char *)_charsetBuffer, (char *)buf + 13); //description(); } } else { diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp index 6a215189d1c..c4b56256a61 100644 --- a/scumm/script_v8.cpp +++ b/scumm/script_v8.cpp @@ -795,7 +795,7 @@ void Scumm_v8::o8_cursorCommand() case 0xE8: // SO_CHARSET_COLOR getStackList(args, sizeof(args) / sizeof(args[0])); for (i = 0; i < 16; i++) - _charset->_colorMap[i] = _charsetData[_string[1].t_charset][i] = (unsigned char)args[i]; + _charsetColorMap[i] = _charsetData[_string[1].t_charset][i] = (unsigned char)args[i]; break; case 0xE9: // SO_CURSOR_PUT default: diff --git a/scumm/scumm.h b/scumm/scumm.h index 04440e913af..25a3ccf046a 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -858,9 +858,14 @@ public: /* String class */ CharsetRenderer *_charset; byte _charsetColor; - bool _noSubtitles; // Skip all subtitles? + byte _charsetColorMap[16]; byte _charsetData[15][16]; + int _charsetBufPos; + byte _charsetBuffer[512]; + + bool _noSubtitles; // Skip all subtitles? + void initCharset(int charset); void restoreCharsetBg(); int hasCharsetMask(int x, int y, int x2, int y2); diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index 1e9efbbd5b8..3c3c76ba188 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -289,7 +289,7 @@ void Scumm::scummInit() _numObjectsInRoom = 0; _actorToPrintStrFor = 0; - _charset->_bufPos = 0; + _charsetBufPos = 0; _haveMsg = 0; _varwatch = -1; diff --git a/scumm/string.cpp b/scumm/string.cpp index ece823c75d9..c7ea18e67e0 100644 --- a/scumm/string.cpp +++ b/scumm/string.cpp @@ -146,7 +146,7 @@ void Scumm::CHARSET_1() if (!(_features & GF_OLD256)) // FIXME for (i = 0; i < 4; i++) - _charset->_colorMap[i] = _charsetData[_charset->getCurID()][i]; + _charsetColorMap[i] = _charsetData[_charset->getCurID()][i]; if (_keepText) { _charset->_strLeft = gdi._mask_left; @@ -199,7 +199,7 @@ void Scumm::CHARSET_1() t <<= 1; } - buffer = _charset->_buffer + _charset->_bufPos; + buffer = _charsetBuffer + _charsetBufPos; _charset->addLinebreaks(0, buffer, 0, t); if (_charset->_center) { @@ -304,7 +304,7 @@ void Scumm::CHARSET_1() _charset->setCurID(*buffer++); buffer += 2; for (i = 0; i < 4; i++) - _charset->_colorMap[i] = _charsetData[_charset->getCurID()][i]; + _charsetColorMap[i] = _charsetData[_charset->getCurID()][i]; _charset->_nextTop -= _charset->getFontHeight() - oldy; break; } @@ -326,7 +326,7 @@ void Scumm::CHARSET_1() if (a && has_anim) a->startAnimActor(frme != -1 ? frme : a->talkFrame1); - _charset->_bufPos = buffer - _charset->_buffer; + _charsetBufPos = buffer - _charsetBuffer; gdi._mask_left = _charset->_strLeft; gdi._mask_right = _charset->_strRight; @@ -339,13 +339,13 @@ void Scumm::description() int c; byte *buffer; - buffer = _charset->_buffer; + buffer = _charsetBuffer; _string[0].ypos = camera._cur.y + 88; _string[0].xpos = (_realWidth / 2) - (_charset->getStringWidth(0, buffer) >> 1); if (_string[0].xpos < 0) _string[0].xpos = 0; - _charset->_bufPos = 0; + _charsetBufPos = 0; _charset->_top = _string[0].ypos; _charset->_startLeft = _charset->_left = _string[0].xpos; _charset->_right = _realWidth - 1; @@ -390,7 +390,7 @@ void Scumm::drawDescString(byte *msg) buf = _msgPtrToAdd = buffer; addMessageToStack(msg); - _charset->_bufPos = 0; + _charsetBufPos = 0; _charset->_top = _string[0].ypos; _charset->_startLeft = _charset->_left = _string[0].xpos; _charset->_right = _realWidth - 1; @@ -453,7 +453,7 @@ void Scumm::drawString(int a) if (!(_features & GF_OLD256)) { for (i = 0; i < 4; i++) - _charset->_colorMap[i] = _charsetData[_charset->getCurID()][i]; + _charsetColorMap[i] = _charsetData[_charset->getCurID()][i]; fontHeight = _charset->getFontHeight(); } @@ -752,7 +752,7 @@ void Scumm::initCharset(int charsetno) _string[1].t_charset = charsetno; for (i = 0; i < 16; i++) - _charset->_colorMap[i] = _charsetData[_charset->getCurID()][i]; + _charsetColorMap[i] = _charsetData[_charset->getCurID()][i]; } void Scumm::loadLanguageBundle() {