Skip to content

Commit

Permalink
KYRA: replace const char * with Common::String around getTableString.
Browse files Browse the repository at this point in the history
Currently const char * points into some random buffer with unclear
lifetime.

Instead use Common::String which ensures lifetime as long as a reference is
held.

This also removes the need of copying into existing buffers in HoF and MR.

UnkBuf* are gone as well.
  • Loading branch information
phcoder committed Nov 5, 2020
1 parent 3109f2f commit 7be26a9
Show file tree
Hide file tree
Showing 31 changed files with 204 additions and 187 deletions.
2 changes: 1 addition & 1 deletion engines/kyra/engine/items_mr.cpp
Expand Up @@ -117,7 +117,7 @@ bool KyraEngine_MR::dropItem(int unk1, Item item, int x, int y, int unk2) {
showMessageFromCCode(14, 0xB3, 0);
}

if (!_chatText)
if (_chatText.empty())
snd_playSoundEffect(13, 200);
return false;
}
Expand Down
102 changes: 43 additions & 59 deletions engines/kyra/engine/kyra_hof.cpp
Expand Up @@ -94,9 +94,7 @@ KyraEngine_HoF::KyraEngine_HoF(OSystem *system, const GameFlags &flags) : KyraEn
_dbgPass = 0;

_gamePlayBuffer = 0;
_unkBuf500Bytes = 0;
_inventorySaved = false;
_unkBuf200kByte = 0;
memset(&_sceneShapeTable, 0, sizeof(_sceneShapeTable));

