mirror of https://github.com/AxioDL/kabufuda.git
Directory: Avoid use of unnamed struct in union
Anonymous structs have a limitation on GCC when involving non-trivial default constructors, as it's a compiler extension and not actually standard C++ to use anonymous structs. We can give the struct a concrete name, which fixes this issue.
This commit is contained in:
parent
e186d1498f
commit
1779e14bcc
|
@ -8,14 +8,15 @@ namespace kabufuda {
|
||||||
class Directory {
|
class Directory {
|
||||||
friend class Card;
|
friend class Card;
|
||||||
#pragma pack(push, 4)
|
#pragma pack(push, 4)
|
||||||
|
struct Data {
|
||||||
|
std::array<File, MaxFiles> m_files;
|
||||||
|
std::array<uint8_t, 0x3a> padding;
|
||||||
|
uint16_t m_updateCounter;
|
||||||
|
uint16_t m_checksum;
|
||||||
|
uint16_t m_checksumInv;
|
||||||
|
};
|
||||||
union {
|
union {
|
||||||
struct {
|
Data data;
|
||||||
std::array<File, MaxFiles> m_files;
|
|
||||||
std::array<uint8_t, 0x3a> padding;
|
|
||||||
uint16_t m_updateCounter;
|
|
||||||
uint16_t m_checksum;
|
|
||||||
uint16_t m_checksumInv;
|
|
||||||
};
|
|
||||||
std::array<uint8_t, BlockSize> raw;
|
std::array<uint8_t, BlockSize> raw;
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
|
@ -42,6 +42,8 @@ union SRAMFlags {
|
||||||
};
|
};
|
||||||
|
|
||||||
union SRAM {
|
union SRAM {
|
||||||
|
using FlashID = std::array<std::array<uint8_t, 12>, 2>;
|
||||||
|
|
||||||
std::array<uint8_t, 64> p_SRAM;
|
std::array<uint8_t, 64> p_SRAM;
|
||||||
struct // Stored configuration value from the system SRAM area
|
struct // Stored configuration value from the system SRAM area
|
||||||
{
|
{
|
||||||
|
@ -56,7 +58,6 @@ union SRAM {
|
||||||
SRAMFlags flags; // Device and operations flag
|
SRAMFlags flags; // Device and operations flag
|
||||||
|
|
||||||
// Stored configuration value from the extended SRAM area
|
// Stored configuration value from the extended SRAM area
|
||||||
using FlashID = std::array<std::array<uint8_t, 12>, 2>;
|
|
||||||
FlashID flash_id; // flash_id[2][12] 96bit memorycard unlock flash ID
|
FlashID flash_id; // flash_id[2][12] 96bit memorycard unlock flash ID
|
||||||
uint32_t wirelessKbd_id; // Device ID of last connected wireless keyboard
|
uint32_t wirelessKbd_id; // Device ID of last connected wireless keyboard
|
||||||
std::array<uint16_t, 4> wirelessPad_id; // 16-bit device ID of last connected pad.
|
std::array<uint16_t, 4> wirelessPad_id; // 16-bit device ID of last connected pad.
|
||||||
|
|
|
@ -88,7 +88,7 @@ ECardResult Card::_pumpOpen() {
|
||||||
else if (!m_bats[1].valid() && m_bats[0].valid())
|
else if (!m_bats[1].valid() && m_bats[0].valid())
|
||||||
m_bats[1] = m_bats[0];
|
m_bats[1] = m_bats[0];
|
||||||
|
|
||||||
if (m_dirs[0].m_updateCounter > m_dirs[1].m_updateCounter)
|
if (m_dirs[0].data.m_updateCounter > m_dirs[1].data.m_updateCounter)
|
||||||
m_currentDir = 0;
|
m_currentDir = 0;
|
||||||
else
|
else
|
||||||
m_currentDir = 1;
|
m_currentDir = 1;
|
||||||
|
@ -151,7 +151,7 @@ void Card::_updateDirAndBat(const Directory& dir, const BlockAllocationTable& ba
|
||||||
m_currentDir = !m_currentDir;
|
m_currentDir = !m_currentDir;
|
||||||
Directory& updateDir = m_dirs[m_currentDir];
|
Directory& updateDir = m_dirs[m_currentDir];
|
||||||
updateDir = dir;
|
updateDir = dir;
|
||||||
updateDir.m_updateCounter++;
|
updateDir.data.m_updateCounter++;
|
||||||
updateDir.updateChecksum();
|
updateDir.updateChecksum();
|
||||||
|
|
||||||
m_currentBat = !m_currentBat;
|
m_currentBat = !m_currentBat;
|
||||||
|
|
|
@ -7,16 +7,16 @@
|
||||||
|
|
||||||
namespace kabufuda {
|
namespace kabufuda {
|
||||||
void Directory::swapEndian() {
|
void Directory::swapEndian() {
|
||||||
std::for_each(std::begin(m_files), std::end(m_files), [](File& f) { f.swapEndian(); });
|
std::for_each(std::begin(data.m_files), std::end(data.m_files), [](File& f) { f.swapEndian(); });
|
||||||
|
|
||||||
m_updateCounter = SBig(m_updateCounter);
|
data.m_updateCounter = SBig(data.m_updateCounter);
|
||||||
m_checksum = SBig(m_checksum);
|
data.m_checksum = SBig(data.m_checksum);
|
||||||
m_checksumInv = SBig(m_checksumInv);
|
data.m_checksumInv = SBig(data.m_checksumInv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Directory::updateChecksum() {
|
void Directory::updateChecksum() {
|
||||||
swapEndian();
|
swapEndian();
|
||||||
calculateChecksumBE(reinterpret_cast<uint16_t*>(raw.data()), 0xFFE, &m_checksum, &m_checksumInv);
|
calculateChecksumBE(reinterpret_cast<uint16_t*>(raw.data()), 0xFFE, &data.m_checksum, &data.m_checksumInv);
|
||||||
swapEndian();
|
swapEndian();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,33 +24,34 @@ bool Directory::valid() const {
|
||||||
uint16_t ckSum, ckSumInv;
|
uint16_t ckSum, ckSumInv;
|
||||||
const_cast<Directory&>(*this).swapEndian();
|
const_cast<Directory&>(*this).swapEndian();
|
||||||
calculateChecksumBE(reinterpret_cast<const uint16_t*>(raw.data()), 0xFFE, &ckSum, &ckSumInv);
|
calculateChecksumBE(reinterpret_cast<const uint16_t*>(raw.data()), 0xFFE, &ckSum, &ckSumInv);
|
||||||
bool res = (ckSum == m_checksum && ckSumInv == m_checksumInv);
|
const bool res = (ckSum == data.m_checksum && ckSumInv == data.m_checksumInv);
|
||||||
const_cast<Directory&>(*this).swapEndian();
|
const_cast<Directory&>(*this).swapEndian();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory::Directory() {
|
Directory::Directory() {
|
||||||
raw.fill(0xFF);
|
raw.fill(0xFF);
|
||||||
m_updateCounter = 0;
|
data.m_updateCounter = 0;
|
||||||
updateChecksum();
|
updateChecksum();
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory::Directory(uint8_t data[]) { std::memcpy(raw.data(), data, BlockSize); }
|
Directory::Directory(uint8_t data[]) { std::memcpy(raw.data(), data, BlockSize); }
|
||||||
|
|
||||||
bool Directory::hasFreeFile() const {
|
bool Directory::hasFreeFile() const {
|
||||||
return std::any_of(m_files.cbegin(), m_files.cend(), [](const auto& file) { return file.m_game[0] == 0xFF; });
|
return std::any_of(data.m_files.cbegin(), data.m_files.cend(),
|
||||||
|
[](const auto& file) { return file.m_game[0] == 0xFF; });
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Directory::numFreeFiles() const {
|
int32_t Directory::numFreeFiles() const {
|
||||||
return int32_t(
|
return int32_t(std::count_if(data.m_files.cbegin(), data.m_files.cend(),
|
||||||
std::count_if(m_files.cbegin(), m_files.cend(), [](const auto& file) { return file.m_game[0] == 0xFF; }));
|
[](const auto& file) { return file.m_game[0] == 0xFF; }));
|
||||||
}
|
}
|
||||||
|
|
||||||
File* Directory::getFirstFreeFile(const char* game, const char* maker, const char* filename) {
|
File* Directory::getFirstFreeFile(const char* game, const char* maker, const char* filename) {
|
||||||
const auto iter =
|
const auto iter =
|
||||||
std::find_if(m_files.begin(), m_files.end(), [](const auto& file) { return file.m_game[0] == 0xFF; });
|
std::find_if(data.m_files.begin(), data.m_files.end(), [](const auto& file) { return file.m_game[0] == 0xFF; });
|
||||||
|
|
||||||
if (iter == m_files.cend()) {
|
if (iter == data.m_files.cend()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ File* Directory::getFirstFreeFile(const char* game, const char* maker, const cha
|
||||||
}
|
}
|
||||||
|
|
||||||
File* Directory::getFirstNonFreeFile(uint32_t start, const char* game, const char* maker) {
|
File* Directory::getFirstNonFreeFile(uint32_t start, const char* game, const char* maker) {
|
||||||
const auto iter = std::find_if(m_files.begin(), m_files.end(), [game, maker](const auto& file) {
|
const auto iter = std::find_if(data.m_files.begin() + start, data.m_files.end(), [game, maker](const auto& file) {
|
||||||
if (file.m_game[0] == 0xFF) {
|
if (file.m_game[0] == 0xFF) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +87,7 @@ File* Directory::getFirstNonFreeFile(uint32_t start, const char* game, const cha
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (iter == m_files.cend()) {
|
if (iter == data.m_files.cend()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +95,7 @@ File* Directory::getFirstNonFreeFile(uint32_t start, const char* game, const cha
|
||||||
}
|
}
|
||||||
|
|
||||||
File* Directory::getFile(const char* game, const char* maker, const char* filename) {
|
File* Directory::getFile(const char* game, const char* maker, const char* filename) {
|
||||||
const auto iter = std::find_if(m_files.begin(), m_files.end(), [=](const auto& file) {
|
const auto iter = std::find_if(data.m_files.begin(), data.m_files.end(), [=](const auto& file) {
|
||||||
const auto game_size = file.m_game.size();
|
const auto game_size = file.m_game.size();
|
||||||
if (game != nullptr && std::strlen(game) == game_size && std::memcmp(file.m_game.data(), game, game_size) != 0) {
|
if (game != nullptr && std::strlen(game) == game_size && std::memcmp(file.m_game.data(), game, game_size) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -109,7 +110,7 @@ File* Directory::getFile(const char* game, const char* maker, const char* filena
|
||||||
return std::strcmp(file.m_filename, filename) == 0;
|
return std::strcmp(file.m_filename, filename) == 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (iter == m_files.cend()) {
|
if (iter == data.m_files.cend()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,11 +118,11 @@ File* Directory::getFile(const char* game, const char* maker, const char* filena
|
||||||
}
|
}
|
||||||
|
|
||||||
File* Directory::getFile(uint32_t idx) {
|
File* Directory::getFile(uint32_t idx) {
|
||||||
if (idx >= m_files.size()) {
|
if (idx >= data.m_files.size()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &m_files[idx];
|
return &data.m_files[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Directory::indexForFile(File* f) {
|
int32_t Directory::indexForFile(File* f) {
|
||||||
|
@ -129,11 +130,12 @@ int32_t Directory::indexForFile(File* f) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto it = std::find_if(std::cbegin(m_files), std::cend(m_files), [&f](const File& file) { return f == &file; });
|
const auto it =
|
||||||
if (it == std::cend(m_files)) {
|
std::find_if(std::cbegin(data.m_files), std::cend(data.m_files), [&f](const File& file) { return f == &file; });
|
||||||
|
if (it == std::cend(data.m_files)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return it - std::cbegin(m_files);
|
return it - std::cbegin(data.m_files);
|
||||||
}
|
}
|
||||||
} // namespace kabufuda
|
} // namespace kabufuda
|
||||||
|
|
Loading…
Reference in New Issue