CHEWY: Start reworking dynamic hotspot string changes

This was not implemented in the refactoring done in 8eadac5eeda.
It's still incomplete, and doesn't work yet
This commit is contained in:
Filippos Karapetis 2022-07-03 16:14:06 +03:00
parent abc0538214
commit 4d7695cd70
8 changed files with 145 additions and 90 deletions

View File

@ -352,39 +352,11 @@ void Atdsys::load_atds(int16 chunkNr, int16 mode) {
}
}
void Atdsys::set_ats_mem(int16 mode) {
switch (mode) {
case ATS_DATA:
_ats_sheader = _G(gameState).Ats;
_atsMem = _atdsMem[mode];
break;
case INV_USE_DATA:
_ats_sheader = _G(gameState).InvUse;
_atsMem = _atdsMem[mode];
break;
case INV_USE_DEF:
error("set_ats_mem() called with mode INV_USE_DEF");
case INV_ATS_DATA:
_ats_sheader = _G(gameState).InvAts;
_atsMem = _atdsMem[mode];
break;
default:
break;
}
}
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;
if (mode != INV_USE_DEF)
set_ats_mem(mode);
_atsv.shown = false;
Common::StringArray textArray;
@ -501,19 +473,7 @@ void Atdsys::print_ats(int16 x, int16 y, int16 scrX, int16 scrY) {
}
void Atdsys::set_ats_str(int16 txtNr, int16 txtMode, int16 strNr, int16 mode) {
set_ats_mem(mode);
uint8 status = _ats_sheader[(txtNr * MAX_ATS_STATUS) + (txtMode + 1) / 2];
int16 ak_nybble = (txtMode + 1) % 2;
uint8 lo_hi[2];
lo_hi[1] = status >> 4;
lo_hi[0] = status &= 15;
lo_hi[ak_nybble] = strNr;
status = 0;
lo_hi[1] <<= 4;
status |= lo_hi[0];
status |= lo_hi[1];
_ats_sheader[(txtNr * MAX_ATS_STATUS) + (txtMode + 1) / 2] = status;
_text->setTextId(txtNr, txtMode, strNr, mode);
}
void Atdsys::set_ats_str(int16 txtNr, int16 strNr, int16 mode) {
@ -521,31 +481,16 @@ void Atdsys::set_ats_str(int16 txtNr, int16 strNr, int16 mode) {
set_ats_str(txtNr, i, strNr, mode);
}
int16 Atdsys::get_ats_str(int16 txtNr, int16 txtMode, int16 mode) {
set_ats_mem(mode);
uint8 status = _ats_sheader[(txtNr * MAX_ATS_STATUS) + (txtMode + 1) / 2];
int16 ak_nybble = (txtMode + 1) % 2;
uint8 lo_hi[2];
lo_hi[1] = status >> 4;
lo_hi[0] = status &= 15;
return (int16)lo_hi[ak_nybble];
}
int16 Atdsys::getControlBit(int16 txtNr, int16 bitIdx) {
set_ats_mem(ATS_DATA);
return (_ats_sheader[txtNr * MAX_ATS_STATUS] & bitIdx) != 0;
return _text->getControlBit(txtNr, bitIdx);
}
void Atdsys::setControlBit(int16 txtNr, int16 bitIdx) {
set_ats_mem(ATS_DATA);
_ats_sheader[txtNr * MAX_ATS_STATUS] |= bitIdx;
_text->setControlBit(txtNr, bitIdx);
}
void Atdsys::delControlBit(int16 txtNr, int16 bitIdx) {
set_ats_mem(ATS_DATA);
_ats_sheader[txtNr * MAX_ATS_STATUS] &= ~bitIdx;
_text->delControlBit(txtNr, bitIdx);
}
int16 Atdsys::start_aad(int16 diaNr) {
@ -1025,4 +970,8 @@ Common::String Atdsys::getTextEntry(uint dialogNum, uint entryNum, int type, int
return Common::String();
}
int16 Atdsys::getLastSpeechId() {
return _text->getLastSpeechId();
}
} // namespace Chewy

View File

@ -228,8 +228,6 @@ public:
void delControlBit(int16 txtNr, int16 bitIdx);
void set_ats_str(int16 txtNr, int16 txtMode, int16 strNr, int16 mode);
void set_ats_str(int16 txtNr, int16 strNr, int16 mode);
int16 get_ats_str(int16 txtNr, int16 txtMode, int16 mode);
void set_ats_mem(int16 mode);
int16 start_aad(int16 diaNr);
void stopAad();
void print_aad(int16 scrX, int16 scrY);
@ -263,7 +261,7 @@ public:
Common::StringArray getTextArray(uint dialogNum, uint entryNum, int type, int subEntry = -1);
Common::String getTextEntry(uint dialogNum, uint entryNum, int type, int subEntry = -1);
int16 getLastSpeechId() { return _text->getLastSpeechId(); }
int16 getLastSpeechId();
private:
void init();
@ -273,8 +271,6 @@ private:
Common::File *_atdsHandle = nullptr;
char *_atdsMem[MAX_HANDLE] = { nullptr };
int16 _atdsPoolOff[MAX_HANDLE] = { 0 };
char *_atsMem = nullptr;
uint8 *_ats_sheader = nullptr;
AadVar _aadv;
AtsVar _atsv;
DialogCloseupVariables _dialogCloseup;

View File

@ -404,7 +404,6 @@ enum SetupScreenMode {
#define AUTO_OBJ4 4
#define MAX_OBJ_MOV 3
#define ROOM_ATS_MAX 1000
#define INV_USE_ATS_MAX 500
#define ATS_ACTION_VOR 0
#define ATS_ACTION_NACH 1

View File

@ -164,24 +164,6 @@ void new_game() {
_G(obj)->load(INVENTORY_SIB, &_G(gameState).room_s_obj[0]);
_G(obj)->load(EXIT_EIB, &_G(gameState).room_e_obj[0]);
Common::File f;
if (!f.open(ROOM_ATS_STEUER))
error("Error reading file: %s", ROOM_ATS_STEUER);
for (int16 i = 0; i < ROOM_ATS_MAX; i++)
_G(gameState).Ats[i * MAX_ATS_STATUS] = f.readByte();
f.close();
// WORKAROUND: For English version, taxi hotspot in
// room 45 (Big City) isn't turned on by default
_G(gameState).Ats[295 * MAX_ATS_STATUS] = ATS_ACTION_BIT;
if (!f.open(INV_ATS_STEUER))
error("Error reading file: %s", INV_ATS_STEUER);
for (int16 i = 0; i < MAX_MOV_OBJ; i++)
_G(gameState).InvAts[i * MAX_ATS_STATUS] = f.readByte();
f.close();
_G(obj)->sort();
for (int16 i = 0; i < _G(obj)->spieler_invnr[0]; i++)
_G(gameState).InventSlot[i] = _G(obj)->spieler_invnr[i + 1];

View File

@ -22,12 +22,35 @@
#include "common/system.h"
#include "chewy/resource.h"
#include "chewy/text.h"
#include "types.h"
#include "chewy/atds.h"
#include "chewy/defines.h"
namespace Chewy {
Text::Text() : Resource("atds.tap") {
memset(_hotspotStrings, sizeof(_hotspotStrings), 0);
Common::File f;
if (!f.open(ROOM_ATS_STEUER))
error("Error reading file: %s", ROOM_ATS_STEUER);
for (int16 i = 0; i < ROOM_ATS_MAX; i++)
_hotspotStrings[i * MAX_ATS_STATUS] = f.readByte();
f.close();
if (!f.open(INV_ATS_STEUER))
error("Error reading file: %s", INV_ATS_STEUER);
for (int16 i = 0; i < MAX_MOV_OBJ; i++)
_inventoryStrings[i * MAX_ATS_STATUS] = f.readByte();
f.close();
// WORKAROUND: For English version, taxi hotspot in
// room 45 (Big City) isn't turned on by default
_hotspotStrings[295] = ATS_ACTION_BIT;
}
Text::~Text() {
@ -86,6 +109,11 @@ TextEntry *Text::getText(uint chunk, uint entry, int type, int subEntry) {
bool isAutoDialog = false;
bool isInvDesc = false;
//int subEntryNew = -1;
//if (subEntry >= 0)
// subEntryNew = getTextId(entry, subEntry, type);
switch (type) {
case AAD_DATA:
chunk += kADSTextMax + kATSTextMax;
@ -232,4 +260,85 @@ const char *Text::strPos(const char *txtAdr, int16 pos) {
return ptr;
}
void Text::syncHotspotStrings(Common::Serializer &s) {
for (size_t i = 0; i < sizeof(_hotspotStrings); ++i)
s.syncAsByte(_hotspotStrings[i]);
}
void Text::syncInventoryStrings(Common::Serializer &s) {
for (size_t i = 0; i < sizeof(_inventoryStrings); ++i)
s.syncAsByte(_inventoryStrings[i]);
}
void Text::syncInventoryUseStrings(Common::Serializer &s) {
for (size_t i = 0; i < sizeof(_inventoryUseStrings); ++i)
s.syncAsByte(_inventoryUseStrings[i]);
}
bool Text::getControlBit(int16 txtNr, int16 bitIdx) {
return (_hotspotStrings[txtNr * MAX_ATS_STATUS] & bitIdx) != 0;
}
void Text::setControlBit(int16 txtNr, int16 bitIdx) {
_hotspotStrings[txtNr * MAX_ATS_STATUS] |= bitIdx;
}
void Text::delControlBit(int16 txtNr, int16 bitIdx) {
_hotspotStrings[txtNr * MAX_ATS_STATUS] &= ~bitIdx;
}
/*uint8 Text::getTextStatus(uint8 status, int16 subEntry, int16 strNr) {
const int16 hotspotActionStr = (subEntry + 1) % 2;
uint8 lo_hi[2];
lo_hi[0] = status &= 15;
lo_hi[1] = status >> 4;
lo_hi[hotspotActionStr] = strNr;
status = 0;
lo_hi[1] <<= 4;
status |= lo_hi[0];
status |= lo_hi[1];
return status;
}*/
uint8 Text::updateTextStatus(int16 entry, int16 subEntry, int16 strNr, int16 type) {
byte *buffer;
switch (type) {
case ATS_DATA:
buffer = _hotspotStrings;
break;
case INV_USE_DATA:
buffer = _inventoryUseStrings;
break;
case INV_ATS_DATA:
buffer = _inventoryStrings;
break;
default:
error("setTextId called for type %d", type);
}
const uint8 status = buffer[(entry * MAX_ATS_STATUS) + (subEntry + 1) / 2];
if (strNr >= 0) {
buffer[(entry * MAX_ATS_STATUS) + (subEntry + 1) / 2] = strNr; // getTextStatus(status, subEntry, strNr);
return strNr;
}
return status;
}
uint8 Text::getTextId(uint entry, uint subEntry, int type) {
uint8 status = updateTextStatus(entry, subEntry, -1, type);
const int16 hotspotActionStr = (subEntry + 1) % 2;
uint8 lo_hi[2];
lo_hi[0] = status &= 15;
lo_hi[1] = status >> 4;
return lo_hi[hotspotActionStr];
}
void Text::setTextId(int16 entry, int16 subEntry, int16 strNr, int16 type) {
updateTextStatus(entry, subEntry, strNr, type);
}
} // namespace Chewy

View File

@ -23,7 +23,10 @@
#define CHEWY_TEXT_H
#include "common/list.h"
#include "common/serializer.h"
#include "chewy/atds.h"
#include "chewy/chewy.h"
#include "chewy/defines.h"
#include "chewy/resource.h"
namespace Chewy {
@ -65,6 +68,8 @@ struct TextEntry {
typedef Common::List<TextEntry> TextEntryList;
#define ROOM_ATS_MAX 1000
class Text : public Resource {
public:
Text();
@ -93,8 +98,25 @@ public:
const char *strPos(const char *txtAdr, int16 pos);
void syncHotspotStrings(Common::Serializer &s);
void syncInventoryStrings(Common::Serializer &s);
void syncInventoryUseStrings(Common::Serializer &s);
bool getControlBit(int16 txtNr, int16 bitIdx);
void setControlBit(int16 txtNr, int16 bitIdx);
void delControlBit(int16 txtNr, int16 bitIdx);
void setTextId(int16 entry, int16 subEntry, int16 strNr, int16 type);
private:
int16 _lastSpeechId = -1;
byte _hotspotStrings[ROOM_ATS_MAX * 3] = { 0 };
uint8 _inventoryStrings[MAX_MOV_OBJ * 3] = {0};
uint8 _inventoryUseStrings[INV_USE_ATS_MAX * 3] = {0};
//uint8 getTextStatus(uint8 status, int16 subEntry, int16 strNr);
uint8 getTextId(uint entry, uint subEntry, int type);
uint8 updateTextStatus(int16 entry, int16 subEntry, int16 strNr, int16 type);
};
} // namespace Chewy

View File

@ -42,6 +42,7 @@ static void syncArray(Common::Serializer &s, uint8 *arr, size_t count) {
for (size_t i = 0; i < count; ++i)
s.syncAsByte(arr[i]);
}
static void syncArray(Common::Serializer &s, int16 *arr, size_t count) {
for (size_t i = 0; i < count; ++i)
s.syncAsSint16LE(arr[i]);
@ -55,14 +56,15 @@ bool GameState::synchronize(Common::Serializer &s) {
byte dummy = 0;
int16 dummy16 = 0;
uint8 InvUseDef[40 * 3] = {0}; // dummy
int inventoryCursor = _G(cur)->getInventoryCursor();
// Sync the structure's bitflags
s.syncBytes((byte *)_flags, SPIELER_FLAGS_SIZE);
syncArray(s, Ats, ROOM_ATS_MAX * 3);
syncArray(s, InvAts, MAX_MOV_OBJ * 3);
syncArray(s, InvUse, INV_USE_ATS_MAX * 3);
_G(txt)->syncHotspotStrings(s);
_G(txt)->syncInventoryStrings(s);
_G(txt)->syncInventoryUseStrings(s);
syncArray(s, InvUseDef, 40 * 3);
s.syncAsSint16LE(MainMenuY);

View File

@ -391,10 +391,6 @@ struct GameState : public GameFlags {
bool synchronize(Common::Serializer &s);
GameFlags *_flags = nullptr;
uint8 Ats[ROOM_ATS_MAX * 3] = { 0 };
uint8 InvAts[MAX_MOV_OBJ * 3] = { 0 };
uint8 InvUse[INV_USE_ATS_MAX * 3] = { 0 };
uint8 InvUseDef[40 * 3] = { 0 };
int16 MainMenuY = 0;
int16 InvDisp = 0;