_talkObjectList = 0;
Expand Down Expand Up @@ -287,15 +285,13 @@ void KyraEngine_HoF::startup() {

memset(_sceneShapeTable, 0, sizeof(_sceneShapeTable));
_gamePlayBuffer = new uint8[46080];
_unkBuf500Bytes = new uint8[500];

loadMouseShapes();
loadItemShapes();

_screen->setMouseCursor(0, 0, getShapePtr(0));

_screenBuffer = new uint8[64000];
_unkBuf200kByte = new uint8[200000];

loadChapterBuffer(_newChapterFile);

Expand All @@ -313,7 +309,7 @@ void KyraEngine_HoF::startup() {
_optionsBuffer = _cCodeBuffer;
}

showMessage(0, 207);
clearMessage();

_screen->setShapePages(5, 3);

Expand Down Expand Up @@ -621,7 +617,7 @@ void KyraEngine_HoF::updateWithText() {
restorePage3();
drawAnimObjects();

if (_chatTextEnabled && _chatText) {
if (_chatTextEnabled && !_chatText.empty()) {
int pageBackUp = _screen->_curPage;
_screen->_curPage = 2;
objectChatPrintText(_chatText, _chatObject);
Expand Down Expand Up @@ -741,8 +737,6 @@ void KyraEngine_HoF::cleanup() {
delete[] _inventoryButtons; _inventoryButtons = 0;

delete[] _gamePlayBuffer; _gamePlayBuffer = 0;
delete[] _unkBuf500Bytes; _unkBuf500Bytes = 0;
delete[] _unkBuf200kByte; _unkBuf200kByte = 0;

freeSceneShapePtrs();

Expand Down Expand Up @@ -821,19 +815,17 @@ uint8 *KyraEngine_HoF::getTableEntry(uint8 *buffer, int id) {
return buffer + READ_LE_UINT16(buffer + (id<<1));
}

char *KyraEngine_HoF::getTableString(int id, uint8 *buffer, bool decode) {
char *string = (char *)getTableEntry(buffer, id);
Common::String KyraEngine_HoF::getTableString(int id, uint8 *buffer, bool decode) {
Common::String string((char *)getTableEntry(buffer, id));

if (decode && _flags.lang != Common::JA_JPN) {
Util::decodeString1(string, _internStringBuf);
Util::decodeString2(_internStringBuf, _internStringBuf);
string = _internStringBuf;
string = Util::decodeString2(Util::decodeString1(string));
}

return string;
}

const char *KyraEngine_HoF::getChapterString(int id) {
Common::String KyraEngine_HoF::getChapterString(int id) {
if (_currentChapter != _newChapterFile)
loadChapterBuffer(_newChapterFile);

Expand All @@ -843,15 +835,14 @@ const char *KyraEngine_HoF::getChapterString(int id) {
#pragma mark -

void KyraEngine_HoF::showMessageFromCCode(int id, int16 palIndex, int) {
const char *string = getTableString(id, _cCodeBuffer, true);
showMessage(string, palIndex);
showMessage(getTableString(id, _cCodeBuffer, true), palIndex);
}

void KyraEngine_HoF::showMessage(const char *string, int16 palIndex) {
void KyraEngine_HoF::showMessage(const Common::String &string, int16 palIndex) {
_shownMessage = string;
_screen->fillRect(0, 190, 319, 199, 0xCF);

if (string) {
if (!string.empty()) {
if (palIndex != -1 || _fadeMessagePalette) {
palIndex *= 3;
memcpy(_messagePal, _screen->getPalette(0).getData() + palIndex, 3);
Expand All @@ -868,32 +859,34 @@ void KyraEngine_HoF::showMessage(const char *string, int16 palIndex) {
_fadeMessagePalette = false;
}

void KyraEngine_HoF::clearMessage() {
_shownMessage = "";
_screen->fillRect(0, 190, 319, 199, 0xCF);
_fadeMessagePalette = false;
}

void KyraEngine_HoF::showChapterMessage(int id, int16 palIndex) {
showMessage(getChapterString(id), palIndex);
}

void KyraEngine_HoF::updateCommandLineEx(int str1, int str2, int16 palIndex) {
char buffer[0x51];
char *src = buffer;

strcpy(src, getTableString(str1, _cCodeBuffer, true));

if (_flags.lang != Common::JA_JPN) {
while (*src != 0x20)
++src;
++src;
*src = toupper(*src);
}

strcpy((char *)_unkBuf500Bytes, src);

if (str2 > 0) {
if (_flags.lang != Common::JA_JPN)
strcat((char *)_unkBuf500Bytes, " ");
strcat((char *)_unkBuf500Bytes, getTableString(str2, _cCodeBuffer, true));
}

showMessage((char *)_unkBuf500Bytes, palIndex);
Common::String str = getTableString(str1, _cCodeBuffer, true);

if (_flags.lang != Common::JA_JPN) {
uint i = 0;
while (str[i] != ' ')
++i;
++i;
str.setChar(toupper(str[i]), i);
}

if (str2 > 0) {
if (_flags.lang != Common::JA_JPN)
str += " ";
str += getTableString(str2, _cCodeBuffer, 1);
}

showMessage(str, palIndex);
}

void KyraEngine_HoF::fadeMessagePalette() {
Expand Down Expand Up @@ -1771,7 +1764,7 @@ bool KyraEngine_HoF::updateCauldron() {
}

if (cauldronState >= 0) {
showMessage(0, 0xCF);
clearMessage();
setCauldronState(cauldronState, true);
if (cauldronState == 7)
objectChat(getTableString(0xF2, _cCodeBuffer, true), 0, 0x83, 0xF2);
Expand All @@ -1784,7 +1777,7 @@ bool KyraEngine_HoF::updateCauldron() {
}

void KyraEngine_HoF::cauldronRndPaletteFade() {
showMessage(0, 0xCF);
clearMessage();
int index = _rnd.getRandomNumberRng(0x0F, 0x16);
Common::SeekableReadStream *file = _res->createReadStream("_POTIONS.PAL");
if (!file)
Expand Down Expand Up @@ -1831,30 +1824,21 @@ void KyraEngine_HoF::listItemsInCauldron() {
} else {
objectChat(getTableString(0xF7, _cCodeBuffer, true), 0, 0x83, 0xF7);

char buffer[80];
for (int i = 0; i < itemsInCauldron-1; ++i) {
char *str = buffer;
strcpy(str, getTableString(_cauldronTable[i]+54, _cCodeBuffer, true));
Common::String str = getTableString(_cauldronTable[i]+54, _cCodeBuffer, true);
if (_lang == 1) {
if (*str == 37)
str += 2;
if (str[0] == 37)
str = str.substr(2);
}
strcpy((char *)_unkBuf500Bytes, "...");
strcat((char *)_unkBuf500Bytes, str);
strcat((char *)_unkBuf500Bytes, "...");
objectChat((const char *)_unkBuf500Bytes, 0, 0x83, _cauldronTable[i]+54);
objectChat("..." + str + "...", 0, 0x83, _cauldronTable[i]+54);
}

char *str = buffer;
strcpy(str, getTableString(_cauldronTable[itemsInCauldron-1]+54, _cCodeBuffer, true));
Common::String str = getTableString(_cauldronTable[itemsInCauldron-1]+54, _cCodeBuffer, true);
if (_lang == 1) {
if (*str == 37)
str += 2;
if (str[0] == 37)
str = str.substr(2);
}
strcpy((char *)_unkBuf500Bytes, "...");
strcat((char *)_unkBuf500Bytes, str);
strcat((char *)_unkBuf500Bytes, ".");
objectChat((const char *)_unkBuf500Bytes, 0, 0x83, _cauldronTable[itemsInCauldron-1]+54);
objectChat("..." + str + ".", 0, 0x83, _cauldronTable[itemsInCauldron-1]+54);
}
}

Expand Down Expand Up @@ -1905,7 +1889,7 @@ void KyraEngine_HoF::playTim(const char *filename) {
_tim->resetFinishedFlag();
while (!shouldQuit() && !_tim->finished()) {
_tim->exec(tim, 0);
if (_chatText)
if (!_chatText.empty())
updateWithText();
else
update();
Expand Down
22 changes: 10 additions & 12 deletions engines/kyra/engine/kyra_hof.h
Expand Up @@ -333,8 +333,8 @@ friend class GUI_HoF;
int _newChapterFile;

uint8 *getTableEntry(uint8 *buffer, int id);
char *getTableString(int id, uint8 *buffer, bool decode);
const char *getChapterString(int id);
Common::String getTableString(int id, uint8 *buffer, bool decode);
Common::String getChapterString(int id);

void changeFileExtension(char *buffer);

Expand Down Expand Up @@ -367,12 +367,13 @@ friend class GUI_HoF;

// text
void showMessageFromCCode(int id, int16 palIndex, int);
void showMessage(const char *string, int16 palIndex);
void showMessage(const Common::String &string, int16 palIndex);
void clearMessage();
void showChapterMessage(int id, int16 palIndex);

void updateCommandLineEx(int str1, int str2, int16 palIndex);

const char *_shownMessage;
Common::String _shownMessage;

byte _messagePal[3];
bool _fadeMessagePalette;
Expand All @@ -382,11 +383,11 @@ friend class GUI_HoF;
bool _chatIsNote;

int chatGetType(const char *text);
int chatCalcDuration(const char *text);
int chatCalcDuration(const Common::String &text);

void objectChat(const char *text, int object, int vocHigh = -1, int vocLow = -1);
void objectChatInit(const char *text, int object, int vocHigh = -1, int vocLow = -1);
void objectChatPrintText(const char *text, int object);
void objectChat(const Common::String &text, int object, int vocHigh = -1, int vocLow = -1);
void objectChatInit(const Common::String &text, int object, int vocHigh = -1, int vocLow = -1);
void objectChatPrintText(const Common::String &text, int object);
void objectChatProcess(const char *script);
void objectChatWaitToFinish();

Expand All @@ -397,7 +398,7 @@ friend class GUI_HoF;
void updateDlgBuffer();
void loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2);
void processDialogue(int dlgOffset, int vocH = 0, int csEntry = 0);
void npcChatSequence(const char *str, int objectId, int vocHigh = -1, int vocLow = -1);
void npcChatSequence(const Common::String &str, int objectId, int vocHigh = -1, int vocLow = -1);
void setDlgIndex(int dlgIndex) override;

int _npcTalkChpIndex;
Expand Down Expand Up @@ -615,9 +616,6 @@ friend class GUI_HoF;

EMCData _npcScriptData;

// pathfinder
uint8 *_unkBuf500Bytes;
uint8 *_unkBuf200kByte;
bool _chatAltFlag;

// sequence player
Expand Down
2 changes: 1 addition & 1 deletion engines/kyra/engine/kyra_mr.cpp
Expand Up @@ -1065,7 +1065,7 @@ void KyraEngine_MR::updateWithText() {

restorePage3();
drawAnimObjects();
if (_chatTextEnabled && _chatText) {
if (_chatTextEnabled && !_chatText.empty()) {
int curPage = _screen->_curPage;
_screen->_curPage = 2;
objectChatPrintText(_chatText, _chatObject);
Expand Down
2 changes: 1 addition & 1 deletion engines/kyra/engine/kyra_mr.h
Expand Up @@ -419,7 +419,7 @@ friend class GUI_MR;

void objectChat(const char *text, int object, int vocHigh, int vocLow);
void objectChatInit(const char *text, int object, int vocHigh, int vocLow);
void objectChatPrintText(const char *text, int object);
void objectChatPrintText(const Common::String &text, int object);
void objectChatProcess(const char *script);
void objectChatWaitToFinish();

Expand Down
4 changes: 2 additions & 2 deletions engines/kyra/engine/kyra_v2.cpp
Expand Up @@ -61,7 +61,7 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags, const Engi
_vocHigh = -1;
_chatVocHigh = -1;
_chatVocLow = -1;
_chatText = 0;
_chatText = "";
_chatObject = -1;
_chatTextEnabled = false;

Expand Down Expand Up @@ -150,7 +150,7 @@ void KyraEngine_v2::delay(uint32 amount, bool updateGame, bool isMainLoop) {
uint32 start = _system->getMillis();
do {
if (updateGame) {
if (_chatText)
if (!_chatText.empty())
updateWithText();
else
update();
Expand Down
2 changes: 1 addition & 1 deletion engines/kyra/engine/kyra_v2.h
Expand Up @@ -343,7 +343,7 @@ friend class GUI_v2;
// chat
int _vocHigh;

const char *_chatText;
Common::String _chatText;
int _chatObject;
uint32 _chatEndTime;
int _chatVocHigh, _chatVocLow;
Expand Down
2 changes: 1 addition & 1 deletion engines/kyra/engine/timer_hof.cpp
Expand Up @@ -37,7 +37,7 @@ void KyraEngine_HoF::setupTimers() {
}

void KyraEngine_HoF::timerFadeOutMessage(int arg) {
if (_shownMessage)
if (!_shownMessage.empty())
_fadeMessagePalette = 1;
}

Expand Down
22 changes: 22 additions & 0 deletions engines/kyra/engine/util.cpp
Expand Up @@ -113,6 +113,28 @@ void Util::convertISOToDOS(char &c) {
c = code;
}

Common::String Util::convertISOToDOS(const Common::String &str) {
char *tmp = new char[str.size() + 1];

memcpy(tmp, str.c_str(), str.size() + 1);
convertISOToDOS(tmp);
Common::String res = tmp;
delete[] tmp;
return res;
}

Common::String Util::decodeString1(const Common::String &src) {
char *tmp = new char[src.size() * 2 + 2];
Util::decodeString1(src.c_str(), tmp);
return tmp;
}

Common::String Util::decodeString2(const Common::String &src) {
char *tmp = new char[src.size() * 2 + 2];
Util::decodeString2(src.c_str(), tmp);
return tmp;
}

// CP850 to ISO-8859-1 (borrowed from engines/saga/font_map.cpp)
const uint8 Util::_charMapDOSToISO[128] = {
199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232,
Expand Down
5 changes: 5 additions & 0 deletions engines/kyra/engine/util.h
Expand Up @@ -24,19 +24,24 @@
#define KYRA_UTIL_H

#include "common/scummsys.h"
#include "common/str.h"

namespace Kyra {

class Util {
public:
static int decodeString1(const char *src, char *dst);
static void decodeString2(const char *src, char *dst);
static Common::String decodeString1(const Common::String &src);
static Common::String decodeString2(const Common::String &src);


// Since our current GUI font uses ISO-8859-1, this
// conversion functionallty uses that as a base.
static void convertDOSToISO(char *str);
static void convertISOToDOS(char *str);
static void convertISOToDOS(char &c);
static Common::String convertISOToDOS(const Common::String &str);

private:
static const uint8 _charMapDOSToISO[128];
Expand Down

0 comments on commit 7be26a9

Please sign in to comment.