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;
private:
using PtrType = typename PlatSpec::PtrType;
class UnionIdxTracker {
private:
int m_unionIdx = -1;
@@ -55,6 +56,14 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
};
ox::Vector<PtrPair> m_ptrs;
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) {}
@@ -86,7 +95,9 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>> {
template<typename T>
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;
@@ -156,7 +167,10 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
if constexpr(ox::is_integral_v<T>) {
return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val));
} 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>) {
return fieldVector(name, val);
} else {
@@ -188,7 +202,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::BasicStri
} else {
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.write(val->data(), sz));
oxReturnError(m_writer.seekp(restore));
@@ -230,14 +244,30 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const T **val, std:
}
template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::startAlloc(std::size_t sz) noexcept {
oxRequire(p, ox::allocate(&m_writer, sz));
return m_writer.seekp(p);
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(std::size_t sz) noexcept {
oxRequire(a, ox::allocate(&m_writer, sz));
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>
constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept {
if (m_allocStack.empty()) {
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>
@@ -306,7 +336,7 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView, const auto *v
}
// serialize the Vector
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 {};
}

View File

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