[nostalgia] Split part of Core out into Foundation, add module system
This commit is contained in:
		@@ -1,7 +1,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#project packages
 | 
					#project packages
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_subdirectory(appmodules)
 | 
				
			||||||
add_subdirectory(core)
 | 
					add_subdirectory(core)
 | 
				
			||||||
 | 
					add_subdirectory(foundation)
 | 
				
			||||||
add_subdirectory(geo)
 | 
					add_subdirectory(geo)
 | 
				
			||||||
add_subdirectory(scene)
 | 
					add_subdirectory(scene)
 | 
				
			||||||
add_subdirectory(world)
 | 
					add_subdirectory(world)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								src/nostalgia/appmodules/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/nostalgia/appmodules/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					add_library(
 | 
				
			||||||
 | 
						NostalgiaAppModules OBJECT
 | 
				
			||||||
 | 
							appmodules.cpp
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(NOT MSVC)
 | 
				
			||||||
 | 
						target_compile_options(NostalgiaAppModules PRIVATE -Wsign-conversion)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_link_libraries(
 | 
				
			||||||
 | 
						NostalgiaAppModules PUBLIC
 | 
				
			||||||
 | 
							NostalgiaCore
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install(
 | 
				
			||||||
 | 
						FILES
 | 
				
			||||||
 | 
							appmodules.hpp
 | 
				
			||||||
 | 
						DESTINATION
 | 
				
			||||||
 | 
							include/nostalgia/appmodules
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										27
									
								
								src/nostalgia/appmodules/appmodules.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/nostalgia/appmodules/appmodules.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ox/std/array.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nostalgia/foundation/module.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nostalgia/core/module.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loadModules() noexcept {
 | 
				
			||||||
 | 
						static bool done = false;
 | 
				
			||||||
 | 
						if (done) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						const ox::Array<foundation::Module*, 1> mods = {
 | 
				
			||||||
 | 
							&core::CoreModule::mod,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						for (const auto m : mods) {
 | 
				
			||||||
 | 
							foundation::registerModule(m);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						done = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								src/nostalgia/appmodules/appmodules.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/nostalgia/appmodules/appmodules.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loadModules() noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,8 +1,7 @@
 | 
				
			|||||||
add_library(
 | 
					add_library(
 | 
				
			||||||
	NostalgiaCore-Common OBJECT
 | 
						NostalgiaCore-Common OBJECT
 | 
				
			||||||
		gfx.cpp
 | 
							gfx.cpp
 | 
				
			||||||
		media.cpp
 | 
							module.cpp
 | 
				
			||||||
		typeconv.cpp
 | 
					 | 
				
			||||||
		typestore.cpp
 | 
							typestore.cpp
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -10,7 +9,6 @@ add_library(
 | 
				
			|||||||
	NostalgiaCore-Headless
 | 
						NostalgiaCore-Headless
 | 
				
			||||||
		headless/core.cpp
 | 
							headless/core.cpp
 | 
				
			||||||
		headless/gfx.cpp
 | 
							headless/gfx.cpp
 | 
				
			||||||
		headless/media.cpp
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_library(NostalgiaCore)
 | 
					add_library(NostalgiaCore)
 | 
				
			||||||
@@ -23,7 +21,6 @@ if(NOT NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
 | 
				
			|||||||
			glfw/gfx.cpp
 | 
								glfw/gfx.cpp
 | 
				
			||||||
			userland/gfx.cpp
 | 
								userland/gfx.cpp
 | 
				
			||||||
			userland/gfx_opengl.cpp
 | 
								userland/gfx_opengl.cpp
 | 
				
			||||||
			userland/media.cpp
 | 
					 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	target_link_libraries(
 | 
						target_link_libraries(
 | 
				
			||||||
		NostalgiaCore PUBLIC
 | 
							NostalgiaCore PUBLIC
 | 
				
			||||||
@@ -44,7 +41,6 @@ else()
 | 
				
			|||||||
			gba/gfx.cpp
 | 
								gba/gfx.cpp
 | 
				
			||||||
			gba/irq.arm.cpp
 | 
								gba/irq.arm.cpp
 | 
				
			||||||
			gba/irq.s
 | 
								gba/irq.s
 | 
				
			||||||
			gba/media.cpp
 | 
					 | 
				
			||||||
			gba/panic.cpp
 | 
								gba/panic.cpp
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	target_link_libraries(
 | 
						target_link_libraries(
 | 
				
			||||||
@@ -59,8 +55,7 @@ endif()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
target_link_libraries(
 | 
					target_link_libraries(
 | 
				
			||||||
	NostalgiaCore-Common PUBLIC
 | 
						NostalgiaCore-Common PUBLIC
 | 
				
			||||||
		OxClaw
 | 
							NostalgiaFoundation
 | 
				
			||||||
		OxFS
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_link_libraries(
 | 
					target_link_libraries(
 | 
				
			||||||
@@ -79,7 +74,6 @@ endif()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
install(
 | 
					install(
 | 
				
			||||||
	FILES
 | 
						FILES
 | 
				
			||||||
		assetmanager.hpp
 | 
					 | 
				
			||||||
		clipboard.hpp
 | 
							clipboard.hpp
 | 
				
			||||||
		color.hpp
 | 
							color.hpp
 | 
				
			||||||
		config.hpp
 | 
							config.hpp
 | 
				
			||||||
@@ -89,7 +83,6 @@ install(
 | 
				
			|||||||
		event.hpp
 | 
							event.hpp
 | 
				
			||||||
		gfx.hpp
 | 
							gfx.hpp
 | 
				
			||||||
		input.hpp
 | 
							input.hpp
 | 
				
			||||||
		media.hpp
 | 
					 | 
				
			||||||
		typeconv.hpp
 | 
							typeconv.hpp
 | 
				
			||||||
		typestore.hpp
 | 
							typestore.hpp
 | 
				
			||||||
	DESTINATION
 | 
						DESTINATION
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ox/fs/fs.hpp>
 | 
					#include <ox/fs/fs.hpp>
 | 
				
			||||||
 | 
					#include <ox/model/desctypes.hpp>
 | 
				
			||||||
#include <ox/std/buffer.hpp>
 | 
					#include <ox/std/buffer.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "assetmanager.hpp"
 | 
					#include <nostalgia/foundation/context.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "event.hpp"
 | 
					#include "event.hpp"
 | 
				
			||||||
#include "input.hpp"
 | 
					#include "input.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -19,15 +21,14 @@ namespace nostalgia::core {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class BaseClipboardObject {
 | 
					class BaseClipboardObject {
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		virtual ~BaseClipboardObject() = default;
 | 
							virtual ~BaseClipboardObject() noexcept = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		virtual ox::String typeId() const noexcept = 0;
 | 
							virtual ox::String typeId() const noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]]
 | 
							[[nodiscard]]
 | 
				
			||||||
		constexpr auto typeMatch(auto name, auto version) const noexcept {
 | 
							constexpr auto typeMatch(auto name, auto version) const noexcept {
 | 
				
			||||||
			auto inId = ox::sfmt("{};{}", name, version);
 | 
								return typeId() == ox::buildTypeId(name, version);
 | 
				
			||||||
			return typeId() == inId;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,7 +36,7 @@ template<typename T>
 | 
				
			|||||||
class ClipboardObject: public BaseClipboardObject {
 | 
					class ClipboardObject: public BaseClipboardObject {
 | 
				
			||||||
	[[nodiscard]]
 | 
						[[nodiscard]]
 | 
				
			||||||
	ox::String typeId() const noexcept final {
 | 
						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
 | 
					// User Input Output
 | 
				
			||||||
class Context {
 | 
					class Context: public foundation::Context {
 | 
				
			||||||
	friend constexpr void setApplicationData(Context *ctx, void *applicationData) noexcept;
 | 
						friend constexpr void setApplicationData(Context *ctx, void *applicationData) noexcept;
 | 
				
			||||||
	template<typename T>
 | 
						template<typename T>
 | 
				
			||||||
	friend constexpr T *applicationData(Context *ctx) noexcept;
 | 
						friend constexpr T *applicationData(Context *ctx) noexcept;
 | 
				
			||||||
@@ -68,7 +69,7 @@ class Context {
 | 
				
			|||||||
	                                                      const struct CompactTileSheet &tilesheetAddr) noexcept;
 | 
						                                                      const struct CompactTileSheet &tilesheetAddr) noexcept;
 | 
				
			||||||
	friend ox::Error run(Context *ctx) noexcept;
 | 
						friend ox::Error run(Context *ctx) noexcept;
 | 
				
			||||||
	friend void shutdown(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 ox::String getClipboardText(Context *ctx) noexcept;
 | 
				
			||||||
	friend uint64_t ticksMs(Context *ctx) noexcept;
 | 
						friend uint64_t ticksMs(Context *ctx) noexcept;
 | 
				
			||||||
	friend uint8_t bgStatus(Context *ctx) noexcept;
 | 
						friend uint8_t bgStatus(Context *ctx) noexcept;
 | 
				
			||||||
@@ -93,17 +94,13 @@ class Context {
 | 
				
			|||||||
	friend void hideSprite(Context *ctx, unsigned idx) noexcept;
 | 
						friend void hideSprite(Context *ctx, unsigned idx) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		ox::UniquePtr<ox::FileSystem> rom;
 | 
					 | 
				
			||||||
		ox::Vector<Drawer*, 5> drawers;
 | 
							ox::Vector<Drawer*, 5> drawers;
 | 
				
			||||||
		ox::StringView appName = "Nostalgia";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef OX_BARE_METAL
 | 
					#ifndef OX_BARE_METAL
 | 
				
			||||||
		AssetManager assetManager;
 | 
					 | 
				
			||||||
		int uninterruptedRefreshes = 3;
 | 
							int uninterruptedRefreshes = 3;
 | 
				
			||||||
		ox::UniquePtr<BaseClipboardObject> clipboard;
 | 
							ox::UPtr<BaseClipboardObject> clipboard;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
		bool running = true;
 | 
							bool running = true;
 | 
				
			||||||
		std::size_t preloadSectionOffset = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	protected:
 | 
						protected:
 | 
				
			||||||
#ifndef OX_BARE_METAL
 | 
					#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
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ox/fs/fs.hpp>
 | 
					#include <ox/fs/fs.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "assetmanager.hpp"
 | 
					 | 
				
			||||||
#include "clipboard.hpp"
 | 
					#include "clipboard.hpp"
 | 
				
			||||||
#include "consts.hpp"
 | 
					#include "consts.hpp"
 | 
				
			||||||
#include "event.hpp"
 | 
					#include "event.hpp"
 | 
				
			||||||
#include "gfx.hpp"
 | 
					#include "gfx.hpp"
 | 
				
			||||||
#include "input.hpp"
 | 
					#include "input.hpp"
 | 
				
			||||||
#include "media.hpp"
 | 
					#include "module.hpp"
 | 
				
			||||||
#include "typeconv.hpp"
 | 
					#include "typeconv.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nostalgia::core {
 | 
					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/fs/fs.hpp>
 | 
				
			||||||
#include <ox/mc/mc.hpp>
 | 
					#include <ox/mc/mc.hpp>
 | 
				
			||||||
#include <ox/std/array.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 <nostalgia/core/gfx.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "addresses.hpp"
 | 
					#include "addresses.hpp"
 | 
				
			||||||
@@ -129,7 +130,7 @@ ox::Error initConsole(Context *ctx) noexcept {
 | 
				
			|||||||
	setBgStatus(ctx, 0b0001);
 | 
						setBgStatus(ctx, 0b0001);
 | 
				
			||||||
	if (!ctx) {
 | 
						if (!ctx) {
 | 
				
			||||||
		ctx = new (ox_alloca(sizeof(Context))) Context();
 | 
							ctx = new (ox_alloca(sizeof(Context))) Context();
 | 
				
			||||||
		oxRequire(rom, loadRom());
 | 
							oxRequire(rom, foundation::loadRom());
 | 
				
			||||||
		ox::FileStore32 fs(rom, 32 * ox::units::MB);
 | 
							ox::FileStore32 fs(rom, 32 * ox::units::MB);
 | 
				
			||||||
		auto romFs = new (ox_alloca(sizeof(ox::FileSystem32))) ox::FileSystem32(fs);
 | 
							auto romFs = new (ox_alloca(sizeof(ox::FileSystem32))) ox::FileSystem32(fs);
 | 
				
			||||||
		new (&ctx->rom) ox::UniquePtr<ox::FileSystem>(romFs);
 | 
							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 <glad/glad.h>
 | 
				
			||||||
#include <GLFW/glfw3.h>
 | 
					#include <GLFW/glfw3.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nostalgia/foundation/foundation.hpp>
 | 
				
			||||||
#include <nostalgia/core/gfx.hpp>
 | 
					#include <nostalgia/core/gfx.hpp>
 | 
				
			||||||
#include <nostalgia/core/input.hpp>
 | 
					#include <nostalgia/core/input.hpp>
 | 
				
			||||||
#include <nostalgia/core/userland/gfx.hpp>
 | 
					#include <nostalgia/core/userland/gfx.hpp>
 | 
				
			||||||
@@ -13,10 +14,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace nostalgia::core {
 | 
					namespace nostalgia::core {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ox::Result<ox::UniquePtr<Context>> init(ox::UniquePtr<ox::FileSystem> fs, ox::CRStringView appName) noexcept {
 | 
					ox::Result<ox::UPtr<Context>> init(ox::UPtr<ox::FileSystem> fs, ox::CRStringView appName) noexcept {
 | 
				
			||||||
	auto ctx = ox::make_unique<Context>();
 | 
						auto ctx = foundation::init<Context>(std::move(fs), appName);
 | 
				
			||||||
	ctx->rom = std::move(fs);
 | 
					 | 
				
			||||||
	ctx->appName = appName;
 | 
					 | 
				
			||||||
	const auto id = ox::make<GlfwImplData>();
 | 
						const auto id = ox::make<GlfwImplData>();
 | 
				
			||||||
	ctx->setWindowerData(id);
 | 
						ctx->setWindowerData(id);
 | 
				
			||||||
	using namespace std::chrono;
 | 
						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
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										23
									
								
								src/nostalgia/core/module.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/nostalgia/core/module.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								src/nostalgia/core/module.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/nostalgia/core/module.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -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 {
 | 
					namespace nostalgia::core {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ox::Vector<studio::EditorMaker> Module::editors(core::Context *ctx) noexcept {
 | 
					ox::Vector<studio::EditorMaker> StudioModule::editors(core::Context *ctx) noexcept {
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			{"ng"},
 | 
								{"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;
 | 
						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::TileSheet>>("Tile Sheet", "TileSheets", "ng"));
 | 
				
			||||||
	out.emplace_back(ox::make<studio::ItemMakerT<core::Palette>>("Palette", "Palettes", "npal"));
 | 
						out.emplace_back(ox::make<studio::ItemMakerT<core::Palette>>("Palette", "Palettes", "npal"));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace nostalgia::core {
 | 
					namespace nostalgia::core {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Module: public studio::Module {
 | 
					class StudioModule: public studio::Module {
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		ox::Vector<studio::EditorMaker> editors(core::Context *ctx) noexcept override;
 | 
							ox::Vector<studio::EditorMaker> editors(core::Context *ctx) noexcept override;
 | 
				
			||||||
		ox::Vector<ox::UniquePtr<studio::ItemMaker>> itemMakers(core::Context*) 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 <imgui.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <nostalgia/core/gfx.hpp>
 | 
					#include <nostalgia/core/gfx.hpp>
 | 
				
			||||||
#include <nostalgia/core/media.hpp>
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
#include <ox/std/memory.hpp>
 | 
					#include <ox/std/memory.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "paletteeditor.hpp"
 | 
					#include "paletteeditor.hpp"
 | 
				
			||||||
@@ -19,7 +19,7 @@ ox::Result<PaletteEditorImGui*> PaletteEditorImGui::make(Context *ctx, ox::CRStr
 | 
				
			|||||||
	out->m_itemPath = path;
 | 
						out->m_itemPath = path;
 | 
				
			||||||
	const auto lastSlash = std::find(out->m_itemPath.rbegin(), out->m_itemPath.rend(), '/').offset();
 | 
						const auto lastSlash = std::find(out->m_itemPath.rbegin(), out->m_itemPath.rend(), '/').offset();
 | 
				
			||||||
	out->m_itemName = out->m_itemPath.substr(lastSlash + 1);
 | 
						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;
 | 
						out->m_pal = *pal;
 | 
				
			||||||
	return out.release();
 | 
						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 <imgui.h>
 | 
				
			||||||
#include <lodepng.h>
 | 
					#include <lodepng.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <nostalgia/core/media.hpp>
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
#include <nostalgia/geo/point.hpp>
 | 
					#include <nostalgia/geo/point.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "tilesheeteditor-imgui.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 <ox/std/memory.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <nostalgia/core/clipboard.hpp>
 | 
					#include <nostalgia/core/clipboard.hpp>
 | 
				
			||||||
#include <nostalgia/core/media.hpp>
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "tilesheeteditormodel.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
 | 
					#pragma once
 | 
				
			||||||
@@ -23,7 +23,7 @@ class TileSheetEditorModel: public ox::SignalHandler {
 | 
				
			|||||||
		static const Palette s_defaultPalette;
 | 
							static const Palette s_defaultPalette;
 | 
				
			||||||
		TileSheet m_img;
 | 
							TileSheet m_img;
 | 
				
			||||||
		TileSheet::SubSheetIdx m_activeSubsSheetIdx;
 | 
							TileSheet::SubSheetIdx m_activeSubsSheetIdx;
 | 
				
			||||||
		AssetRef<Palette> m_pal;
 | 
							foundation::AssetRef<Palette> m_pal;
 | 
				
			||||||
		studio::UndoStack m_undoStack;
 | 
							studio::UndoStack m_undoStack;
 | 
				
			||||||
		class DrawCommand *m_ongoingDrawCommand = nullptr;
 | 
							class DrawCommand *m_ongoingDrawCommand = nullptr;
 | 
				
			||||||
		bool m_updated = false;
 | 
							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/consts.hpp>
 | 
				
			||||||
#include <nostalgia/core/media.hpp>
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
#include <nostalgia/geo/point.hpp>
 | 
					#include <nostalgia/geo/point.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "tilesheeteditorview.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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gfx.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nostalgia/foundation/typeconv.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ox/std/def.hpp>
 | 
					#include <ox/std/def.hpp>
 | 
				
			||||||
#include <ox/std/error.hpp>
 | 
					#include <ox/std/error.hpp>
 | 
				
			||||||
#include <ox/std/optional.hpp>
 | 
					 | 
				
			||||||
#include <ox/std/string.hpp>
 | 
					#include <ox/std/string.hpp>
 | 
				
			||||||
#include <ox/claw/read.hpp>
 | 
					#include <ox/claw/read.hpp>
 | 
				
			||||||
#include <ox/claw/write.hpp>
 | 
					#include <ox/claw/write.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "context.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nostalgia::core {
 | 
					namespace nostalgia::core {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Wrap {
 | 
					// Type converters
 | 
				
			||||||
	public:
 | 
					
 | 
				
			||||||
		virtual ~Wrap() = default;
 | 
					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>
 | 
					struct NostalgiaGraphicToTileSheetConverter: public foundation::Converter<NostalgiaGraphic, TileSheet> {
 | 
				
			||||||
class WrapInline: public Wrap {
 | 
						ox::Error convert(foundation::Context*, NostalgiaGraphic *src, TileSheet *dst) noexcept final {
 | 
				
			||||||
	private:
 | 
							dst->bpp              = src->bpp;
 | 
				
			||||||
		T m_obj;
 | 
							dst->subsheet.name    = "Root";
 | 
				
			||||||
 | 
							dst->subsheet.rows    = src->rows;
 | 
				
			||||||
	public:
 | 
							dst->subsheet.columns = src->columns;
 | 
				
			||||||
		constexpr WrapInline() = default;
 | 
							dst->defaultPalette   = std::move(src->defaultPalette);
 | 
				
			||||||
 | 
							dst->subsheet.pixels  = std::move(src->pixels);
 | 
				
			||||||
		template<typename... Args>
 | 
							return {};
 | 
				
			||||||
		constexpr explicit WrapInline(Args &&...args): m_obj(ox::forward<Args>(args)...) {
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		[[nodiscard]]
 | 
					 | 
				
			||||||
		constexpr auto obj() noexcept {
 | 
					 | 
				
			||||||
			return &m_obj;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T, typename... Args>
 | 
					struct TileSheetToCompactTileSheetConverter: public foundation::Converter<TileSheet, CompactTileSheet> {
 | 
				
			||||||
constexpr auto makeWrap(Args &&...args) noexcept {
 | 
						ox::Error convert(foundation::Context*, TileSheet *src, CompactTileSheet *dst) noexcept final {
 | 
				
			||||||
	return ox::make_unique<WrapInline<T>>(ox::forward<Args>(args)...);
 | 
							dst->bpp            = src->bpp;
 | 
				
			||||||
 | 
							dst->defaultPalette = std::move(src->defaultPalette);
 | 
				
			||||||
 | 
							dst->pixels         = src->pixels();
 | 
				
			||||||
 | 
							return {};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
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);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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"
 | 
					#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
 | 
					#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/gfx.hpp>
 | 
				
			||||||
#include <nostalgia/core/media.hpp>
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "gfx.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");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										26
									
								
								src/nostalgia/foundation/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/nostalgia/foundation/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					add_library(
 | 
				
			||||||
 | 
						NostalgiaFoundation
 | 
				
			||||||
 | 
							foundation.hpp
 | 
				
			||||||
 | 
							media.cpp
 | 
				
			||||||
 | 
							module.cpp
 | 
				
			||||||
 | 
							typeconv.cpp
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_link_libraries(
 | 
				
			||||||
 | 
						NostalgiaFoundation PUBLIC
 | 
				
			||||||
 | 
							OxClaw
 | 
				
			||||||
 | 
							OxEvent
 | 
				
			||||||
 | 
							OxFS
 | 
				
			||||||
 | 
							OxModel
 | 
				
			||||||
 | 
							OxStd
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					install(
 | 
				
			||||||
 | 
						FILES
 | 
				
			||||||
 | 
							media.hpp
 | 
				
			||||||
 | 
							module.hpp
 | 
				
			||||||
 | 
							typeconv.hpp
 | 
				
			||||||
 | 
						DESTINATION
 | 
				
			||||||
 | 
							include/nostalgia/core
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -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
 | 
					#pragma once
 | 
				
			||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
#include <ox/std/hashmap.hpp>
 | 
					#include <ox/std/hashmap.hpp>
 | 
				
			||||||
#include <ox/std/utility.hpp>
 | 
					#include <ox/std/utility.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nostalgia::core {
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AssetManager;
 | 
					class AssetManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										34
									
								
								src/nostalgia/foundation/context.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/nostalgia/foundation/context.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ox/fs/fs.hpp>
 | 
				
			||||||
 | 
					#include <ox/std/memory.hpp>
 | 
				
			||||||
 | 
					#include <ox/std/stringview.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "assetmanager.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Context {
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							ox::UPtr<ox::FileSystem> rom;
 | 
				
			||||||
 | 
							ox::StringView appName = "Nostalgia Foundation App";
 | 
				
			||||||
 | 
					#ifndef OX_BARE_METAL
 | 
				
			||||||
 | 
							AssetManager assetManager;
 | 
				
			||||||
 | 
							ox::Vector<class BaseConverter*> converters;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							std::size_t preloadSectionOffset = 0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							constexpr Context() noexcept = default;
 | 
				
			||||||
 | 
							Context(const Context&) noexcept = delete;
 | 
				
			||||||
 | 
							Context(Context&&) noexcept = delete;
 | 
				
			||||||
 | 
							Context &operator=(const Context&) noexcept = delete;
 | 
				
			||||||
 | 
							Context &operator=(Context&&) noexcept = delete;
 | 
				
			||||||
 | 
							constexpr virtual ~Context() noexcept = default;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/nostalgia/foundation/foundation.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/nostalgia/foundation/foundation.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ox/std/memory.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "context.hpp"
 | 
				
			||||||
 | 
					#include "module.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename Context = foundation::Context>
 | 
				
			||||||
 | 
					ox::UPtr<Context> init(ox::UPtr<ox::FileSystem> &&fs, ox::CRStringView appName) noexcept {
 | 
				
			||||||
 | 
						auto ctx = ox::make_unique<Context>();
 | 
				
			||||||
 | 
						ctx->rom = std::move(fs);
 | 
				
			||||||
 | 
						ctx->appName = appName;
 | 
				
			||||||
 | 
						auto mods = modules();
 | 
				
			||||||
 | 
						if (mods) {
 | 
				
			||||||
 | 
							for (auto &mod : *mods) {
 | 
				
			||||||
 | 
								// load type converters
 | 
				
			||||||
 | 
								for (auto c : mod->converters()) {
 | 
				
			||||||
 | 
									ctx->converters.emplace_back(c);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ctx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										110
									
								
								src/nostalgia/foundation/media.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/nostalgia/foundation/media.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "media.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef OX_BARE_METAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ox/std/trace.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "context.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MEM_ROM reinterpret_cast<char*>(0x0800'0000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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(foundation::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(foundation::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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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, 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,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
 | 
					#pragma once
 | 
				
			||||||
@@ -10,10 +10,11 @@
 | 
				
			|||||||
#include <ox/fs/fs.hpp>
 | 
					#include <ox/fs/fs.hpp>
 | 
				
			||||||
#include <ox/model/metadata.hpp>
 | 
					#include <ox/model/metadata.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "context.hpp"
 | 
					#include <nostalgia/foundation/context.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "typeconv.hpp"
 | 
					#include "typeconv.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nostalgia::core {
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct PreloadPtr {
 | 
					struct PreloadPtr {
 | 
				
			||||||
	static constexpr auto TypeName = "net.drinkingtea.ox.PreloadPtr";
 | 
						static constexpr auto TypeName = "net.drinkingtea.ox.PreloadPtr";
 | 
				
			||||||
@@ -25,20 +26,20 @@ oxModelBegin(PreloadPtr)
 | 
				
			|||||||
	oxModelField(preloadAddr)
 | 
						oxModelField(preloadAddr)
 | 
				
			||||||
oxModelEnd()
 | 
					oxModelEnd()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ox::Result<std::size_t> getPreloadAddr(Context *ctx, const ox::FileAddress &file) noexcept;
 | 
					ox::Result<std::size_t> getPreloadAddr(foundation::Context *ctx, const ox::FileAddress &file) noexcept;
 | 
				
			||||||
ox::Result<std::size_t> getPreloadAddr(Context *ctx, ox::CRStringView file) noexcept;
 | 
					ox::Result<std::size_t> getPreloadAddr(foundation::Context *ctx, ox::CRStringView file) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
ox::Result<AssetRef<T>> readObj([[maybe_unused]] Context *ctx, [[maybe_unused]] ox::CRStringView path,
 | 
					ox::Result<foundation::AssetRef<T>> readObj([[maybe_unused]] foundation::Context *ctx, [[maybe_unused]] ox::CRStringView path,
 | 
				
			||||||
                                            [[maybe_unused]] bool forceLoad = false) noexcept {
 | 
					                                            [[maybe_unused]] bool forceLoad = false) noexcept {
 | 
				
			||||||
#ifndef OX_BARE_METAL
 | 
					#ifndef OX_BARE_METAL
 | 
				
			||||||
	constexpr auto readConvert = [](const ox::Buffer &buff) -> ox::Result<T> {
 | 
						const auto readConvert = [ctx](const ox::Buffer &buff) -> ox::Result<T> {
 | 
				
			||||||
		auto [obj, err] = ox::readClaw<T>(buff);
 | 
							auto [obj, err] = ox::readClaw<T>(buff);
 | 
				
			||||||
		if (err) {
 | 
							if (err) {
 | 
				
			||||||
			if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) {
 | 
								if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) {
 | 
				
			||||||
				return err;
 | 
									return err;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			oxReturnError(convert<T>(buff, &obj));
 | 
								oxReturnError(convert<T>(ctx, buff, &obj));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return std::move(obj);
 | 
							return std::move(obj);
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
@@ -59,7 +60,7 @@ ox::Result<AssetRef<T>> readObj([[maybe_unused]] Context *ctx, [[maybe_unused]]
 | 
				
			|||||||
#else
 | 
					#else
 | 
				
			||||||
	if constexpr(ox::preloadable<T>::value) {
 | 
						if constexpr(ox::preloadable<T>::value) {
 | 
				
			||||||
		oxRequire(addr, getPreloadAddr(ctx, path));
 | 
							oxRequire(addr, getPreloadAddr(ctx, path));
 | 
				
			||||||
		return AssetRef<T>(reinterpret_cast<const T*>(addr));
 | 
							return foundation::AssetRef<T>(reinterpret_cast<const T*>(addr));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return OxError(1);
 | 
							return OxError(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -67,7 +68,7 @@ ox::Result<AssetRef<T>> readObj([[maybe_unused]] Context *ctx, [[maybe_unused]]
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
ox::Result<AssetRef<T>> readObj(Context *ctx, const ox::FileAddress &file,
 | 
					ox::Result<foundation::AssetRef<T>> readObj(foundation::Context *ctx, const ox::FileAddress &file,
 | 
				
			||||||
                                            [[maybe_unused]] bool forceLoad = false) noexcept {
 | 
					                                            [[maybe_unused]] bool forceLoad = false) noexcept {
 | 
				
			||||||
#ifndef OX_BARE_METAL
 | 
					#ifndef OX_BARE_METAL
 | 
				
			||||||
	oxRequire(path, file.getPath());
 | 
						oxRequire(path, file.getPath());
 | 
				
			||||||
@@ -75,7 +76,7 @@ ox::Result<AssetRef<T>> readObj(Context *ctx, const ox::FileAddress &file,
 | 
				
			|||||||
#else
 | 
					#else
 | 
				
			||||||
	if constexpr(ox::preloadable<T>::value) {
 | 
						if constexpr(ox::preloadable<T>::value) {
 | 
				
			||||||
		oxRequire(addr, getPreloadAddr(ctx, file));
 | 
							oxRequire(addr, getPreloadAddr(ctx, file));
 | 
				
			||||||
		return AssetRef<T>(reinterpret_cast<const T*>(addr));
 | 
							return foundation::AssetRef<T>(reinterpret_cast<const T*>(addr));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return OxError(1);
 | 
							return OxError(1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -83,7 +84,7 @@ ox::Result<AssetRef<T>> readObj(Context *ctx, const ox::FileAddress &file,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
ox::Error writeObj(Context *ctx, const ox::FileAddress &file, const T &obj,
 | 
					ox::Error writeObj(foundation::Context *ctx, const ox::FileAddress &file, const T &obj,
 | 
				
			||||||
                   ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept {
 | 
					                   ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept {
 | 
				
			||||||
	oxRequire(objBuff, ox::writeClaw(&obj, fmt));
 | 
						oxRequire(objBuff, ox::writeClaw(&obj, fmt));
 | 
				
			||||||
	return ctx->rom->write(file, objBuff.data(), objBuff.size());
 | 
						return ctx->rom->write(file, objBuff.data(), objBuff.size());
 | 
				
			||||||
							
								
								
									
										36
									
								
								src/nostalgia/foundation/module.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/nostalgia/foundation/module.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "module.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]]
 | 
				
			||||||
 | 
					static ox::Vector<const Module*> *moduleRegistry() noexcept {
 | 
				
			||||||
 | 
					#ifdef OX_BARE_METAL
 | 
				
			||||||
 | 
						return nullptr;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						static ox::Vector<const Module*> modules;
 | 
				
			||||||
 | 
						return &modules;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void registerModule(const Module *mod) noexcept {
 | 
				
			||||||
 | 
						auto mods = moduleRegistry();
 | 
				
			||||||
 | 
						if (mods) {
 | 
				
			||||||
 | 
							mods->emplace_back(mod);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]]
 | 
				
			||||||
 | 
					const ox::Vector<const Module*> *modules() noexcept {
 | 
				
			||||||
 | 
						return moduleRegistry();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Vector<foundation::BaseConverter*> Module::converters() const noexcept {
 | 
				
			||||||
 | 
						return {};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										30
									
								
								src/nostalgia/foundation/module.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/nostalgia/foundation/module.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ox/std/vector.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "typeconv.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Module {
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							constexpr Module() noexcept = default;
 | 
				
			||||||
 | 
							Module(const Module&) noexcept = delete;
 | 
				
			||||||
 | 
							Module(Module&&) noexcept = delete;
 | 
				
			||||||
 | 
							Module &operator=(const Module&) noexcept = delete;
 | 
				
			||||||
 | 
							Module &operator=(Module&&) noexcept = delete;
 | 
				
			||||||
 | 
							constexpr virtual ~Module() noexcept = default;
 | 
				
			||||||
 | 
							[[nodiscard]]
 | 
				
			||||||
 | 
							virtual ox::Vector<foundation::BaseConverter*> converters() const noexcept;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void registerModule(const Module *mod) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]]
 | 
				
			||||||
 | 
					const ox::Vector<const foundation::Module*> *modules() noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										55
									
								
								src/nostalgia/foundation/typeconv.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/nostalgia/foundation/typeconv.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ox/claw/read.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "typeconv.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef OX_BARE_METAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]]
 | 
				
			||||||
 | 
					static auto findConverter(foundation::Context *ctx,
 | 
				
			||||||
 | 
					                          ox::CRStringView srcTypeName, int srcTypeVersion,
 | 
				
			||||||
 | 
					                          ox::CRStringView dstTypeName, int dstTypeVersion) noexcept -> ox::Result<BaseConverter*> {
 | 
				
			||||||
 | 
						for (auto &c : ctx->converters) {
 | 
				
			||||||
 | 
							if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) {
 | 
				
			||||||
 | 
								return c;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return OxError(1, "Could not find converter");
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ox::Result<ox::UniquePtr<Wrap>> convert(foundation::Context *ctx, const ox::Buffer &srcBuffer,
 | 
				
			||||||
 | 
					                                               ox::CRStringView srcTypeName, int srcTypeVersion,
 | 
				
			||||||
 | 
					                                               ox::CRStringView dstTypeName, int dstTypeVersion) noexcept {
 | 
				
			||||||
 | 
						// look for direct converter
 | 
				
			||||||
 | 
						auto [c, err] = findConverter(ctx, srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion);
 | 
				
			||||||
 | 
						if (!err) {
 | 
				
			||||||
 | 
							return c->convertBuffToPtr(nullptr, srcBuffer);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// try to chain multiple converters
 | 
				
			||||||
 | 
						for (const auto &subConverter : ctx->converters) {
 | 
				
			||||||
 | 
							if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) {
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							const auto [intermediate, chainErr] =
 | 
				
			||||||
 | 
								convert(ctx, srcBuffer, srcTypeName, srcTypeVersion,
 | 
				
			||||||
 | 
								        subConverter->srcTypeName(), subConverter->srcTypeVersion());
 | 
				
			||||||
 | 
							if (!chainErr) {
 | 
				
			||||||
 | 
								return subConverter->convertPtrToPtr(ctx, intermediate.get());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return OxError(1, "Could not convert between types");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<ox::UniquePtr<Wrap>> convert(foundation::Context *ctx, const ox::Buffer &srcBuffer, ox::CRStringView dstTypeName, int dstTypeVersion) noexcept {
 | 
				
			||||||
 | 
						oxRequire(hdr, ox::readClawHeader(srcBuffer));
 | 
				
			||||||
 | 
						return convert(ctx, srcBuffer, hdr.typeName, hdr.typeVersion, dstTypeName, dstTypeVersion);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										155
									
								
								src/nostalgia/foundation/typeconv.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								src/nostalgia/foundation/typeconv.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,155 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ox/std/def.hpp>
 | 
				
			||||||
 | 
					#include <ox/std/error.hpp>
 | 
				
			||||||
 | 
					#include <ox/std/string.hpp>
 | 
				
			||||||
 | 
					#include <ox/claw/read.hpp>
 | 
				
			||||||
 | 
					#include <ox/claw/write.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "context.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nostalgia::foundation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Wrap {
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							virtual ~Wrap() = default;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseConverter {
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							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(foundation::Context *ctx, Wrap *src) noexcept = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							virtual ox::Result<ox::UniquePtr<Wrap>> convertBuffToPtr(foundation::Context *ctx, 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);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename SrcType, typename DstType>
 | 
				
			||||||
 | 
					class Converter: public BaseConverter {
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							virtual ox::Error convert(foundation::Context *ctx, 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(foundation::Context *ctx, Wrap *src) noexcept final {
 | 
				
			||||||
 | 
								auto dst = makeWrap<DstType>();
 | 
				
			||||||
 | 
								oxReturnError(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(dst.get())));
 | 
				
			||||||
 | 
								return ox::Result<ox::UniquePtr<Wrap>>(std::move(dst));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ox::Result<ox::UniquePtr<Wrap>> convertBuffToPtr(foundation::Context *ctx, const ox::Buffer &srcBuff) noexcept final {
 | 
				
			||||||
 | 
								oxRequireM(src, ox::readClaw<SrcType>(srcBuff));
 | 
				
			||||||
 | 
								auto dst = makeWrap<DstType>();
 | 
				
			||||||
 | 
								oxReturnError(convert(ctx, &src, wrapCast<DstType>(dst.get())));
 | 
				
			||||||
 | 
								return ox::Result<ox::UniquePtr<Wrap>>(std::move(dst));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ox::Result<ox::UniquePtr<Wrap>> convert(foundation::Context *ctx, const ox::Buffer &srcBuffer,
 | 
				
			||||||
 | 
					                                        ox::CRStringView dstTypeName, int dstTypeVersion) noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename DstType>
 | 
				
			||||||
 | 
					ox::Result<DstType> convert(foundation::Context *ctx, const ox::Buffer &srcBuffer) noexcept {
 | 
				
			||||||
 | 
						static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
 | 
				
			||||||
 | 
						static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
 | 
				
			||||||
 | 
						oxRequire(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion));
 | 
				
			||||||
 | 
						return wrapCast<DstType>(out);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename DstType>
 | 
				
			||||||
 | 
					ox::Error convert(foundation::Context *ctx, const ox::Buffer &buff, DstType *outObj) noexcept {
 | 
				
			||||||
 | 
						static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
 | 
				
			||||||
 | 
						static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
 | 
				
			||||||
 | 
						oxRequire(outPtr, convert(ctx, buff, DstTypeName, DstTypeVersion));
 | 
				
			||||||
 | 
						*outObj = std::move(*wrapCast<DstType>(outPtr.get()));
 | 
				
			||||||
 | 
						return OxError(0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename DstType>
 | 
				
			||||||
 | 
					ox::Result<ox::Buffer> convertBuffToBuff(foundation::Context *ctx, 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(ctx, srcBuffer, DstTypeName, DstTypeVersion));
 | 
				
			||||||
 | 
						return ox::writeClaw<DstType>(wrapCast<DstType>(out.get()), fmt);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -22,8 +22,7 @@ endif()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
target_link_libraries(
 | 
					target_link_libraries(
 | 
				
			||||||
	nostalgia
 | 
						nostalgia
 | 
				
			||||||
		NostalgiaWorld
 | 
							NostalgiaAppModules
 | 
				
			||||||
		NostalgiaCore
 | 
					 | 
				
			||||||
		OxLogConn
 | 
							OxLogConn
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <nostalgia/core/core.hpp>
 | 
					#include <nostalgia/core/core.hpp>
 | 
				
			||||||
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace nostalgia;
 | 
					using namespace nostalgia;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,6 +34,7 @@ static int updateHandler(core::Context *ctx) noexcept {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	spriteX += xmod;
 | 
						spriteX += xmod;
 | 
				
			||||||
	spriteY += ymod;
 | 
						spriteY += ymod;
 | 
				
			||||||
 | 
						//constexpr ox::StringView sprites = "nostalgia";
 | 
				
			||||||
	for (unsigned i = 0; i < sprites.len(); ++i) {
 | 
						for (unsigned i = 0; i < sprites.len(); ++i) {
 | 
				
			||||||
		const auto c = static_cast<unsigned>(sprites[i] - ('a' - 1));
 | 
							const auto c = static_cast<unsigned>(sprites[i] - ('a' - 1));
 | 
				
			||||||
		core::setSprite(ctx, i, spriteX + 8 * (static_cast<int>(i) + 1), spriteY, c, 0, 0, 0);
 | 
							core::setSprite(ctx, i, spriteX + 8 * (static_cast<int>(i) + 1), spriteY, c, 0, 0, 0);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +1,29 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ox/logconn/logconn.hpp>
 | 
					#include <ox/logconn/logconn.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <nostalgia/core/core.hpp>
 | 
					#include <nostalgia/core/core.hpp>
 | 
				
			||||||
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nostalgia/appmodules/appmodules.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "app.hpp"
 | 
					#include "app.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ox::Error run(int argc, const char **argv) noexcept {
 | 
					static ox::Error run(int argc, const char **argv) noexcept {
 | 
				
			||||||
	ox::trace::init();
 | 
						ox::trace::init();
 | 
				
			||||||
 | 
						nostalgia::loadModules();
 | 
				
			||||||
 | 
						if (argc < 2) {
 | 
				
			||||||
 | 
							oxErr("Please provide path to project directory or OxFS file.\n");
 | 
				
			||||||
 | 
							return OxError(1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						const auto path = argv[1];
 | 
				
			||||||
 | 
						oxRequireM(fs, nostalgia::foundation::loadRomFs(path));
 | 
				
			||||||
 | 
						return run(std::move(fs));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, const char **argv) {
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
	ox::LoggerConn loggerConn;
 | 
						ox::LoggerConn loggerConn;
 | 
				
			||||||
	const auto loggerErr = loggerConn.initConn("Nostalgia Player");
 | 
						const auto loggerErr = loggerConn.initConn("Nostalgia Player");
 | 
				
			||||||
@@ -19,16 +33,6 @@ static ox::Error run(int argc, const char **argv) noexcept {
 | 
				
			|||||||
		ox::trace::setLogger(&loggerConn);
 | 
							ox::trace::setLogger(&loggerConn);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	if (argc < 2) {
 | 
					 | 
				
			||||||
		oxErr("Please provide path to project directory or OxFS file.\n");
 | 
					 | 
				
			||||||
		return OxError(1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	const auto path = argv[1];
 | 
					 | 
				
			||||||
	oxRequireM(fs, nostalgia::core::loadRomFs(path));
 | 
					 | 
				
			||||||
	return run(std::move(fs));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(int argc, const char **argv) {
 | 
					 | 
				
			||||||
	const auto err = run(argc, argv);
 | 
						const auto err = run(argc, argv);
 | 
				
			||||||
	oxAssert(err, "Something went wrong...");
 | 
						oxAssert(err, "Something went wrong...");
 | 
				
			||||||
	return static_cast<int>(err);
 | 
						return static_cast<int>(err);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,42 +1,41 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
					 * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ox/fs/fs.hpp>
 | 
					#include <ox/fs/fs.hpp>
 | 
				
			||||||
#include <ox/preloader/preloader.hpp>
 | 
					 | 
				
			||||||
#include <ox/std/error.hpp>
 | 
					#include <ox/std/error.hpp>
 | 
				
			||||||
#include <ox/std/types.hpp>
 | 
					#include <ox/std/types.hpp>
 | 
				
			||||||
#include <ox/std/vector.hpp>
 | 
					#include <ox/std/vector.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace nostalgia::scene {
 | 
					namespace nostalgia::scene {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct TileDoc {
 | 
					struct Tile {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constexpr static auto Preloadable = true;
 | 
					 | 
				
			||||||
	constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.Tile";
 | 
						constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.Tile";
 | 
				
			||||||
	constexpr static auto TypeVersion = 1;
 | 
						constexpr static auto TypeVersion = 1;
 | 
				
			||||||
 | 
						constexpr static auto Preloadable = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint16_t sheetIdx = 0;
 | 
						ox::String sheetIdx;
 | 
				
			||||||
	uint8_t  type = 0;
 | 
						uint8_t  type = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oxModelBegin(TileDoc)
 | 
					oxModelBegin(Tile)
 | 
				
			||||||
	oxModelField(sheetIdx);
 | 
						oxModelFieldRename(sheet_idx, sheetIdx);
 | 
				
			||||||
	oxModelField(type);
 | 
						oxModelField(type);
 | 
				
			||||||
oxModelEnd()
 | 
					oxModelEnd()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SceneDoc {
 | 
					struct Scene {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	using TileMapRow = ox::Vector<TileDoc>;
 | 
						using TileMapRow = ox::Vector<Tile>;
 | 
				
			||||||
	using TileMapLayer = ox::Vector<TileMapRow>;
 | 
						using TileMapLayer = ox::Vector<TileMapRow>;
 | 
				
			||||||
	using TileMap = ox::Vector<TileMapLayer>;
 | 
						using TileMap = ox::Vector<TileMapLayer>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constexpr static auto Preloadable = true;
 | 
					 | 
				
			||||||
	constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.Scene";
 | 
						constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.Scene";
 | 
				
			||||||
	constexpr static auto TypeVersion = 1;
 | 
						constexpr static auto TypeVersion = 1;
 | 
				
			||||||
 | 
						constexpr static auto Preloadable = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ox::FileAddress tilesheet;
 | 
						ox::FileAddress tilesheet;
 | 
				
			||||||
	ox::FileAddress palette;
 | 
						ox::FileAddress palette;
 | 
				
			||||||
@@ -44,7 +43,7 @@ struct SceneDoc {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oxModelBegin(SceneDoc)
 | 
					oxModelBegin(Scene)
 | 
				
			||||||
	oxModelField(tilesheet)
 | 
						oxModelField(tilesheet)
 | 
				
			||||||
	oxModelField(palette)
 | 
						oxModelField(palette)
 | 
				
			||||||
	oxModelField(tiles)
 | 
						oxModelField(tiles)
 | 
				
			||||||
@@ -63,8 +62,8 @@ struct SceneInstance {
 | 
				
			|||||||
	struct Layer {
 | 
						struct Layer {
 | 
				
			||||||
		uint16_t &columns;
 | 
							uint16_t &columns;
 | 
				
			||||||
		uint16_t &rows;
 | 
							uint16_t &rows;
 | 
				
			||||||
		uint16_t *tileMapIdx;
 | 
							uint16_t *tileMapIdx = nullptr;
 | 
				
			||||||
		uint8_t *tileType;
 | 
							uint8_t *tileType = nullptr;
 | 
				
			||||||
		constexpr Layer(uint16_t &pColumns,
 | 
							constexpr Layer(uint16_t &pColumns,
 | 
				
			||||||
		                uint16_t &pRows,
 | 
							                uint16_t &pRows,
 | 
				
			||||||
		                uint16_t *pTileMapIdx,
 | 
							                uint16_t *pTileMapIdx,
 | 
				
			||||||
@@ -90,6 +89,15 @@ struct SceneInstance {
 | 
				
			|||||||
	constexpr Layer layer(std::size_t i) noexcept {
 | 
						constexpr Layer layer(std::size_t i) noexcept {
 | 
				
			||||||
		return {columns[i], rows[i], tileMapIdx[i].data(), tileType[i].data()};
 | 
							return {columns[i], rows[i], tileMapIdx[i].data(), tileType[i].data()};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					oxModelBegin(SceneInstance)
 | 
				
			||||||
 | 
						oxModelField(layers)
 | 
				
			||||||
 | 
						oxModelField(columns)
 | 
				
			||||||
 | 
						oxModelField(rows)
 | 
				
			||||||
 | 
						oxModelFieldRename(tile_map_idx, tileMapIdx)
 | 
				
			||||||
 | 
						oxModelFieldRename(tile_type, tileType)
 | 
				
			||||||
 | 
					oxModelEnd()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ target_link_libraries(
 | 
				
			|||||||
	nostalgia-studio
 | 
						nostalgia-studio
 | 
				
			||||||
		OxClArgs
 | 
							OxClArgs
 | 
				
			||||||
		OxLogConn
 | 
							OxLogConn
 | 
				
			||||||
 | 
							NostalgiaAppModules
 | 
				
			||||||
		NostalgiaStudio
 | 
							NostalgiaStudio
 | 
				
			||||||
		NostalgiaCore-Studio
 | 
							NostalgiaCore-Studio
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
					#pragma once
 | 
				
			||||||
@@ -13,7 +13,7 @@ namespace nostalgia {
 | 
				
			|||||||
[[maybe_unused]] // GCC warns about the existence of this "unused" constexpr list in a header file...
 | 
					[[maybe_unused]] // GCC warns about the existence of this "unused" constexpr list in a header file...
 | 
				
			||||||
constexpr auto BuiltinModules = {
 | 
					constexpr auto BuiltinModules = {
 | 
				
			||||||
	[] {
 | 
						[] {
 | 
				
			||||||
		 return ox::make_unique<core::Module>();
 | 
							 return ox::make_unique<core::StudioModule>();
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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/logconn/logconn.hpp>
 | 
					#include <ox/logconn/logconn.hpp>
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <ox/std/trace.hpp>
 | 
					#include <ox/std/trace.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nostalgia/appmodules/appmodules.hpp>
 | 
				
			||||||
#include <nostalgia/core/core.hpp>
 | 
					#include <nostalgia/core/core.hpp>
 | 
				
			||||||
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "lib/context.hpp"
 | 
					#include "lib/context.hpp"
 | 
				
			||||||
#include "studioapp.hpp"
 | 
					#include "studioapp.hpp"
 | 
				
			||||||
@@ -55,18 +56,10 @@ static ox::Error run(ox::UniquePtr<ox::FileSystem> fs) noexcept {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static ox::Error run(int argc, const char **argv) noexcept {
 | 
					static ox::Error run(int argc, const char **argv) noexcept {
 | 
				
			||||||
	ox::trace::init();
 | 
						ox::trace::init();
 | 
				
			||||||
#ifdef DEBUG
 | 
						loadModules();
 | 
				
			||||||
	ox::LoggerConn loggerConn;
 | 
					 | 
				
			||||||
	const auto loggerErr = loggerConn.initConn("Nostalgia Studio");
 | 
					 | 
				
			||||||
	if (loggerErr) {
 | 
					 | 
				
			||||||
		oxErrf("Could not connect to logger: {}\n", toStr(loggerErr));
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		ox::trace::setLogger(&loggerConn);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	if (argc >= 2) {
 | 
						if (argc >= 2) {
 | 
				
			||||||
		const auto path = argv[1];
 | 
							const auto path = argv[1];
 | 
				
			||||||
		oxRequireM(fs, core::loadRomFs(path));
 | 
							oxRequireM(fs, foundation::loadRomFs(path));
 | 
				
			||||||
		return run(std::move(fs));
 | 
							return run(std::move(fs));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return run(ox::UniquePtr<ox::FileSystem>(nullptr));
 | 
							return run(ox::UniquePtr<ox::FileSystem>(nullptr));
 | 
				
			||||||
@@ -76,6 +69,15 @@ static ox::Error run(int argc, const char **argv) noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, const char **argv) {
 | 
					int main(int argc, const char **argv) {
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
						ox::LoggerConn loggerConn;
 | 
				
			||||||
 | 
						const auto loggerErr = loggerConn.initConn("Nostalgia Studio");
 | 
				
			||||||
 | 
						if (loggerErr) {
 | 
				
			||||||
 | 
							oxErrf("Could not connect to logger: {}\n", toStr(loggerErr));
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ox::trace::setLogger(&loggerConn);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	const auto err = nostalgia::run(argc, argv);
 | 
						const auto err = nostalgia::run(argc, argv);
 | 
				
			||||||
	oxAssert(err, "Something went wrong...");
 | 
						oxAssert(err, "Something went wrong...");
 | 
				
			||||||
	return static_cast<int>(err);
 | 
						return static_cast<int>(err);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@
 | 
				
			|||||||
#include <imgui.h>
 | 
					#include <imgui.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <nostalgia/core/core.hpp>
 | 
					#include <nostalgia/core/core.hpp>
 | 
				
			||||||
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "lib/configio.hpp"
 | 
					#include "lib/configio.hpp"
 | 
				
			||||||
#include "builtinmodules.hpp"
 | 
					#include "builtinmodules.hpp"
 | 
				
			||||||
@@ -284,7 +285,7 @@ void StudioUI::save() noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ox::Error StudioUI::openProject(ox::CRStringView path) noexcept {
 | 
					ox::Error StudioUI::openProject(ox::CRStringView path) noexcept {
 | 
				
			||||||
	oxRequireM(fs, core::loadRomFs(path));
 | 
						oxRequireM(fs, foundation::loadRomFs(path));
 | 
				
			||||||
	m_ctx->rom = std::move(fs);
 | 
						m_ctx->rom = std::move(fs);
 | 
				
			||||||
	core::setWindowTitle(m_ctx, ox::sfmt("Nostalgia Studio - {}", path));
 | 
						core::setWindowTitle(m_ctx, ox::sfmt("Nostalgia Studio - {}", path));
 | 
				
			||||||
	m_project = ox::make_unique<studio::Project>(m_ctx->rom.get(), path);
 | 
						m_project = ox::make_unique<studio::Project>(m_ctx->rom.get(), path);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ target_link_libraries(
 | 
				
			|||||||
		OxClArgs
 | 
							OxClArgs
 | 
				
			||||||
		OxLogConn
 | 
							OxLogConn
 | 
				
			||||||
		NostalgiaPack
 | 
							NostalgiaPack
 | 
				
			||||||
 | 
							NostalgiaAppModules
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(CMAKE_BUILD_TYPE STREQUAL "Release" AND NOT WIN32)
 | 
					if(CMAKE_BUILD_TYPE STREQUAL "Release" AND NOT WIN32)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 <fstream>
 | 
					#include <fstream>
 | 
				
			||||||
@@ -8,6 +8,7 @@
 | 
				
			|||||||
#include <ox/fs/fs.hpp>
 | 
					#include <ox/fs/fs.hpp>
 | 
				
			||||||
#include <ox/logconn/logconn.hpp>
 | 
					#include <ox/logconn/logconn.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <nostalgia/appmodules/appmodules.hpp>
 | 
				
			||||||
#include <nostalgia/core/typestore.hpp>
 | 
					#include <nostalgia/core/typestore.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pack/pack.hpp"
 | 
					#include "pack/pack.hpp"
 | 
				
			||||||
@@ -43,6 +44,7 @@ static ox::Result<ox::Buffer> readFileBuff(ox::CRStringView path) noexcept {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ox::Error run(const ox::ClArgs &args) noexcept {
 | 
					static ox::Error run(const ox::ClArgs &args) noexcept {
 | 
				
			||||||
 | 
						loadModules();
 | 
				
			||||||
	const auto argSrc = args.getString("src", "");
 | 
						const auto argSrc = args.getString("src", "");
 | 
				
			||||||
	const auto argRomBin = args.getString("rom-bin", "");
 | 
						const auto argRomBin = args.getString("rom-bin", "");
 | 
				
			||||||
	if (argSrc == "") {
 | 
						if (argSrc == "") {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ add_library(
 | 
				
			|||||||
target_link_libraries(
 | 
					target_link_libraries(
 | 
				
			||||||
	NostalgiaPack PUBLIC
 | 
						NostalgiaPack PUBLIC
 | 
				
			||||||
		NostalgiaCore-Headless
 | 
							NostalgiaCore-Headless
 | 
				
			||||||
 | 
							NostalgiaFoundation
 | 
				
			||||||
		OxPreloader
 | 
							OxPreloader
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 <ox/claw/read.hpp>
 | 
					#include <ox/claw/read.hpp>
 | 
				
			||||||
@@ -8,9 +8,9 @@
 | 
				
			|||||||
#include <ox/model/modelvalue.hpp>
 | 
					#include <ox/model/modelvalue.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <nostalgia/core/gfx.hpp>
 | 
					#include <nostalgia/core/gfx.hpp>
 | 
				
			||||||
#include <nostalgia/core/media.hpp>
 | 
					 | 
				
			||||||
#include <nostalgia/core/typeconv.hpp>
 | 
					#include <nostalgia/core/typeconv.hpp>
 | 
				
			||||||
#include <nostalgia/core/typestore.hpp>
 | 
					#include <nostalgia/core/typestore.hpp>
 | 
				
			||||||
 | 
					#include <nostalgia/foundation/media.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pack.hpp"
 | 
					#include "pack.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -64,7 +64,7 @@ static ox::Error doTransformations(core::TypeStore *ts, ox::FileSystem *dest, ox
 | 
				
			|||||||
		oxRequire(s, dest->stat(filePath));
 | 
							oxRequire(s, dest->stat(filePath));
 | 
				
			||||||
		oxRequireM(buff, dest->read(s.inode));
 | 
							oxRequireM(buff, dest->read(s.inode));
 | 
				
			||||||
		if (endsWith(filePath, ".ng")) {
 | 
							if (endsWith(filePath, ".ng")) {
 | 
				
			||||||
			oxReturnError(core::convertBuffToBuff<core::CompactTileSheet>(buff, ox::ClawFormat::Metal).moveTo(&buff));
 | 
								oxReturnError(foundation::convertBuffToBuff<core::CompactTileSheet>(nullptr, buff, ox::ClawFormat::Metal).moveTo(&buff));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		oxRequireM(obj, ox::readClaw(ts, buff));
 | 
							oxRequireM(obj, ox::readClaw(ts, buff));
 | 
				
			||||||
		// do transformations
 | 
							// do transformations
 | 
				
			||||||
@@ -153,7 +153,7 @@ static ox::Error preloadObj(core::TypeStore *ts, ox::FileSystem *romFs, GbaPrelo
 | 
				
			|||||||
		const auto err = ox::preload<GbaPlatSpec, decltype(obj)>(pl, &obj);
 | 
							const auto err = ox::preload<GbaPlatSpec, decltype(obj)>(pl, &obj);
 | 
				
			||||||
		oxReturnError(pl->endAlloc());
 | 
							oxReturnError(pl->endAlloc());
 | 
				
			||||||
		oxReturnError(err);
 | 
							oxReturnError(err);
 | 
				
			||||||
		const core::PreloadPtr p{.preloadAddr = static_cast<uint32_t>(a)};
 | 
							const foundation::PreloadPtr p{.preloadAddr = static_cast<uint32_t>(a)};
 | 
				
			||||||
		oxReturnError(ox::writeMC(&p).moveTo(&buff));
 | 
							oxReturnError(ox::writeMC(&p).moveTo(&buff));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// strip the Claw header (it is not needed after preloading) and write back out to dest fs
 | 
							// strip the Claw header (it is not needed after preloading) and write back out to dest fs
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 <ox/preloader/preloader.hpp>
 | 
					#include <ox/preloader/preloader.hpp>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user