[nostalgia] Split part of Core out into Foundation, add module system
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
add_library(
|
||||
NostalgiaCore-Common OBJECT
|
||||
gfx.cpp
|
||||
media.cpp
|
||||
typeconv.cpp
|
||||
module.cpp
|
||||
typestore.cpp
|
||||
)
|
||||
|
||||
@@ -10,7 +9,6 @@ add_library(
|
||||
NostalgiaCore-Headless
|
||||
headless/core.cpp
|
||||
headless/gfx.cpp
|
||||
headless/media.cpp
|
||||
)
|
||||
|
||||
add_library(NostalgiaCore)
|
||||
@@ -23,7 +21,6 @@ if(NOT NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
|
||||
glfw/gfx.cpp
|
||||
userland/gfx.cpp
|
||||
userland/gfx_opengl.cpp
|
||||
userland/media.cpp
|
||||
)
|
||||
target_link_libraries(
|
||||
NostalgiaCore PUBLIC
|
||||
@@ -44,7 +41,6 @@ else()
|
||||
gba/gfx.cpp
|
||||
gba/irq.arm.cpp
|
||||
gba/irq.s
|
||||
gba/media.cpp
|
||||
gba/panic.cpp
|
||||
)
|
||||
target_link_libraries(
|
||||
@@ -59,8 +55,7 @@ endif()
|
||||
|
||||
target_link_libraries(
|
||||
NostalgiaCore-Common PUBLIC
|
||||
OxClaw
|
||||
OxFS
|
||||
NostalgiaFoundation
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
@@ -79,7 +74,6 @@ endif()
|
||||
|
||||
install(
|
||||
FILES
|
||||
assetmanager.hpp
|
||||
clipboard.hpp
|
||||
color.hpp
|
||||
config.hpp
|
||||
@@ -89,7 +83,6 @@ install(
|
||||
event.hpp
|
||||
gfx.hpp
|
||||
input.hpp
|
||||
media.hpp
|
||||
typeconv.hpp
|
||||
typestore.hpp
|
||||
DESTINATION
|
||||
|
||||
@@ -1,298 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/event/signal.hpp>
|
||||
#include <ox/fs/fs.hpp>
|
||||
#include <ox/model/typenamecatcher.hpp>
|
||||
#include <ox/std/hashmap.hpp>
|
||||
#include <ox/std/utility.hpp>
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
class AssetManager;
|
||||
|
||||
template<typename T>
|
||||
class AssetRef;
|
||||
|
||||
#ifndef OX_BARE_METAL
|
||||
template<typename T>
|
||||
class AssetContainer {
|
||||
|
||||
friend AssetManager;
|
||||
friend AssetRef<T>;
|
||||
|
||||
protected:
|
||||
ox::Signal<ox::Error()> updated;
|
||||
|
||||
private:
|
||||
T m_obj;
|
||||
mutable int m_references = 0;
|
||||
|
||||
public:
|
||||
template<class... Args>
|
||||
explicit constexpr AssetContainer(Args&&... args): m_obj(ox::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
AssetContainer(AssetContainer&) = delete;
|
||||
AssetContainer(AssetContainer&&) = delete;
|
||||
AssetContainer& operator=(AssetContainer&) = delete;
|
||||
AssetContainer& operator=(AssetContainer&&) = delete;
|
||||
|
||||
constexpr T *get() noexcept {
|
||||
return &m_obj;
|
||||
}
|
||||
|
||||
constexpr const T *get() const noexcept {
|
||||
return &m_obj;
|
||||
}
|
||||
|
||||
constexpr void set(T &&val) {
|
||||
m_obj = std::move(val);
|
||||
}
|
||||
|
||||
constexpr void set(const T &val) {
|
||||
m_obj = val;
|
||||
}
|
||||
|
||||
protected:
|
||||
constexpr void incRefs() const noexcept {
|
||||
++m_references;
|
||||
}
|
||||
|
||||
constexpr void decRefs() const noexcept {
|
||||
--m_references;
|
||||
}
|
||||
|
||||
constexpr int references() const noexcept {
|
||||
return m_references;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class AssetRef: public ox::SignalHandler {
|
||||
private:
|
||||
const AssetContainer<T> *m_ctr = nullptr;
|
||||
|
||||
public:
|
||||
ox::Signal<ox::Error()> updated;
|
||||
|
||||
explicit constexpr AssetRef(const AssetContainer<T> *c = nullptr) noexcept;
|
||||
|
||||
constexpr AssetRef(const AssetRef &h) noexcept;
|
||||
|
||||
constexpr AssetRef(AssetRef &&h) noexcept;
|
||||
|
||||
~AssetRef() noexcept override {
|
||||
if (m_ctr) {
|
||||
m_ctr->decRefs();
|
||||
}
|
||||
}
|
||||
|
||||
constexpr const T *get() const noexcept {
|
||||
if (m_ctr) {
|
||||
return m_ctr->get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
constexpr const T &operator*() const & noexcept {
|
||||
return *m_ctr->get();
|
||||
}
|
||||
|
||||
constexpr const T &&operator*() const && noexcept {
|
||||
return *m_ctr->get();
|
||||
}
|
||||
|
||||
constexpr const T *operator->() const noexcept {
|
||||
return m_ctr->get();
|
||||
}
|
||||
|
||||
AssetRef &operator=(const AssetRef &h) noexcept {
|
||||
if (this == &h) {
|
||||
return *this;
|
||||
}
|
||||
if (m_ctr) {
|
||||
m_ctr->decRefs();
|
||||
oxIgnoreError(m_ctr->updated.disconnectObject(this));
|
||||
}
|
||||
m_ctr = h.m_ctr;
|
||||
m_ctr->updated.connect(&updated, &ox::Signal<ox::Error()>::emitCheckError);
|
||||
if (m_ctr) {
|
||||
m_ctr->incRefs();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
AssetRef &operator=(AssetRef &&h) noexcept {
|
||||
if (this == &h) {
|
||||
return *this;
|
||||
}
|
||||
if (m_ctr) {
|
||||
m_ctr->decRefs();
|
||||
oxIgnoreError(m_ctr->updated.disconnectObject(this));
|
||||
}
|
||||
m_ctr = h.m_ctr;
|
||||
m_ctr->updated.connect(this, &AssetRef::emitUpdated);
|
||||
h.m_ctr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit constexpr operator bool() const noexcept {
|
||||
return m_ctr;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr ox::Error emitUpdated() const noexcept {
|
||||
updated.emit();
|
||||
return OxError(0);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr AssetRef<T>::AssetRef(const AssetContainer<T> *c) noexcept: m_ctr(c) {
|
||||
if (c) {
|
||||
c->updated.connect(this, &AssetRef::emitUpdated);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr AssetRef<T>::AssetRef(const AssetRef &h) noexcept {
|
||||
m_ctr = h.m_ctr;
|
||||
if (m_ctr) {
|
||||
m_ctr->updated.connect(this, &AssetRef::emitUpdated);
|
||||
m_ctr->incRefs();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr AssetRef<T>::AssetRef(AssetRef &&h) noexcept {
|
||||
m_ctr = h.m_ctr;
|
||||
m_ctr->updated.connect(this, &AssetRef::emitUpdated);
|
||||
h.m_ctr = nullptr;
|
||||
}
|
||||
|
||||
class AssetManager {
|
||||
private:
|
||||
class AssetTypeManagerBase {
|
||||
public:
|
||||
virtual ~AssetTypeManagerBase() = default;
|
||||
|
||||
virtual void gc() noexcept = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class AssetTypeManager: public AssetTypeManagerBase {
|
||||
private:
|
||||
ox::HashMap<ox::String, ox::UniquePtr<AssetContainer<T>>> m_cache;
|
||||
|
||||
public:
|
||||
ox::Result<AssetRef<T>> getAsset(const ox::String &path) const noexcept {
|
||||
auto out = m_cache.at(path);
|
||||
oxReturnError(out);
|
||||
return AssetRef<T>(out.value->get());
|
||||
}
|
||||
|
||||
ox::Result<AssetRef<T>> setAsset(const ox::String &path, const T &obj) noexcept {
|
||||
auto &p = m_cache[path];
|
||||
if (!p) {
|
||||
p = ox::make_unique<AssetContainer<T>>(obj);
|
||||
} else {
|
||||
p->set(obj);
|
||||
p->updated.emit();
|
||||
}
|
||||
return AssetRef<T>(p.get());
|
||||
}
|
||||
|
||||
ox::Result<AssetRef<T>> setAsset(const ox::String &path, T &&obj) noexcept {
|
||||
auto &p = m_cache[path];
|
||||
if (!p) {
|
||||
p = ox::make_unique<AssetContainer<T>>(obj);
|
||||
} else {
|
||||
p->set(std::move(obj));
|
||||
p->updated.emit();
|
||||
}
|
||||
return AssetRef<T>(p.get());
|
||||
}
|
||||
|
||||
void gc() noexcept final {
|
||||
for (const auto &ack : m_cache.keys()) {
|
||||
auto &ac = m_cache[ack];
|
||||
if (ac->references()) {
|
||||
m_cache.erase(ack);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ox::HashMap<ox::String, ox::UniquePtr<AssetTypeManagerBase>> m_assetTypeManagers;
|
||||
|
||||
template<typename T>
|
||||
AssetTypeManager<T> *getTypeManager() noexcept {
|
||||
constexpr auto typeName = ox::requireModelTypeName<T>();
|
||||
static_assert(ox_strcmp(typeName, "") != 0, "Types must have TypeName to use AssetManager");
|
||||
auto &am = m_assetTypeManagers[typeName];
|
||||
if (!am) {
|
||||
am = ox::make_unique<AssetTypeManager<T>>();
|
||||
}
|
||||
return dynamic_cast<AssetTypeManager<T>*>(am.get());
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
ox::Result<AssetRef<T>> getAsset(const ox::String &path) noexcept {
|
||||
auto m = getTypeManager<T>();
|
||||
return m->getAsset(path);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ox::Result<AssetRef<T>> setAsset(const ox::String &path, const T &obj) noexcept {
|
||||
auto m = getTypeManager<T>();
|
||||
return m->setAsset(path, obj);
|
||||
}
|
||||
|
||||
void gc() noexcept {
|
||||
for (const auto &amk : m_assetTypeManagers.keys()) {
|
||||
auto &am = m_assetTypeManagers[amk];
|
||||
am->gc();
|
||||
}
|
||||
}
|
||||
};
|
||||
#else
|
||||
template<typename T>
|
||||
class AssetRef {
|
||||
private:
|
||||
const T *m_obj = nullptr;
|
||||
|
||||
public:
|
||||
constexpr AssetRef() noexcept = default;
|
||||
|
||||
explicit constexpr AssetRef(const T *obj) noexcept: m_obj(obj) {
|
||||
}
|
||||
|
||||
constexpr const T *get() const noexcept {
|
||||
return m_obj;
|
||||
}
|
||||
|
||||
constexpr const T &operator*() const & noexcept {
|
||||
return *m_obj;
|
||||
}
|
||||
|
||||
constexpr const T &&operator*() const && noexcept {
|
||||
return *m_obj;
|
||||
}
|
||||
|
||||
constexpr const T *operator->() const noexcept {
|
||||
return m_obj;
|
||||
}
|
||||
|
||||
explicit constexpr operator bool() const noexcept {
|
||||
return m_obj;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/fs/fs.hpp>
|
||||
#include <ox/model/desctypes.hpp>
|
||||
#include <ox/std/buffer.hpp>
|
||||
|
||||
#include "assetmanager.hpp"
|
||||
#include <nostalgia/foundation/context.hpp>
|
||||
|
||||
#include "event.hpp"
|
||||
#include "input.hpp"
|
||||
|
||||
@@ -19,15 +21,14 @@ namespace nostalgia::core {
|
||||
|
||||
class BaseClipboardObject {
|
||||
public:
|
||||
virtual ~BaseClipboardObject() = default;
|
||||
virtual ~BaseClipboardObject() noexcept = default;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual ox::String typeId() const noexcept = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto typeMatch(auto name, auto version) const noexcept {
|
||||
auto inId = ox::sfmt("{};{}", name, version);
|
||||
return typeId() == inId;
|
||||
return typeId() == ox::buildTypeId(name, version);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -35,7 +36,7 @@ template<typename T>
|
||||
class ClipboardObject: public BaseClipboardObject {
|
||||
[[nodiscard]]
|
||||
ox::String typeId() const noexcept final {
|
||||
return ox::sfmt("{};{}", T::TypeName, T::TypeVersion);
|
||||
return ox::buildTypeId(T::TypeName, T::TypeVersion);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,7 +47,7 @@ struct BgCbbData {
|
||||
};
|
||||
|
||||
// User Input Output
|
||||
class Context {
|
||||
class Context: public foundation::Context {
|
||||
friend constexpr void setApplicationData(Context *ctx, void *applicationData) noexcept;
|
||||
template<typename T>
|
||||
friend constexpr T *applicationData(Context *ctx) noexcept;
|
||||
@@ -68,7 +69,7 @@ class Context {
|
||||
const struct CompactTileSheet &tilesheetAddr) noexcept;
|
||||
friend ox::Error run(Context *ctx) noexcept;
|
||||
friend void shutdown(Context *ctx) noexcept;
|
||||
friend ox::Result<ox::UniquePtr<Context>> init(ox::UniquePtr<ox::FileSystem> fs, ox::CRStringView appName) noexcept;
|
||||
friend ox::Result<ox::UPtr<Context>> init(ox::UPtr<ox::FileSystem> fs, ox::CRStringView appName) noexcept;
|
||||
friend ox::String getClipboardText(Context *ctx) noexcept;
|
||||
friend uint64_t ticksMs(Context *ctx) noexcept;
|
||||
friend uint8_t bgStatus(Context *ctx) noexcept;
|
||||
@@ -93,17 +94,13 @@ class Context {
|
||||
friend void hideSprite(Context *ctx, unsigned idx) noexcept;
|
||||
|
||||
public:
|
||||
ox::UniquePtr<ox::FileSystem> rom;
|
||||
ox::Vector<Drawer*, 5> drawers;
|
||||
ox::StringView appName = "Nostalgia";
|
||||
|
||||
#ifndef OX_BARE_METAL
|
||||
AssetManager assetManager;
|
||||
int uninterruptedRefreshes = 3;
|
||||
ox::UniquePtr<BaseClipboardObject> clipboard;
|
||||
ox::UPtr<BaseClipboardObject> clipboard;
|
||||
#else
|
||||
bool running = true;
|
||||
std::size_t preloadSectionOffset = 0;
|
||||
#endif
|
||||
protected:
|
||||
#ifndef OX_BARE_METAL
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/fs/fs.hpp>
|
||||
|
||||
#include "assetmanager.hpp"
|
||||
#include "clipboard.hpp"
|
||||
#include "consts.hpp"
|
||||
#include "event.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "input.hpp"
|
||||
#include "media.hpp"
|
||||
#include "module.hpp"
|
||||
#include "typeconv.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/fs/fs.hpp>
|
||||
#include <ox/mc/mc.hpp>
|
||||
#include <ox/std/array.hpp>
|
||||
|
||||
#include <nostalgia/core/media.hpp>
|
||||
#include <nostalgia/foundation/media.hpp>
|
||||
#include <nostalgia/core/context.hpp>
|
||||
#include <nostalgia/core/gfx.hpp>
|
||||
|
||||
#include "addresses.hpp"
|
||||
@@ -129,7 +130,7 @@ ox::Error initConsole(Context *ctx) noexcept {
|
||||
setBgStatus(ctx, 0b0001);
|
||||
if (!ctx) {
|
||||
ctx = new (ox_alloca(sizeof(Context))) Context();
|
||||
oxRequire(rom, loadRom());
|
||||
oxRequire(rom, foundation::loadRom());
|
||||
ox::FileStore32 fs(rom, 32 * ox::units::MB);
|
||||
auto romFs = new (ox_alloca(sizeof(ox::FileSystem32))) ox::FileSystem32(fs);
|
||||
new (&ctx->rom) ox::UniquePtr<ox::FileSystem>(romFs);
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/mc/read.hpp>
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
#include "../media.hpp"
|
||||
|
||||
#include "addresses.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
ox::Result<char*> loadRom(ox::CRStringView) noexcept {
|
||||
// put the header in the wrong order to prevent mistaking this code for the
|
||||
// media section
|
||||
constexpr auto headerP2 = "HEADER__________";
|
||||
constexpr auto headerP1 = "NOSTALGIA_MEDIA_";
|
||||
constexpr auto headerP1Len = ox_strlen(headerP2);
|
||||
constexpr auto headerP2Len = ox_strlen(headerP1);
|
||||
constexpr auto headerLen = headerP1Len + headerP2Len;
|
||||
for (auto current = MEM_ROM; current < reinterpret_cast<char*>(0x0a000000); current += headerLen) {
|
||||
if (ox_memcmp(current, headerP1, headerP1Len) == 0 &&
|
||||
ox_memcmp(current + headerP1Len, headerP2, headerP2Len) == 0) {
|
||||
return current + headerLen;
|
||||
}
|
||||
}
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
void unloadRom(char*) noexcept {
|
||||
}
|
||||
|
||||
ox::Result<std::size_t> getPreloadAddr(Context *ctx, ox::CRStringView path) noexcept {
|
||||
oxRequire(stat, ctx->rom->stat(path));
|
||||
oxRequire(buff, static_cast<ox::MemFS*>(ctx->rom.get())->directAccess(path));
|
||||
PreloadPtr p;
|
||||
oxReturnError(ox::readMC(buff, stat.size, &p));
|
||||
return p.preloadAddr + ctx->preloadSectionOffset;
|
||||
}
|
||||
|
||||
ox::Result<std::size_t> getPreloadAddr(Context *ctx, const ox::FileAddress &file) noexcept {
|
||||
oxRequire(stat, ctx->rom->stat(file));
|
||||
oxRequire(buff, static_cast<ox::MemFS*>(ctx->rom.get())->directAccess(file));
|
||||
PreloadPtr p;
|
||||
oxReturnError(ox::readMC(buff, stat.size, &p));
|
||||
return p.preloadAddr + ctx->preloadSectionOffset;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <nostalgia/foundation/foundation.hpp>
|
||||
#include <nostalgia/core/gfx.hpp>
|
||||
#include <nostalgia/core/input.hpp>
|
||||
#include <nostalgia/core/userland/gfx.hpp>
|
||||
@@ -13,10 +14,8 @@
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
ox::Result<ox::UniquePtr<Context>> init(ox::UniquePtr<ox::FileSystem> fs, ox::CRStringView appName) noexcept {
|
||||
auto ctx = ox::make_unique<Context>();
|
||||
ctx->rom = std::move(fs);
|
||||
ctx->appName = appName;
|
||||
ox::Result<ox::UPtr<Context>> init(ox::UPtr<ox::FileSystem> fs, ox::CRStringView appName) noexcept {
|
||||
auto ctx = foundation::init<Context>(std::move(fs), appName);
|
||||
const auto id = ox::make<GlfwImplData>();
|
||||
ctx->setWindowerData(id);
|
||||
using namespace std::chrono;
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
#include "../media.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
ox::Result<char*> loadRom(ox::CRStringView) noexcept {
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
void unloadRom(char*) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include "media.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
ox::Result<ox::UniquePtr<ox::FileSystem>> loadRomFs(ox::CRStringView path) noexcept {
|
||||
const auto lastDot = ox_lastIndexOf(path, '.');
|
||||
const auto fsExt = lastDot != -1 ? path.substr(static_cast<std::size_t>(lastDot)) : "";
|
||||
if (ox_strcmp(fsExt, ".oxfs") == 0) {
|
||||
oxRequire(rom, core::loadRom(path));
|
||||
return {ox::make_unique<ox::FileSystem32>(rom, 32 * ox::units::MB, unloadRom)};
|
||||
} else {
|
||||
#ifdef OX_HAS_PASSTHROUGHFS
|
||||
return {ox::make_unique<ox::PassThroughFS>(path)};
|
||||
#else
|
||||
return OxError(2);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/defines.hpp>
|
||||
|
||||
#include <ox/claw/claw.hpp>
|
||||
#include <ox/fs/fs.hpp>
|
||||
#include <ox/model/metadata.hpp>
|
||||
|
||||
#include "context.hpp"
|
||||
#include "typeconv.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
struct PreloadPtr {
|
||||
static constexpr auto TypeName = "net.drinkingtea.ox.PreloadPtr";
|
||||
static constexpr auto TypeVersion = 1;
|
||||
uint32_t preloadAddr = 0;
|
||||
};
|
||||
|
||||
oxModelBegin(PreloadPtr)
|
||||
oxModelField(preloadAddr)
|
||||
oxModelEnd()
|
||||
|
||||
ox::Result<std::size_t> getPreloadAddr(Context *ctx, const ox::FileAddress &file) noexcept;
|
||||
ox::Result<std::size_t> getPreloadAddr(Context *ctx, ox::CRStringView file) noexcept;
|
||||
|
||||
template<typename T>
|
||||
ox::Result<AssetRef<T>> readObj([[maybe_unused]] Context *ctx, [[maybe_unused]] ox::CRStringView path,
|
||||
[[maybe_unused]] bool forceLoad = false) noexcept {
|
||||
#ifndef OX_BARE_METAL
|
||||
constexpr auto readConvert = [](const ox::Buffer &buff) -> ox::Result<T> {
|
||||
auto [obj, err] = ox::readClaw<T>(buff);
|
||||
if (err) {
|
||||
if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) {
|
||||
return err;
|
||||
}
|
||||
oxReturnError(convert<T>(buff, &obj));
|
||||
}
|
||||
return std::move(obj);
|
||||
};
|
||||
if (forceLoad) {
|
||||
oxRequire(buff, ctx->rom->read(path));
|
||||
oxRequire(obj, readConvert(buff));
|
||||
oxRequire(cached, ctx->assetManager.setAsset(path, obj));
|
||||
return std::move(cached);
|
||||
} else {
|
||||
auto [cached, err] = ctx->assetManager.getAsset<T>(path);
|
||||
if (err) {
|
||||
oxRequire(buff, ctx->rom->read(path));
|
||||
oxRequire(obj, readConvert(buff));
|
||||
oxReturnError(ctx->assetManager.setAsset(path, obj).moveTo(&cached));
|
||||
}
|
||||
return std::move(cached);
|
||||
}
|
||||
#else
|
||||
if constexpr(ox::preloadable<T>::value) {
|
||||
oxRequire(addr, getPreloadAddr(ctx, path));
|
||||
return AssetRef<T>(reinterpret_cast<const T*>(addr));
|
||||
} else {
|
||||
return OxError(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ox::Result<AssetRef<T>> readObj(Context *ctx, const ox::FileAddress &file,
|
||||
[[maybe_unused]] bool forceLoad = false) noexcept {
|
||||
#ifndef OX_BARE_METAL
|
||||
oxRequire(path, file.getPath());
|
||||
return readObj<T>(ctx, ox::StringView(path), forceLoad);
|
||||
#else
|
||||
if constexpr(ox::preloadable<T>::value) {
|
||||
oxRequire(addr, getPreloadAddr(ctx, file));
|
||||
return AssetRef<T>(reinterpret_cast<const T*>(addr));
|
||||
} else {
|
||||
return OxError(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ox::Error writeObj(Context *ctx, const ox::FileAddress &file, const T &obj,
|
||||
ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept {
|
||||
oxRequire(objBuff, ox::writeClaw(&obj, fmt));
|
||||
return ctx->rom->write(file, objBuff.data(), objBuff.size());
|
||||
}
|
||||
|
||||
ox::Result<ox::UniquePtr<ox::FileSystem>> loadRomFs(ox::CRStringView path) noexcept;
|
||||
|
||||
ox::Result<char*> loadRom(ox::CRStringView path = "") noexcept;
|
||||
|
||||
void unloadRom(char*) noexcept;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nostalgia/foundation/module.hpp>
|
||||
|
||||
#include "typeconv.hpp"
|
||||
|
||||
#include "module.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
ox::Vector<foundation::BaseConverter*> CoreModule::converters() const noexcept {
|
||||
return {
|
||||
&nostalgiaPaletteToPaletteConverter,
|
||||
&nostalgiaGraphicToTileSheetConverter,
|
||||
&tileSheetToCompactTileSheetConverter,
|
||||
};
|
||||
}
|
||||
|
||||
CoreModule CoreModule::mod;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <nostalgia/foundation/module.hpp>
|
||||
|
||||
#include "typeconv.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
class CoreModule: public foundation::Module {
|
||||
private:
|
||||
mutable NostalgiaPaletteToPaletteConverter nostalgiaPaletteToPaletteConverter;
|
||||
mutable NostalgiaGraphicToTileSheetConverter nostalgiaGraphicToTileSheetConverter;
|
||||
mutable TileSheetToCompactTileSheetConverter tileSheetToCompactTileSheetConverter;
|
||||
|
||||
public:
|
||||
static CoreModule mod;
|
||||
[[nodiscard]]
|
||||
ox::Vector<foundation::BaseConverter*> converters() const noexcept override;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
ox::Vector<studio::EditorMaker> Module::editors(core::Context *ctx) noexcept {
|
||||
ox::Vector<studio::EditorMaker> StudioModule::editors(core::Context *ctx) noexcept {
|
||||
return {
|
||||
{
|
||||
{"ng"},
|
||||
@@ -32,7 +32,7 @@ ox::Vector<studio::EditorMaker> Module::editors(core::Context *ctx) noexcept {
|
||||
};
|
||||
}
|
||||
|
||||
ox::Vector<ox::UniquePtr<studio::ItemMaker>> Module::itemMakers(core::Context*) noexcept {
|
||||
ox::Vector<ox::UniquePtr<studio::ItemMaker>> StudioModule::itemMakers(core::Context*) noexcept {
|
||||
ox::Vector<ox::UniquePtr<studio::ItemMaker>> out;
|
||||
out.emplace_back(ox::make<studio::ItemMakerT<core::TileSheet>>("Tile Sheet", "TileSheets", "ng"));
|
||||
out.emplace_back(ox::make<studio::ItemMakerT<core::Palette>>("Palette", "Palettes", "npal"));
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
class Module: public studio::Module {
|
||||
class StudioModule: public studio::Module {
|
||||
public:
|
||||
ox::Vector<studio::EditorMaker> editors(core::Context *ctx) noexcept override;
|
||||
ox::Vector<ox::UniquePtr<studio::ItemMaker>> itemMakers(core::Context*) noexcept override;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include <nostalgia/core/gfx.hpp>
|
||||
#include <nostalgia/core/media.hpp>
|
||||
#include <nostalgia/foundation/media.hpp>
|
||||
#include <ox/std/memory.hpp>
|
||||
|
||||
#include "paletteeditor.hpp"
|
||||
@@ -19,7 +19,7 @@ ox::Result<PaletteEditorImGui*> PaletteEditorImGui::make(Context *ctx, ox::CRStr
|
||||
out->m_itemPath = path;
|
||||
const auto lastSlash = std::find(out->m_itemPath.rbegin(), out->m_itemPath.rend(), '/').offset();
|
||||
out->m_itemName = out->m_itemPath.substr(lastSlash + 1);
|
||||
oxRequire(pal, core::readObj<Palette>(out->m_ctx, ox::FileAddress(out->m_itemPath.c_str())));
|
||||
oxRequire(pal, foundation::readObj<Palette>(out->m_ctx, ox::FileAddress(out->m_itemPath.c_str())));
|
||||
out->m_pal = *pal;
|
||||
return out.release();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <imgui.h>
|
||||
#include <lodepng.h>
|
||||
|
||||
#include <nostalgia/core/media.hpp>
|
||||
#include <nostalgia/foundation/media.hpp>
|
||||
#include <nostalgia/geo/point.hpp>
|
||||
|
||||
#include "tilesheeteditor-imgui.hpp"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <ox/std/memory.hpp>
|
||||
|
||||
#include <nostalgia/core/clipboard.hpp>
|
||||
#include <nostalgia/core/media.hpp>
|
||||
#include <nostalgia/foundation/media.hpp>
|
||||
|
||||
#include "tilesheeteditormodel.hpp"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -23,7 +23,7 @@ class TileSheetEditorModel: public ox::SignalHandler {
|
||||
static const Palette s_defaultPalette;
|
||||
TileSheet m_img;
|
||||
TileSheet::SubSheetIdx m_activeSubsSheetIdx;
|
||||
AssetRef<Palette> m_pal;
|
||||
foundation::AssetRef<Palette> m_pal;
|
||||
studio::UndoStack m_undoStack;
|
||||
class DrawCommand *m_ongoingDrawCommand = nullptr;
|
||||
bool m_updated = false;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nostalgia/core/consts.hpp>
|
||||
#include <nostalgia/core/media.hpp>
|
||||
#include <nostalgia/foundation/media.hpp>
|
||||
#include <nostalgia/geo/point.hpp>
|
||||
|
||||
#include "tilesheeteditorview.hpp"
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/claw/read.hpp>
|
||||
|
||||
#include "gfx.hpp"
|
||||
|
||||
#include "typeconv.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
struct NostalgiaGraphicToTileSheetConverter: public Converter<NostalgiaGraphic, TileSheet> {
|
||||
ox::Error convert(NostalgiaGraphic *src, TileSheet *dst) noexcept final {
|
||||
dst->bpp = src->bpp;
|
||||
dst->subsheet.name = "Root";
|
||||
dst->subsheet.rows = src->rows;
|
||||
dst->subsheet.columns = src->columns;
|
||||
dst->defaultPalette = std::move(src->defaultPalette);
|
||||
dst->subsheet.pixels = std::move(src->pixels);
|
||||
return OxError(0);
|
||||
}
|
||||
};
|
||||
|
||||
struct NostalgiaPaletteToPaletteConverter: public Converter<NostalgiaPalette, Palette> {
|
||||
ox::Error convert(NostalgiaPalette *src, Palette *dst) noexcept final {
|
||||
dst->colors = std::move(src->colors);
|
||||
return OxError(0);
|
||||
}
|
||||
};
|
||||
|
||||
struct TileSheetToCompactTileSheetConverter: public Converter<TileSheet, CompactTileSheet> {
|
||||
ox::Error convert(TileSheet *src, CompactTileSheet *dst) noexcept final {
|
||||
dst->bpp = src->bpp;
|
||||
dst->defaultPalette = std::move(src->defaultPalette);
|
||||
dst->pixels = src->pixels();
|
||||
return OxError(0);
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef OX_BARE_METAL
|
||||
|
||||
static const auto converters = [] {
|
||||
ox::Vector<ox::UniquePtr<BaseConverter>, 3> converters;
|
||||
converters.emplace_back(ox::make<NostalgiaGraphicToTileSheetConverter>());
|
||||
converters.emplace_back(ox::make<NostalgiaPaletteToPaletteConverter>());
|
||||
converters.emplace_back(ox::make<TileSheetToCompactTileSheetConverter>());
|
||||
return converters;
|
||||
}();
|
||||
|
||||
[[nodiscard]]
|
||||
static auto findConverter(ox::CRStringView srcTypeName, int srcTypeVersion,
|
||||
ox::CRStringView dstTypeName, int dstTypeVersion) noexcept -> ox::Result<BaseConverter*> {
|
||||
for (auto &c : converters) {
|
||||
if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) {
|
||||
return c.get();
|
||||
}
|
||||
}
|
||||
return OxError(1, "Could not find converter");
|
||||
};
|
||||
|
||||
static ox::Result<ox::UniquePtr<Wrap>> convert(const ox::Buffer &srcBuffer,
|
||||
ox::CRStringView srcTypeName, int srcTypeVersion,
|
||||
ox::CRStringView dstTypeName, int dstTypeVersion) noexcept {
|
||||
// look for direct converter
|
||||
auto [c, err] = findConverter(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion);
|
||||
if (!err) {
|
||||
return c->convertBuffToPtr(srcBuffer);
|
||||
}
|
||||
// try to chain multiple converters
|
||||
for (const auto &subConverter : converters) {
|
||||
if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) {
|
||||
continue;
|
||||
}
|
||||
const auto [intermediate, chainErr] =
|
||||
convert(srcBuffer, srcTypeName, srcTypeVersion,
|
||||
subConverter->srcTypeName(), subConverter->srcTypeVersion());
|
||||
if (!chainErr) {
|
||||
return subConverter->convertPtrToPtr(intermediate.get());
|
||||
}
|
||||
}
|
||||
return OxError(1, "Could not convert between types");
|
||||
}
|
||||
|
||||
ox::Result<ox::UniquePtr<Wrap>> convert(const ox::Buffer &srcBuffer, ox::CRStringView dstTypeName, int dstTypeVersion) noexcept {
|
||||
oxRequire(hdr, ox::readClawHeader(srcBuffer));
|
||||
return convert(srcBuffer, hdr.typeName, hdr.typeVersion, dstTypeName, dstTypeVersion);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
+30
-131
@@ -1,152 +1,51 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gfx.hpp"
|
||||
|
||||
#include <nostalgia/foundation/typeconv.hpp>
|
||||
|
||||
#include <ox/std/def.hpp>
|
||||
#include <ox/std/error.hpp>
|
||||
#include <ox/std/optional.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
#include <ox/claw/read.hpp>
|
||||
#include <ox/claw/write.hpp>
|
||||
|
||||
#include "context.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
class Wrap {
|
||||
public:
|
||||
virtual ~Wrap() = default;
|
||||
// Type converters
|
||||
|
||||
struct NostalgiaPaletteToPaletteConverter: public foundation::Converter<NostalgiaPalette, Palette> {
|
||||
ox::Error convert(foundation::Context*, NostalgiaPalette *src, Palette *dst) noexcept final {
|
||||
dst->colors = std::move(src->colors);
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class WrapInline: public Wrap {
|
||||
private:
|
||||
T m_obj;
|
||||
|
||||
public:
|
||||
constexpr WrapInline() = default;
|
||||
|
||||
template<typename... Args>
|
||||
constexpr explicit WrapInline(Args &&...args): m_obj(ox::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto obj() noexcept {
|
||||
return &m_obj;
|
||||
}
|
||||
|
||||
struct NostalgiaGraphicToTileSheetConverter: public foundation::Converter<NostalgiaGraphic, TileSheet> {
|
||||
ox::Error convert(foundation::Context*, NostalgiaGraphic *src, TileSheet *dst) noexcept final {
|
||||
dst->bpp = src->bpp;
|
||||
dst->subsheet.name = "Root";
|
||||
dst->subsheet.rows = src->rows;
|
||||
dst->subsheet.columns = src->columns;
|
||||
dst->defaultPalette = std::move(src->defaultPalette);
|
||||
dst->subsheet.pixels = std::move(src->pixels);
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename... Args>
|
||||
constexpr auto makeWrap(Args &&...args) noexcept {
|
||||
return ox::make_unique<WrapInline<T>>(ox::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr auto wrapCast(auto ptr) noexcept {
|
||||
return static_cast<WrapInline<T>*>(ptr)->obj();
|
||||
}
|
||||
|
||||
struct BaseConverter {
|
||||
virtual ~BaseConverter() noexcept = default;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual ox::StringView srcTypeName() noexcept = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual int srcTypeVersion() noexcept = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual bool srcMatches(ox::CRStringView srcTypeName, int srcTypeVersion) const noexcept = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual bool dstMatches(ox::CRStringView dstTypeName, int dstTypeVersion) const noexcept = 0;
|
||||
|
||||
virtual ox::Result<ox::UniquePtr<Wrap>> convertPtrToPtr(Wrap *src) noexcept = 0;
|
||||
|
||||
virtual ox::Result<ox::UniquePtr<Wrap>> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool matches(ox::CRStringView srcTypeName, int srcTypeVersion,
|
||||
ox::CRStringView dstTypeName, int dstTypeVersion) const noexcept {
|
||||
return srcMatches(srcTypeName, srcTypeVersion)
|
||||
&& dstMatches(dstTypeName, dstTypeVersion);
|
||||
struct TileSheetToCompactTileSheetConverter: public foundation::Converter<TileSheet, CompactTileSheet> {
|
||||
ox::Error convert(foundation::Context*, TileSheet *src, CompactTileSheet *dst) noexcept final {
|
||||
dst->bpp = src->bpp;
|
||||
dst->defaultPalette = std::move(src->defaultPalette);
|
||||
dst->pixels = src->pixels();
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename SrcType, typename DstType>
|
||||
struct Converter: public BaseConverter {
|
||||
|
||||
virtual ox::Error convert(SrcType*, DstType*) noexcept = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
ox::StringView srcTypeName() noexcept final {
|
||||
return ox::requireModelTypeName<SrcType>();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
int srcTypeVersion() noexcept final {
|
||||
return ox::requireModelTypeVersion<SrcType>();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool srcMatches(ox::CRStringView srcTypeName, int srcTypeVersion) const noexcept final {
|
||||
static constexpr auto SrcTypeName = ox::requireModelTypeName<SrcType>();
|
||||
static constexpr auto SrcTypeVersion = ox::requireModelTypeVersion<SrcType>();
|
||||
return ox_strcmp(srcTypeName, SrcTypeName) == 0
|
||||
&& srcTypeVersion == SrcTypeVersion;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool dstMatches(ox::CRStringView dstTypeName, int dstTypeVersion) const noexcept final {
|
||||
static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
|
||||
static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
|
||||
return ox_strcmp(dstTypeName, DstTypeName) == 0
|
||||
&& dstTypeVersion == DstTypeVersion;
|
||||
}
|
||||
|
||||
ox::Result<ox::UniquePtr<Wrap>> convertPtrToPtr(Wrap *src) noexcept final {
|
||||
auto dst = makeWrap<DstType>();
|
||||
oxReturnError(convert(wrapCast<SrcType>(src), wrapCast<DstType>(dst.get())));
|
||||
return ox::Result<ox::UniquePtr<Wrap>>(std::move(dst));
|
||||
}
|
||||
|
||||
ox::Result<ox::UniquePtr<Wrap>> convertBuffToPtr(const ox::Buffer &srcBuff) noexcept final {
|
||||
oxRequireM(src, ox::readClaw<SrcType>(srcBuff));
|
||||
auto dst = makeWrap<DstType>();
|
||||
oxReturnError(convert(&src, wrapCast<DstType>(dst.get())));
|
||||
return ox::Result<ox::UniquePtr<Wrap>>(std::move(dst));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ox::Result<ox::UniquePtr<Wrap>> convert(const ox::Buffer &srcBuffer,
|
||||
ox::CRStringView dstTypeName, int dstTypeVersion) noexcept;
|
||||
|
||||
template<typename DstType>
|
||||
ox::Result<DstType> convert(const ox::Buffer &srcBuffer) noexcept {
|
||||
static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
|
||||
static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
|
||||
oxRequire(out, convert(srcBuffer, DstTypeName, DstTypeVersion));
|
||||
return wrapCast<DstType>(out);
|
||||
}
|
||||
|
||||
template<typename DstType>
|
||||
ox::Error convert(const ox::Buffer &buff, DstType *outObj) noexcept {
|
||||
static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
|
||||
static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
|
||||
oxRequire(outPtr, convert(buff, DstTypeName, DstTypeVersion));
|
||||
*outObj = std::move(*wrapCast<DstType>(outPtr.get()));
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename DstType>
|
||||
ox::Result<ox::Buffer> convertBuffToBuff(const ox::Buffer &srcBuffer, ox::ClawFormat fmt) noexcept {
|
||||
static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
|
||||
static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
|
||||
oxRequire(out, convert(srcBuffer, DstTypeName, DstTypeVersion));
|
||||
return ox::writeClaw<DstType>(wrapCast<DstType>(out.get()), fmt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include "typestore.hpp"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nostalgia/core/gfx.hpp>
|
||||
#include <nostalgia/core/media.hpp>
|
||||
#include <nostalgia/foundation/media.hpp>
|
||||
|
||||
#include "gfx.hpp"
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <ox/std/trace.hpp>
|
||||
|
||||
#include "../media.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
ox::Result<char*> loadRom(ox::CRStringView path) noexcept {
|
||||
std::ifstream file(std::string(toStdStringView(path)), std::ios::binary | std::ios::ate);
|
||||
if (!file.good()) {
|
||||
oxErrorf("Could not find ROM file: {}", path);
|
||||
return OxError(1, "Could not find ROM file");
|
||||
}
|
||||
try {
|
||||
const auto size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
auto buff = new char[static_cast<std::size_t>(size)];
|
||||
file.read(buff, size);
|
||||
return buff;
|
||||
} catch (const std::ios_base::failure &e) {
|
||||
oxErrorf("Could not read ROM file: {}", e.what());
|
||||
return OxError(2, "Could not read ROM file");
|
||||
}
|
||||
}
|
||||
|
||||
void unloadRom(char *rom) noexcept {
|
||||
ox::safeDelete(rom);
|
||||
}
|
||||
|
||||
ox::Result<void*> findPreloadSection() noexcept {
|
||||
return OxError(1, "findPreloadSection is unsupported on this platform");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user