Commit 05da015f authored by salix5's avatar salix5 Committed by GitHub

Use array to store setcode (#2510)

* card_data.setcode: use std vector

* remove CARD_ARTWORK_VERSIONS_OFFSET

* add extra_setcode for cards with 5+ setcodes

* setcode use array

* Update data_manager.cpp
parent 99cc1108
......@@ -11,21 +11,9 @@
namespace ygo {
using CardData = card_data;
struct CardDataC {
unsigned int code;
unsigned int alias;
unsigned long long setcode;
unsigned int type;
unsigned int level;
unsigned int attribute;
unsigned int race;
int attack;
int defense;
unsigned int lscale;
unsigned int rscale;
unsigned int link_marker;
unsigned int ot;
unsigned int category;
struct CardDataC : card_data {
unsigned int ot{};
unsigned int category{};
};
struct CardString {
std::wstring name;
......
......@@ -1489,15 +1489,7 @@ static bool is_declarable(T const& cd, const std::vector<int>& opcode) {
if (stack.size() >= 1) {
int set_code = stack.top();
stack.pop();
unsigned long long sc = cd.setcode;
bool res = false;
int settype = set_code & 0xfff;
int setsubtype = set_code & 0xf000;
while (sc) {
if ((sc & 0xfff) == settype && (sc & 0xf000 & setsubtype) == setsubtype)
res = true;
sc = sc >> 16;
}
bool res = cd.is_setcode(set_code);
stack.push(res);
}
break;
......
......@@ -9,6 +9,13 @@ byte DataManager::scriptBuffer[0x20000];
IFileSystem* DataManager::FileSystem;
DataManager dataManager;
DataManager::DataManager() : _datas(16384), _strings(16384) {
datas_begin = _datas.begin();
datas_end = _datas.end();
strings_begin = _strings.begin();
strings_end = _strings.end();
extra_setcode = { {8512558u, {0x8f, 0x54, 0x59, 0x82, 0x13a}}, };
}
bool DataManager::LoadDB(const wchar_t* wfile) {
char file[256];
BufferIO::EncodeUTF8(wfile, file);
......@@ -34,11 +41,11 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
const char* sql = "select * from datas,texts where datas.id=texts.id";
if(sqlite3_prepare_v2(pDB, sql, -1, &pStmt, 0) != SQLITE_OK)
return Error(&db);
CardDataC cd;
CardString cs;
wchar_t strBuffer[4096];
int step = 0;
do {
CardDataC cd;
CardString cs;
step = sqlite3_step(pStmt);
if(step == SQLITE_BUSY || step == SQLITE_ERROR || step == SQLITE_MISUSE)
return Error(&db, pStmt);
......@@ -46,7 +53,16 @@ bool DataManager::LoadDB(const wchar_t* wfile) {
cd.code = sqlite3_column_int(pStmt, 0);
cd.ot = sqlite3_column_int(pStmt, 1);
cd.alias = sqlite3_column_int(pStmt, 2);
cd.setcode = sqlite3_column_int64(pStmt, 3);
auto it = extra_setcode.find(cd.code);
if (it != extra_setcode.end()) {
int len = it->second.size();
if (len > SIZE_SETCODE)
len = SIZE_SETCODE;
if (len)
memcpy(cd.setcode, it->second.data(), len * sizeof(uint16_t));
}
else
cd.set_setcode(sqlite3_column_int64(pStmt, 3));
cd.type = sqlite3_column_int(pStmt, 4);
cd.attack = sqlite3_column_int(pStmt, 5);
cd.defense = sqlite3_column_int(pStmt, 6);
......@@ -159,7 +175,7 @@ bool DataManager::GetData(unsigned int code, CardData* pData) {
if (pData) {
pData->code = data.code;
pData->alias = data.alias;
pData->setcode = data.setcode;
memcpy(pData->setcode, data.setcode, SIZE_SETCODE);
pData->type = data.type;
pData->level = data.level;
pData->attribute = data.attribute;
......@@ -329,10 +345,12 @@ const wchar_t* DataManager::FormatType(int type) {
return unknown_string;
return tpBuffer;
}
const wchar_t* DataManager::FormatSetName(unsigned long long setcode) {
const wchar_t* DataManager::FormatSetName(const uint16_t setcode[]) {
wchar_t* p = scBuffer;
for(int i = 0; i < 4; ++i) {
const wchar_t* setname = GetSetName((setcode >> i * 16) & 0xffff);
for(int i = 0; i < 10; ++i) {
if (!setcode[i])
break;
const wchar_t* setname = GetSetName(setcode[i]);
if(setname) {
BufferIO::CopyWStrRef(setname, p, 32);
*p = L'|';
......
......@@ -11,12 +11,7 @@ namespace ygo {
class DataManager {
public:
DataManager(): _datas(16384), _strings(16384) {
datas_begin = _datas.begin();
datas_end = _datas.end();
strings_begin = _strings.begin();
strings_end = _strings.end();
}
DataManager();
bool LoadDB(const wchar_t* wfile);
bool LoadStrings(const char* file);
bool LoadStrings(IReadFile* reader);
......@@ -39,7 +34,7 @@ public:
const wchar_t* FormatAttribute(int attribute);
const wchar_t* FormatRace(int race);
const wchar_t* FormatType(int type);
const wchar_t* FormatSetName(unsigned long long setcode);
const wchar_t* FormatSetName(const uint16_t setcode[]);
const wchar_t* FormatLinkMarker(int link_marker);
std::unordered_map<unsigned int, std::wstring> _counterStrings;
......@@ -69,6 +64,7 @@ public:
private:
std::unordered_map<unsigned int, CardDataC> _datas;
std::unordered_map<unsigned int, CardString> _strings;
std::unordered_map<unsigned int, std::vector<uint16_t>> extra_setcode;
};
extern DataManager dataManager;
......
......@@ -40,23 +40,6 @@ static int parse_filter(const wchar_t* pstr, unsigned int* type) {
return 0;
}
static bool check_set_code(const CardDataC& data, int set_code) {
unsigned long long sc = data.setcode;
if (data.alias) {
auto aptr = dataManager.GetCodePointer(data.alias);
if (aptr != dataManager.datas_end)
sc = aptr->second.setcode;
}
bool res = false;
int settype = set_code & 0xfff;
int setsubtype = set_code & 0xf000;
while (sc) {
if ((sc & 0xfff) == settype && (sc & 0xf000 & setsubtype) == setsubtype)
res = true;
sc = sc >> 16;
}
return res;
}
static inline bool havePopupWindow() {
return mainGame->wQuery->isVisible() || mainGame->wCategories->isVisible() || mainGame->wLinkMarks->isVisible() || mainGame->wDeckManage->isVisible() || mainGame->wDMQuery->isVisible();
......@@ -1353,7 +1336,7 @@ void DeckBuilder::FilterCards() {
results.clear();
struct element_t {
std::wstring keyword;
int setcode;
unsigned int setcode;
enum class type_t {
all,
name,
......@@ -1506,14 +1489,14 @@ void DeckBuilder::FilterCards() {
if (elements_iterator->type == element_t::type_t::name) {
match = CardNameContains(text.name.c_str(), elements_iterator->keyword.c_str());
} else if (elements_iterator->type == element_t::type_t::setcode) {
match = elements_iterator->setcode && check_set_code(data, elements_iterator->setcode);
match = elements_iterator->setcode && data.is_setcode(elements_iterator->setcode);
} else {
int trycode = BufferIO::GetVal(elements_iterator->keyword.c_str());
bool tryresult = dataManager.GetData(trycode, 0);
if(!tryresult) {
match = CardNameContains(text.name.c_str(), elements_iterator->keyword.c_str())
|| text.text.find(elements_iterator->keyword) != std::wstring::npos
|| (elements_iterator->setcode && check_set_code(data, elements_iterator->setcode));
|| (elements_iterator->setcode && data.is_setcode(elements_iterator->setcode));
} else {
match = data.code == trycode || data.alias == trycode;
}
......
......@@ -1518,32 +1518,41 @@ void Game::SaveConfig() {
void Game::ShowCardInfo(int code, bool resize) {
if(showingcode == code && !resize)
return;
CardData cd;
wchar_t formatBuffer[256];
dataManager.GetData(code, &cd);
auto cit = dataManager.GetCodePointer(code);
bool is_valid = (cit != dataManager.datas_end);
imgCard->setImage(imageManager.GetTexture(code, true));
if(cd.alias != 0 && (cd.alias - code < CARD_ARTWORK_VERSIONS_OFFSET || code - cd.alias < CARD_ARTWORK_VERSIONS_OFFSET))
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(cd.alias), cd.alias);
else myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
if (is_valid) {
auto& cd = cit->second;
if (cd.is_alternative())
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(cd.alias), cd.alias);
else
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
}
else {
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
}
stName->setText(formatBuffer);
int offset = 0;
if(!gameConf.hide_setname) {
unsigned long long sc = cd.setcode;
if(cd.alias) {
auto aptr = dataManager.GetCodePointer(cd.alias);
if(aptr != dataManager.datas_end)
sc = aptr->second.setcode;
if (is_valid && !gameConf.hide_setname) {
auto& cd = cit->second;
auto target = cit;
if (cd.alias && dataManager.GetCodePointer(cd.alias) != dataManager.datas_end) {
target = dataManager.GetCodePointer(cd.alias);
}
if(sc) {
if (target->second.setcode[0]) {
offset = 23;// *yScale;
myswprintf(formatBuffer, L"%ls%ls", dataManager.GetSysString(1329), dataManager.FormatSetName(sc));
myswprintf(formatBuffer, L"%ls%ls", dataManager.GetSysString(1329), dataManager.FormatSetName(target->second.setcode));
stSetName->setText(formatBuffer);
} else
}
else
stSetName->setText(L"");
} else {
}
else {
stSetName->setText(L"");
}
if(cd.type & TYPE_MONSTER) {
if(is_valid && cit->second.type & TYPE_MONSTER) {
auto& cd = cit->second;
myswprintf(formatBuffer, L"[%ls] %ls/%ls", dataManager.FormatType(cd.type), dataManager.FormatRace(cd.race), dataManager.FormatAttribute(cd.attribute));
stInfo->setText(formatBuffer);
int offset_info = 0;
......@@ -1589,8 +1598,12 @@ void Game::ShowCardInfo(int code, bool resize) {
stSetName->setRelativePosition(rect<s32>(15, (83 + offset_arrows), 296 * xScale, (83 + offset_arrows) + offset));
stText->setRelativePosition(rect<s32>(15, (83 + offset_arrows) + offset, 287 * xScale, 324 * yScale));
scrCardText->setRelativePosition(rect<s32>(287 * xScale - 20, (83 + offset_arrows) + offset, 287 * xScale, 324 * yScale));
} else {
myswprintf(formatBuffer, L"[%ls]", dataManager.FormatType(cd.type));
}
else {
if (is_valid)
myswprintf(formatBuffer, L"[%ls]", dataManager.FormatType(cit->second.type));
else
myswprintf(formatBuffer, L"[%ls]", dataManager.FormatType(0));
stInfo->setText(formatBuffer);
stDataInfo->setText(L"");
stSetName->setRelativePosition(rect<s32>(15, 60, 296 * xScale, 60 + offset));
......
......@@ -826,6 +826,5 @@ extern Game* mainGame;
#define AVAIL_SC 0x8
#define AVAIL_OCGTCG (AVAIL_OCG|AVAIL_TCG)
#define CARD_ARTWORK_VERSIONS_OFFSET 10
#define MAX_LAYER_COUNT 6
#endif // GAME_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment