Compare commits

..

3 Commits

Author SHA1 Message Date
461e3d61ef [ox/preloader] Add ptr handling 2022-12-05 17:40:22 -06:00
030d46a999 [ox/std] Cleanup mGBA logging 2022-12-05 17:28:42 -06:00
cd4a9300a5 [ox/preloader] Fix Vector preloading 2022-12-04 22:31:51 -06:00
2 changed files with 59 additions and 32 deletions

View File

@@ -32,6 +32,7 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
friend constexpr ox::Error preload(Preloader<PS> *pl, ox::CommonPtrWith<T> auto *obj) noexcept; friend constexpr ox::Error preload(Preloader<PS> *pl, ox::CommonPtrWith<T> auto *obj) noexcept;
private: private:
using PtrType = typename PlatSpec::PtrType;
class UnionIdxTracker { class UnionIdxTracker {
private: private:
int m_unionIdx = -1; int m_unionIdx = -1;
@@ -55,6 +56,14 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
}; };
ox::Vector<PtrPair> m_ptrs; ox::Vector<PtrPair> m_ptrs;
ox::Vector<UnionIdxTracker, 8> m_unionIdx = {{}}; ox::Vector<UnionIdxTracker, 8> m_unionIdx = {{}};
class AllocStackItem {
public:
PtrType restore = 0;
ox::ios_base::seekdir seekdir = ox::ios_base::end;
constexpr AllocStackItem(PtrType pRestore, ox::ios_base::seekdir pSeekdir = ox::ios_base::end) noexcept:
restore(pRestore), seekdir(pSeekdir) {}
};
ox::Vector<AllocStackItem, 8> m_allocStack;
constexpr Preloader() noexcept: m_writer(&m_buff) {} constexpr Preloader() noexcept: m_writer(&m_buff) {}
@@ -86,7 +95,9 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
template<typename T> template<typename T>
constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept; constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept;
constexpr ox::Error startAlloc(std::size_t sz) noexcept; constexpr ox::Result<std::size_t> startAlloc(std::size_t sz) noexcept;
constexpr ox::Result<std::size_t> startAlloc(std::size_t sz, std::size_t restore) noexcept;
constexpr ox::Error endAlloc() noexcept; constexpr ox::Error endAlloc() noexcept;
@@ -156,7 +167,10 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
if constexpr(ox::is_integral_v<T>) { if constexpr(ox::is_integral_v<T>) {
return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val)); return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val));
} else if constexpr(ox::is_pointer_v<T>) { } else if constexpr(ox::is_pointer_v<T>) {
return {}; const PtrType a = startAlloc(sizeOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart;
oxReturnError(field(name, *val));
oxReturnError(endAlloc());
return ox::serialize(&m_writer, PlatSpec::correctEndianness(a));
} else if constexpr(ox::isVector_v<T> || ox::is_same_v<T, ox::ModelValueVector>) { } else if constexpr(ox::isVector_v<T> || ox::is_same_v<T, ox::ModelValueVector>) {
return fieldVector(name, val); return fieldVector(name, val);
} else { } else {
@@ -188,7 +202,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::BasicStri
} else { } else {
a = restore; a = restore;
} }
vecVal.items = sz ? PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(a) + PlatSpec::RomStart) : 0; vecVal.items = PlatSpec::correctEndianness(static_cast<PtrType>(a) + PlatSpec::RomStart);
oxReturnError(m_writer.seekp(a)); oxReturnError(m_writer.seekp(a));
oxReturnError(m_writer.write(val->data(), sz)); oxReturnError(m_writer.write(val->data(), sz));
oxReturnError(m_writer.seekp(restore)); oxReturnError(m_writer.seekp(restore));
@@ -230,15 +244,31 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const T **val, std:
} }
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::startAlloc(std::size_t sz) noexcept { constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(std::size_t sz) noexcept {
oxRequire(p, ox::allocate(&m_writer, sz)); oxRequire(a, ox::allocate(&m_writer, sz));
return m_writer.seekp(p); m_allocStack.emplace_back(m_writer.tellp());
oxReturnError(m_writer.seekp(a));
return a;
}
template<typename PlatSpec>
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(std::size_t sz, std::size_t restore) noexcept {
oxRequire(a, ox::allocate(&m_writer, sz));
m_allocStack.emplace_back(restore, ox::ios_base::beg);
oxReturnError(m_writer.seekp(a));
return a;
} }
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept { constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept {
if (m_allocStack.empty()) {
return m_writer.seekp(0, ox::ios_base::end); return m_writer.seekp(0, ox::ios_base::end);
} }
const auto &si = m_allocStack.back().unwrap();
oxReturnError(m_writer.seekp(si.restore, si.seekdir));
m_allocStack.pop_back();
return {};
}
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept { constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept {
@@ -306,7 +336,7 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView, const auto *v
} }
// serialize the Vector // serialize the Vector
oxReturnError(serialize(&m_writer, vecVal)); oxReturnError(serialize(&m_writer, vecVal));
m_ptrs.emplace_back(vecValPt + offsetof(ox::VectorMemMap<PlatSpec>, items), vecVal.items); m_ptrs.emplace_back(m_writer.tellp() - PlatSpec::PtrSize, vecVal.items);
return {}; return {};
} }

View File

@@ -16,37 +16,34 @@
#define REG_MGBA_DEBUG_FLAGS *reinterpret_cast<volatile uint16_t*>(0x4FFF700) #define REG_MGBA_DEBUG_FLAGS *reinterpret_cast<volatile uint16_t*>(0x4FFF700)
#define REG_MGBA_DEBUG_STRING (reinterpret_cast<char*>(0x4FFF600)) #define REG_MGBA_DEBUG_STRING (reinterpret_cast<char*>(0x4FFF600))
namespace ox::hw { inline void nullLog(ox::CRStringView) {}
static void (*infoLog)(ox::CRStringView) = [](ox::CRStringView) {}; inline void (*infoLog)(ox::CRStringView) = nullLog;
static void (*debugLog)(ox::CRStringView) = [](ox::CRStringView) {}; inline void (*debugLog)(ox::CRStringView) = nullLog;
static void (*errorLog)(ox::CRStringView) = [](ox::CRStringView) {}; inline void (*errorLog)(ox::CRStringView) = nullLog;
}
namespace mgba { namespace mgba {
enum LogChan { enum LogChan {
LOG_FATAL = 0, Fatal = 0,
LOG_ERROR = 1, Error = 1,
LOG_WARN = 2, Warn = 2,
LOG_INFO = 3, Info = 3,
LOG_DEBUG = 4 Debug = 4,
}; };
template<LogChan chan> template<LogChan chan>
static auto mkLogger() { static void log(ox::CRStringView str) {
return [](ox::CRStringView str) {
const auto sz = ox::min<std::size_t>(0x100, str.bytes()); const auto sz = ox::min<std::size_t>(0x100, str.bytes());
ox_strncpy(REG_MGBA_DEBUG_STRING, str.data(), sz); ox_strncpy(REG_MGBA_DEBUG_STRING, str.data(), sz);
REG_MGBA_DEBUG_FLAGS = chan | 0x100; REG_MGBA_DEBUG_FLAGS = chan | 0x100;
};
} }
void initConsole() { void initConsole() {
REG_MGBA_DEBUG_ENABLE = 0xC0DE; REG_MGBA_DEBUG_ENABLE = 0xC0DE;
if (REG_MGBA_DEBUG_ENABLE == 0x1DEA) { if (REG_MGBA_DEBUG_ENABLE == 0x1DEA) {
ox::hw::infoLog = mgba::mkLogger<LOG_INFO>(); infoLog = log<LogChan::Info>;
ox::hw::debugLog = mgba::mkLogger<LOG_INFO>(); // use INFO because mGBA disables DEBUG on start debugLog = log<LogChan::Info>; // use INFO because mGBA disables DEBUG on start
ox::hw::errorLog = mgba::mkLogger<LOG_ERROR>(); errorLog = log<LogChan::Error>;
} }
} }
@@ -84,15 +81,15 @@ void oxTraceHook([[maybe_unused]] const char *file, [[maybe_unused]] int line,
} }
#else #else
if (ox_strcmp(ch, "info") == 0) { if (ox_strcmp(ch, "info") == 0) {
ox::hw::infoLog(msg); infoLog(msg);
} else if (ox_strcmp(ch, "debug") == 0) { } else if (ox_strcmp(ch, "debug") == 0) {
ox::hw::debugLog(msg); debugLog(msg);
} else if (ox_strcmp(ch, "stdout") == 0) { } else if (ox_strcmp(ch, "stdout") == 0) {
ox::hw::infoLog(msg); infoLog(msg);
} else if (ox_strcmp(ch, "stderr") == 0) { } else if (ox_strcmp(ch, "stderr") == 0) {
ox::hw::errorLog(msg); errorLog(msg);
} else if (ox_strcmp(ch, "error") == 0) { } else if (ox_strcmp(ch, "error") == 0) {
ox::hw::errorLog(msg); errorLog(msg);
} }
#endif #endif
} }