CHEWY: More work on the text handling code

This commit is contained in:
Filippos Karapetis 2022-04-10 20:25:20 +03:00
parent 241b75774a
commit 34cb79817f
7 changed files with 65 additions and 27 deletions

View File

@ -442,6 +442,8 @@ void Atdsys::set_ats_mem(int16 mode) {
}
bool Atdsys::start_ats(int16 txtNr, int16 txtMode, int16 color, int16 mode, int16 *vocNr) {
assert(mode == ATS_DATA || mode == INV_USE_DATA || mode == INV_USE_DEF);
*vocNr = -1;
set_ats_mem(mode);
@ -451,7 +453,7 @@ bool Atdsys::start_ats(int16 txtNr, int16 txtMode, int16 color, int16 mode, int1
//const uint8 roomNum = _G(room)->_roomInfo->_roomNr;
int16 txt_anz;
_atsv._ptr = ats_get_txt(txtNr, txtMode, &txt_anz, mode);
//_atsv._ptr = (char *)getTextEntry(roomNum, txtNr, txtMode).c_str();
//Common::StringArray tmp = getTextArray(roomNum, txtNr, mode, txtMode);
if (_atsv._ptr) {
_atsv.shown = g_engine->_sound->subtitlesEnabled();
@ -567,6 +569,8 @@ void Atdsys::print_ats(int16 x, int16 y, int16 scrX, int16 scrY) {
char *Atdsys::ats_get_txt(int16 txtNr, int16 txtMode, int16 *retNr, int16 mode) {
char *str_ = nullptr;
assert(mode == ATS_DATA || mode == INV_USE_DATA || mode == INV_USE_DEF);
set_ats_mem(mode);
_atsv._txtMode = txtMode;
@ -1247,10 +1251,13 @@ void Atdsys::show_item(int16 diaNr, int16 blockNr, int16 itemNr) {
_dialogResource->setItemShown(diaNr, blockNr, itemNr, true);
}
int16 Atdsys::calc_inv_no_use(int16 curInv, int16 testNr, int16 mode) {
assert(mode <= 255 && testNr <= 65535);
int16 Atdsys::calc_inv_no_use(int16 curInv, int16 testNr) {
if (curInv != -1)
_invBlockNr = curInv + 1;
const uint32 key = (mode & 0xff) << 16 | testNr;
assert(curInv <= 255 && testNr <= 65535);
const uint32 key = (curInv & 0xff) << 16 | testNr;
return (_itemUseWithDesc.contains(key)) ? _itemUseWithDesc[key] : -1;
}
@ -1270,16 +1277,16 @@ uint32 Atdsys::getAtdsStreamSize() const {
return _dialogResource->getStreamSize();
}
Common::StringArray Atdsys::getTextArray(uint dialogNum, uint entryNum, int type) {
Common::StringArray Atdsys::getTextArray(uint dialogNum, uint entryNum, int type, int subEntry) {
if (!getControlBit(entryNum, ATS_ACTIVE_BIT))
return _text->getTextArray(dialogNum, entryNum, type);
return _text->getTextArray(dialogNum, entryNum, type, subEntry);
else
return Common::StringArray();
}
Common::String Atdsys::getTextEntry(uint dialogNum, uint entryNum, int type) {
Common::String Atdsys::getTextEntry(uint dialogNum, uint entryNum, int type, int subEntry) {
if (!getControlBit(entryNum, ATS_ACTIVE_BIT))
return _text->getTextEntry(dialogNum, entryNum, type);
return _text->getTextEntry(dialogNum, entryNum, type, subEntry);
else
return Common::String();
}

View File

@ -268,7 +268,7 @@ public:
void ads_search_block(int16 blockNr, char **ptr);
void ads_search_item(int16 itemNr, char **blkAdr);
int16 start_ads_auto_dia(char *itemAdr);
int16 calc_inv_no_use(int16 curInv, int16 testNr, int16 mode);
int16 calc_inv_no_use(int16 curInv, int16 testNr);
int8 getStereoPos(int16 x);
void enableEvents(bool nr) {
_atdsv._eventsEnabled = nr;
@ -278,8 +278,8 @@ public:
void loadAtdsStream(Common::SeekableReadStream *stream);
uint32 getAtdsStreamSize() const;
Common::StringArray getTextArray(uint dialogNum, uint entryNum, int type);
Common::String getTextEntry(uint dialogNum, uint entryNum, int type);
Common::StringArray getTextArray(uint dialogNum, uint entryNum, int type, int subEntry = -1);
Common::String getTextEntry(uint dialogNum, uint entryNum, int type, int subEntry = -1);
private:
void init();

View File

@ -411,10 +411,10 @@ int16 Inventory::look(int16 invent_nr, int16 mode, int16 ats_nr) {
if (ats_nr >= 15000) {
txt_adr = _G(atds)->ats_get_txt(ats_nr - 15000, TXT_MARK_USE, &lineCount, INV_USE_DEF);
//itemDesc = _G(atds)->getTextArray(ats_nr - 15000, TXT_MARK_USE, INV_USE_DEF);
//itemDesc = _G(atds)->getTextArray(0, ats_nr - 15000, INV_USE_DEF, TXT_MARK_USE);
} else {
txt_adr = _G(atds)->ats_get_txt(ats_nr, TXT_MARK_USE, &lineCount, INV_USE_DATA);
//itemDesc = _G(atds)->getTextArray(ats_nr, TXT_MARK_USE, INV_USE_DATA);
//itemDesc = _G(atds)->getTextArray(0, ats_nr, TXT_MARK_USE, INV_USE_DATA);
}
if (!txt_adr) {
endLoop = true;

View File

@ -485,8 +485,10 @@ void start_aad(int16 diaNr) {
bool startAtsWait(int16 txtNr, int16 txtMode, int16 col, int16 mode) {
bool shown = false;
const int16 oldMouseLeftClick = _G(mouseLeftClick);
assert(mode == ATS_DATA || mode == INV_USE_DATA || mode == INV_USE_DEF);
_G(mouseLeftClick) = false;
_G(minfo)._button = 0;

View File

@ -2298,6 +2298,7 @@ static void calc_inv_get_text(int16 cur_inv, int16 test_nr) {
int16 txt_anz;
const char *s = _G(atds)->ats_get_txt(31, TXT_MARK_USE, &txt_anz, INV_USE_DEF);
//Common::String tmp = _G(atds)->getTextEntry(0, 31, INV_USE_DEF, TXT_MARK_USE);
_G(calc_inv_text_str1) = Common::String::format("%s ", s);
_G(calc_inv_text_str1) += _G(atds)->getTextEntry(cur_inv, TXT_MARK_NAME, INV_ATS_DATA);
@ -2341,7 +2342,7 @@ bool calc_inv_no_use(int16 test_nr, int16 mode) {
}
if (inv_mode != -1) {
int16 txt_nr = _G(atds)->calc_inv_no_use(_G(gameState).AkInvent, test_nr, inv_mode);
int16 txt_nr = _G(atds)->calc_inv_no_use(_G(gameState).AkInvent, test_nr);
if (txt_nr != -1) {
if (!_G(flags).InventMenu) {
if (txt_nr >= 15000) {

View File

@ -81,7 +81,7 @@ TextEntryList *Text::getDialog(uint chunk, uint entry) {
return l;
}
TextEntry *Text::getText(uint chunk, uint entry, int type) {
TextEntry *Text::getText(uint chunk, uint entry, int type, int subEntry) {
bool isText = false;
bool isAutoDialog = false;
bool isInvDesc = false;
@ -117,24 +117,38 @@ TextEntry *Text::getText(uint chunk, uint entry, int type) {
byte *data = getChunkData(chunk);
byte *ptr = data;
uint entryId = 0;
uint16 headerBytes, txtNum;
int curSubEntry = -1;
//Common::hexdump(data, _chunkList[chunk].size);
if (isAutoDialog)
ptr += 3;
while (true) {
ptr += 3;
uint16 headerBytes = READ_LE_UINT16(ptr);
headerBytes = READ_LE_UINT16(ptr);
ptr += 2;
if (headerBytes == 0xFEF2) {
// Start of subchunk
curSubEntry = *ptr;
ptr++;
headerBytes = READ_LE_UINT16(ptr);
ptr += 2;
}
if (headerBytes != 0xFEF0)
break;
uint16 txtNum = !isInvDesc ? READ_LE_UINT16(ptr) : entryId++;
txtNum = !isInvDesc ? READ_LE_UINT16(ptr) : entryId++;
ptr += 2;
ptr += 6;
d->_speechId = READ_LE_UINT16(ptr) - VOICE_OFFSET;
ptr += 2;
do {
if (txtNum == entry)
if (txtNum == entry && curSubEntry == subEntry)
d->_text += *ptr++;
else
ptr++;
@ -144,6 +158,16 @@ TextEntry *Text::getText(uint chunk, uint entry, int type) {
}
} while (*ptr);
// FIXME: Skip other embedded strings for now
if (*(ptr + 1) == kEndText && *(ptr + 2) == 0xf1 && *(ptr + 3) == 0xfe) {
ptr += 5;
do {
ptr++;
if (*ptr == 0 && *(ptr + 1) != kEndText)
ptr++;
} while (*ptr);
}
if (*(ptr + 1) != kEndText || *(ptr + 2) != kEndChunk) {
warning("Invalid text resource - %d, %d", chunk, entry);
@ -158,7 +182,7 @@ TextEntry *Text::getText(uint chunk, uint entry, int type) {
if (isAutoDialog)
ptr += 3;
if (txtNum == entry) {
if (txtNum == entry && curSubEntry == subEntry) {
// Found
delete[] data;
return d;
@ -172,8 +196,8 @@ TextEntry *Text::getText(uint chunk, uint entry, int type) {
return nullptr;
}
Common::StringArray Text::getTextArray(uint chunk, uint entry, int type) {
TextEntry *textData = getText(chunk, entry, type);
Common::StringArray Text::getTextArray(uint chunk, uint entry, int type, int subEntry) {
TextEntry *textData = getText(chunk, entry, type, subEntry);
Common::StringArray res;
Common::String txt = textData ? textData->_text : "";
char *text = new char[txt.size() + 1];
@ -191,8 +215,8 @@ Common::StringArray Text::getTextArray(uint chunk, uint entry, int type) {
return res;
}
Common::String Text::getTextEntry(uint chunk, uint entry, int type) {
Common::StringArray res = getTextArray(chunk, entry, type);
Common::String Text::getTextEntry(uint chunk, uint entry, int type, int subEntry) {
Common::StringArray res = getTextArray(chunk, entry, type, subEntry);
return res.size() > 0 ? res[0] : "";
}

View File

@ -81,10 +81,14 @@ public:
* - auto dialog (AAD) - 600 - 699
* - inventory text (INV) - 700 - 799
* - use text (USE) - 800 - 899
*
* A chunk can contain multiple subchunks with
* the same entry IDs per subchunk:
* 0 - name, 1 - look, 2 - use, 3 - walk, 4 - talk
*/
TextEntry *getText(uint chunk, uint entry, int type);
Common::StringArray getTextArray(uint chunk, uint entry, int type);
Common::String getTextEntry(uint chunk, uint entry, int type);
TextEntry *getText(uint chunk, uint entry, int type, int subEntry = -1);
Common::StringArray getTextArray(uint chunk, uint entry, int type, int subEntry = -1);
Common::String getTextEntry(uint chunk, uint entry, int type, int subEntry = -1);
void crypt(char *txt, uint32 size);
const char *strPos(const char *txtAdr, int16 pos);