Compare commits
	
		
			198 Commits
		
	
	
		
			release-d2
			...
			03d4a5736e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 03d4a5736e | |||
| a2e41e6527 | |||
| 40a7caff90 | |||
| 26fc5565e8 | |||
| 388541ce32 | |||
| 6c194667b9 | |||
| 62d0579f40 | |||
| 202595b2a6 | |||
| cb21ff3f04 | |||
| 2a8e3c2dc4 | |||
| 998066d377 | |||
| fefb876fe7 | |||
| 5979e9885e | |||
| a17abe4639 | |||
| d62f913855 | |||
| 12bb7475fc | |||
| df2c7e2b67 | |||
| 713aec887b | |||
| 3089cd7afc | |||
| 00638bc812 | |||
| e002109829 | |||
| b4798fd2ab | |||
| 3c804bf62a | |||
| d39d552bd9 | |||
| b7202a2b0d | |||
| 4e27a4c1f5 | |||
| 4ef31762d0 | |||
| 8b22a8f339 | |||
| d45ff05bcd | |||
| 671dd86206 | |||
| 0abadc1850 | |||
| 4e068d628c | |||
| 4461f99fa4 | |||
| cd1f4bdaa3 | |||
| 4728699585 | |||
| 105a1e5559 | |||
| 1bc18e34a8 | |||
| fb8d295fcb | |||
| 8459d3baea | |||
| 804d78e116 | |||
| 5351e9aa0a | |||
| b5954f15c5 | |||
| 5dce9dd377 | |||
| 0570f76236 | |||
| e22b658a67 | |||
| 56b9cb6ebf | |||
| eaa9a2415e | |||
| 95256a9a0d | |||
| 2286238abc | |||
| 13f0bf57e4 | |||
| 8eb1ac215b | |||
| e132f2fd1b | |||
| 12f6b22c8b | |||
| 6c858e0c4e | |||
| c6b58f7c63 | |||
| a22aafaf96 | |||
| 6298ac3a21 | |||
| cd63afacfe | |||
| 2859183742 | |||
| 8d04af691e | |||
| 055165974e | |||
| be51838775 | |||
| 1207dadee8 | |||
| 109e1898cc | |||
| a24bf7ffb9 | |||
| 046834c2b9 | |||
| f840240aac | |||
| cfa91d3d39 | |||
| f7a7a66a6a | |||
| 5145595d57 | |||
| f01d303381 | |||
| 098c8cb844 | |||
| 04ad0f0264 | |||
| 695e7a4561 | |||
| 7d53028faf | |||
| 6c34198f58 | |||
| 7e3e046109 | |||
| f63c58169f | |||
| e40b11246d | |||
| 161194c8b2 | |||
| 48603ea2c5 | |||
| e2f2a17315 | |||
| e8a0ce88c5 | |||
| 82e2ea747f | |||
| ff666eda9b | |||
| 0d8b82ba49 | |||
| 5598dfdd87 | |||
| 6ef462adcc | |||
| 9511cb5719 | |||
| 1cc1d561e2 | |||
| d15a0df7da | |||
| e1282b6bae | |||
| 5fe7c14ccb | |||
| 42165ba2d6 | |||
| 1af4da43ad | |||
| 4fa879a09e | |||
| fd8f1a29c6 | |||
| 9fda2763ba | |||
| cda23ac4af | |||
| c36b244dd3 | |||
| 335d278f5e | |||
| f987b02c65 | |||
| 3c056276c1 | |||
| 87e2fdefcf | |||
| 672b92b363 | |||
| 762a6517b2 | |||
| d141154a45 | |||
| 6170647c0c | |||
| 48e45c7dd6 | |||
| 5d3d9229b7 | |||
| d54e93d836 | |||
| 830f8fe3e4 | |||
| 7b638538aa | |||
| 2016f6e605 | |||
| 240effd305 | |||
| 6bc629e02c | |||
| f6f2acd67b | |||
| 0146d38405 | |||
| 75d8e7bb89 | |||
| 6b53eaf6b1 | |||
| 16c32273ac | |||
| 1567a6e29d | |||
| 89d543bcbc | |||
| d68e64931b | |||
| 1cbc576286 | |||
| 500b93562c | |||
| 800ca85176 | |||
| cc466a9f1d | |||
| 9d1155843e | |||
| a2139c09b2 | |||
| a3e5f27ab8 | |||
| 643f95ec80 | |||
| 6924147686 | |||
| 6e2b4fa7b4 | |||
| 4e5c749918 | |||
| 66229de77f | |||
| 7eb37c5318 | |||
| 7a21b20711 | |||
| 894be237f2 | |||
| 92e9d9cbfc | |||
| b29b9a9b3a | |||
| 721f844214 | |||
| a3d6a58cc8 | |||
| e598e7fe27 | |||
| ba9e720f9f | |||
| 8e816a261f | |||
| 5b9929ab3d | |||
| ceb54b3f1b | |||
| 8764444758 | |||
| ce9a0b1fdb | |||
| f7a468ea1e | |||
| 861d177a27 | |||
| 3936756b36 | |||
| 3e78ec3fe5 | |||
| 3c3d53b40c | |||
| 151d7c5736 | |||
| 4e4d8d2c3f | |||
| 03d1fd2857 | |||
| 6701decc91 | |||
| 6cff526647 | |||
| dd50bd0249 | |||
| 55a1660242 | |||
| ed365dfef5 | |||
| 23a09e4a13 | |||
| b69e7ebb98 | |||
| 418d6e3f22 | |||
| c44d8678cb | |||
| eb4cd7106d | |||
| d259770f32 | |||
| 80bad608f7 | |||
| 2bce9a2baf | |||
| 791b7746f3 | |||
| 842e3587fd | |||
| 318e79004b | |||
| 9f338a7429 | |||
| 645e48af7b | |||
| ef92c8df13 | |||
| 849d50be8e | |||
| 845092f114 | |||
| 75819a1797 | |||
| d66da85753 | |||
| 98ddb08abd | |||
| 8d1701b0bb | |||
| 1048e522fd | |||
| ee59da4aa3 | |||
| 1ba64cb5d8 | |||
| 462bebf6dd | |||
| e3f84c4e75 | |||
| 6837a0556d | |||
| ede2c8ca37 | |||
| f50367f7d5 | |||
| e758e03d2b | |||
| 835e3270ce | |||
| 480dd5ece4 | |||
| dba6bb5800 | |||
| 40a456e54a | |||
| bf5be00c12 | |||
| dc7c2559d6 | 
| @@ -4,7 +4,7 @@ on: [push] | ||||
|  | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: nostalgia | ||||
|     runs-on: olympic | ||||
|     steps: | ||||
|       - name: Check out repository code | ||||
|         uses: actions/checkout@v3 | ||||
|   | ||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -6,7 +6,7 @@ | ||||
| .mypy_cache | ||||
| .stfolder | ||||
| .stignore | ||||
| scripts/__pycache__ | ||||
| util/scripts/__pycache__ | ||||
| pyenv | ||||
| CMakeLists.txt.user | ||||
| ROM.oxfs | ||||
|   | ||||
							
								
								
									
										19
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,26 +1,31 @@ | ||||
| BC_VAR_PROJECT_NAME=nostalgia | ||||
| BC_VAR_PROJECT_NAME_CAP=Nostalgia | ||||
| BC_VAR_DEVENV_ROOT=util | ||||
| BUILDCORE_PATH=deps/buildcore | ||||
| include ${BUILDCORE_PATH}/base.mk | ||||
|  | ||||
| ifeq ($(BC_VAR_OS),darwin) | ||||
| 	NOSTALGIA_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio.app/Contents/MacOS/${BC_VAR_PROJECT_NAME_CAP}Studio | ||||
| 	PROJECT_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio.app/Contents/MacOS/${BC_VAR_PROJECT_NAME_CAP}Studio | ||||
| 	MGBA=/Applications/mGBA.app/Contents/MacOS/mGBA | ||||
| else | ||||
| 	NOSTALGIA_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio | ||||
| 	PROJECT_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio | ||||
| 	MGBA=mgba-qt | ||||
| endif | ||||
| PROJECT_PLAYER=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP} | ||||
|  | ||||
| .PHONY: pkg-gba | ||||
| pkg-gba: build | ||||
| 	${BC_CMD_ENVRUN} ${BC_PY3} ./scripts/pkg-gba.py sample_project ${BC_VAR_PROJECT_NAME} | ||||
| 	${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/pkg-gba.py sample_project ${BC_VAR_PROJECT_NAME} | ||||
|  | ||||
| .PHONY: build-player | ||||
| build-player: | ||||
| 	${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} ${BC_VAR_PROJECT_NAME_CAP} | ||||
| .PHONY: run | ||||
| run: build | ||||
| 	./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME} sample_project | ||||
| run: build-player | ||||
| 	${PROJECT_PLAYER} sample_project | ||||
| .PHONY: run-studio | ||||
| run-studio: build | ||||
| 	${NOSTALGIA_STUDIO} | ||||
| 	${PROJECT_STUDIO} | ||||
| .PHONY: gba-run | ||||
| gba-run: pkg-gba | ||||
| 	${MGBA} ${BC_VAR_PROJECT_NAME}.gba | ||||
| @@ -29,7 +34,7 @@ debug: build | ||||
| 	${BC_CMD_HOST_DEBUGGER} ./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME} sample_project | ||||
| .PHONY: debug-studio | ||||
| debug-studio: build | ||||
| 	${BC_CMD_HOST_DEBUGGER} ${NOSTALGIA_STUDIO} | ||||
| 	${BC_CMD_HOST_DEBUGGER} ${PROJECT_STUDIO} | ||||
|  | ||||
| .PHONY: configure-gba | ||||
| configure-gba: | ||||
|   | ||||
							
								
								
									
										2
									
								
								deps/buildcore/base.mk
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/buildcore/base.mk
									
									
									
									
										vendored
									
									
								
							| @@ -93,7 +93,7 @@ purge: | ||||
| 	${BC_CMD_RM_RF} compile_commands.json | ||||
| .PHONY: test | ||||
| test: build | ||||
| 	${BC_CMD_ENVRUN} mypy ${BC_VAR_SCRIPTS} | ||||
| 	${BC_CMD_ENVRUN} ${BC_CMD_PY3} -m mypy ${BC_VAR_SCRIPTS} | ||||
| 	${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} test | ||||
| .PHONY: test-verbose | ||||
| test-verbose: build | ||||
|   | ||||
							
								
								
									
										4
									
								
								deps/gbabuildcore/base.cmake
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/gbabuildcore/base.cmake
									
									
									
									
										vendored
									
									
								
							| @@ -1,8 +1,8 @@ | ||||
| list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/modules) | ||||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib") | ||||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++") | ||||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-unwind-tables") | ||||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") | ||||
| #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-unwind-tables") | ||||
| #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") | ||||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") | ||||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") | ||||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb-interwork") | ||||
|   | ||||
							
								
								
									
										11
									
								
								deps/glad/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								deps/glad/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +1,11 @@ | ||||
| add_library(glad OBJECT src/glad.c) | ||||
| add_library(glad src/glad.c) | ||||
|  | ||||
| target_include_directories(glad PUBLIC include) | ||||
|  | ||||
| install( | ||||
| 	TARGETS | ||||
| 		glad | ||||
| 	DESTINATION | ||||
| 		LIBRARY DESTINATION lib | ||||
| 		ARCHIVE DESTINATION lib | ||||
| ) | ||||
|   | ||||
							
								
								
									
										10
									
								
								deps/imgui/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								deps/imgui/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -6,7 +6,7 @@ endif() | ||||
| # DrinkingTea: end | ||||
|  | ||||
| add_library( | ||||
| 	imgui OBJECT | ||||
| 	imgui | ||||
| 		imgui.cpp | ||||
| 		imgui_demo.cpp | ||||
| 		imgui_draw.cpp | ||||
| @@ -20,3 +20,11 @@ target_include_directories( | ||||
| 	imgui SYSTEM PUBLIC | ||||
| 		. | ||||
| ) | ||||
|  | ||||
| install( | ||||
| 	TARGETS | ||||
| 		imgui | ||||
| 	DESTINATION | ||||
| 		LIBRARY DESTINATION lib | ||||
| 		ARCHIVE DESTINATION lib | ||||
| ) | ||||
|   | ||||
							
								
								
									
										2
									
								
								deps/nfde/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/nfde/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| cmake_minimum_required(VERSION 3.5) | ||||
| cmake_minimum_required(VERSION 3.19) | ||||
| project(nativefiledialog-extended VERSION 1.1.1) | ||||
|  | ||||
| set(nfd_ROOT_PROJECT OFF) | ||||
|   | ||||
							
								
								
									
										2
									
								
								deps/ox/deps/jsoncpp/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/deps/jsoncpp/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -12,7 +12,7 @@ | ||||
| # CMake versions greater than the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION policies will | ||||
| # continue to generate policy warnings "CMake Warning (dev)...Policy CMP0XXX is not set:" | ||||
| # | ||||
| set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.8.0") | ||||
| set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.13.2") | ||||
| set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.2") | ||||
| cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION}) | ||||
| if("${CMAKE_VERSION}" VERSION_LESS "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}") | ||||
|   | ||||
							
								
								
									
										12
									
								
								deps/ox/src/ox/event/signal.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								deps/ox/src/ox/event/signal.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -143,6 +143,11 @@ class Signal { | ||||
|  | ||||
| 		Error disconnectObject(const void *receiver) const noexcept; | ||||
|  | ||||
| 		[[nodiscard]] | ||||
| 		size_t connectionCnt() const noexcept { | ||||
| 			return m_slots.size(); | ||||
| 		} | ||||
|  | ||||
| 		void emit(Args... args) const; | ||||
|  | ||||
| 		Error emitCheckError(Args... args) const noexcept; | ||||
| @@ -215,7 +220,7 @@ Error Signal<Args...>::emitCheckError(Args... args) const noexcept { | ||||
| 		} | ||||
| 		return ox::Error(0); | ||||
| 	} catch (const ox::Exception &ex) { | ||||
| 		return ox::Error(ex.file, ex.line, ex.errCode, ex.msg); | ||||
| 		return ox::Error(ex.errCode, ex.msg, ex.src); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -319,6 +324,11 @@ class Signal<Error(Args...)> { | ||||
|  | ||||
| 		Error disconnectObject(const void *receiver) const noexcept; | ||||
|  | ||||
| 		[[nodiscard]] | ||||
| 		size_t connectionCnt() const noexcept { | ||||
| 			return m_slots.size(); | ||||
| 		} | ||||
|  | ||||
| 		void emit(Args... args) const noexcept; | ||||
|  | ||||
| 		Error emitCheckError(Args... args) const noexcept; | ||||
|   | ||||
							
								
								
									
										53
									
								
								deps/ox/src/ox/fs/filesystem/filesystem.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								deps/ox/src/ox/fs/filesystem/filesystem.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -37,6 +37,30 @@ Error FileSystem::read(const FileAddress &addr, void *buffer, std::size_t size) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| Result<Buffer> FileSystem::read(FileAddress const &addr, size_t const size) noexcept { | ||||
| 	Result<Buffer> out; | ||||
| 	out.value.resize(size); | ||||
| 	switch (addr.type()) { | ||||
| 		case FileAddressType::Inode: | ||||
| 			OX_RETURN_ERROR(readFileInode(addr.getInode().value, out.value.data(), size)); | ||||
| 			break; | ||||
| 		case FileAddressType::ConstPath: | ||||
| 		case FileAddressType::Path: | ||||
| 			OX_RETURN_ERROR(readFilePath(StringView{addr.getPath().value}, out.value.data(), size)); | ||||
| 			break; | ||||
| 		default: | ||||
| 			return ox::Error{1}; | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| Result<Buffer> FileSystem::read(StringViewCR path, size_t const size) noexcept { | ||||
| 	Result<Buffer> out; | ||||
| 	out.value.resize(size); | ||||
| 	OX_RETURN_ERROR(readFilePath(path, out.value.data(), size)); | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| Result<Buffer> FileSystem::read(const FileAddress &addr) noexcept { | ||||
| 	OX_REQUIRE(s, stat(addr)); | ||||
| 	Buffer buff(static_cast<std::size_t>(s.size)); | ||||
| @@ -51,28 +75,31 @@ Result<Buffer> FileSystem::read(StringViewCR path) noexcept { | ||||
| 	return buff; | ||||
| } | ||||
|  | ||||
| Error FileSystem::read(const FileAddress &addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept { | ||||
| Error FileSystem::read( | ||||
| 		FileAddress const &addr, | ||||
| 		std::size_t const readStart, | ||||
| 		std::size_t const readSize, | ||||
| 		void *buffer, | ||||
| 		std::size_t *size) noexcept { | ||||
| 	switch (addr.type()) { | ||||
| 		case FileAddressType::Inode: | ||||
| 			return read(addr.getInode().value, readStart, readSize, buffer, size); | ||||
| 			return readFileInodeRange(addr.getInode().value, readStart, readSize, buffer, size); | ||||
| 		case FileAddressType::ConstPath: | ||||
| 		case FileAddressType::Path: | ||||
| 			return ox::Error(2, "Unsupported for path lookups"); | ||||
| 			return readFilePathRange(addr.getPath().value, readStart, readSize, buffer, size); | ||||
| 		default: | ||||
| 			return ox::Error(1); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| Error FileSystem::remove(const FileAddress &addr, bool recursive) noexcept { | ||||
| 	switch (addr.type()) { | ||||
| 		case FileAddressType::Inode: | ||||
| 			return remove(addr.getInode().value, recursive); | ||||
| 		case FileAddressType::ConstPath: | ||||
| 		case FileAddressType::Path: | ||||
| 			return remove(StringView(addr.getPath().value), recursive); | ||||
| 		default: | ||||
| 			return ox::Error(1); | ||||
| 	} | ||||
| Result<size_t> FileSystem::read( | ||||
| 		StringViewCR path, | ||||
| 		std::size_t const readStart, | ||||
| 		std::size_t const readSize, | ||||
| 		Span<char> buff) noexcept { | ||||
| 	size_t szOut{buff.size()}; | ||||
| 	OX_RETURN_ERROR(readFilePathRange(path, readStart, readSize, buff.data(), &szOut)); | ||||
| 	return szOut; | ||||
| } | ||||
|  | ||||
| Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType) noexcept { | ||||
|   | ||||
							
								
								
									
										88
									
								
								deps/ox/src/ox/fs/filesystem/filesystem.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								deps/ox/src/ox/fs/filesystem/filesystem.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -41,6 +41,10 @@ class FileSystem { | ||||
|  | ||||
| 		Error read(const FileAddress &addr, void *buffer, std::size_t size) noexcept; | ||||
|  | ||||
| 		Result<Buffer> read(FileAddress const &addr, size_t size) noexcept; | ||||
|  | ||||
| 		Result<Buffer> read(StringViewCR path, size_t size) noexcept; | ||||
|  | ||||
| 		Result<Buffer> read(const FileAddress &addr) noexcept; | ||||
|  | ||||
| 		Result<Buffer> read(StringViewCR path) noexcept; | ||||
| @@ -53,13 +57,30 @@ class FileSystem { | ||||
| 			return readFileInode(inode, buffer, buffSize); | ||||
| 		} | ||||
|  | ||||
| 		Error read(const FileAddress &addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept; | ||||
| 		Error read( | ||||
| 			FileAddress const &addr, | ||||
| 			size_t readStart, | ||||
| 			size_t readSize, | ||||
| 			void *buffer, | ||||
| 			size_t *size) noexcept; | ||||
|  | ||||
| 		/** | ||||
| 		 * | ||||
| 		 * @param path | ||||
| 		 * @param readStart | ||||
| 		 * @param readSize | ||||
| 		 * @param buffer | ||||
| 		 * @param size | ||||
| 		 * @return error or number of bytes read | ||||
| 		 */ | ||||
| 		Result<size_t> read( | ||||
| 			StringViewCR path, size_t readStart, size_t readSize, ox::Span<char> buff) noexcept; | ||||
|  | ||||
| 		virtual Result<Vector<String>> ls(StringViewCR dir) const noexcept = 0; | ||||
|  | ||||
| 		virtual Error remove(StringViewCR path, bool recursive) noexcept = 0; | ||||
|  | ||||
| 		Error remove(const FileAddress &addr, bool recursive = false) noexcept; | ||||
| 		Error remove(StringViewCR path, bool recursive = false) noexcept { | ||||
| 			return removePath(path, recursive); | ||||
| 		} | ||||
|  | ||||
| 		virtual Error resize(uint64_t size, void *buffer) noexcept = 0; | ||||
|  | ||||
| @@ -140,7 +161,12 @@ class FileSystem { | ||||
|  | ||||
| 		virtual Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept = 0; | ||||
|  | ||||
| 		virtual Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept = 0; | ||||
| 		virtual Error readFilePathRange( | ||||
| 			StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept = 0; | ||||
|  | ||||
| 		virtual Error readFileInodeRange(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) noexcept = 0; | ||||
|  | ||||
| 		virtual Error removePath(StringViewCR path, bool recursive) noexcept = 0; | ||||
|  | ||||
| 		virtual Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept = 0; | ||||
|  | ||||
| @@ -209,6 +235,11 @@ class FileSystemTemplate: public MemFS { | ||||
|  | ||||
| 		Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override; | ||||
|  | ||||
| 		Error readFilePathRange( | ||||
| 			StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept override; | ||||
|  | ||||
| 		Error removePath(StringViewCR path, bool recursive) noexcept override; | ||||
|  | ||||
| 		Result<const char*> directAccessInode(uint64_t) const noexcept override; | ||||
|  | ||||
| 		Result<Vector<String>> ls(StringViewCR dir) const noexcept override; | ||||
| @@ -216,8 +247,6 @@ class FileSystemTemplate: public MemFS { | ||||
| 		template<typename F> | ||||
| 		Error ls(StringViewCR path, F cb) const; | ||||
|  | ||||
| 		Error remove(StringViewCR path, bool recursive) noexcept override; | ||||
|  | ||||
| 		/** | ||||
| 		 * Resizes FileSystem to minimum possible size. | ||||
| 		 */ | ||||
| @@ -356,6 +385,32 @@ Error FileSystemTemplate<FileStore, Directory>::readFileInodeRange(uint64_t inod | ||||
| 	return m_fs.read(inode, readStart, readSize, reinterpret_cast<uint8_t*>(buffer), size); | ||||
| } | ||||
|  | ||||
| template<typename FileStore, typename Directory> | ||||
| Error FileSystemTemplate<FileStore, Directory>::readFilePathRange( | ||||
| 	StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept { | ||||
| 	OX_REQUIRE(s, stat(path)); | ||||
| 	return readFileInodeRange(s.inode, readStart, readSize, buffer, buffSize); | ||||
| } | ||||
|  | ||||
| template<typename FileStore, typename Directory> | ||||
| Error FileSystemTemplate<FileStore, Directory>::removePath(StringViewCR path, bool recursive) noexcept { | ||||
| 	OX_REQUIRE(fd, fileSystemData()); | ||||
| 	Directory rootDir(m_fs, fd.rootDirInode); | ||||
| 	OX_REQUIRE(inode, rootDir.find(path)); | ||||
| 	OX_REQUIRE(st, statInode(inode)); | ||||
| 	if (st.fileType == FileType::NormalFile || recursive) { | ||||
| 		if (auto err = rootDir.remove(path)) { | ||||
| 			// removal failed, try putting the index back | ||||
| 			oxLogError(rootDir.write(path, inode)); | ||||
| 			return err; | ||||
| 		} | ||||
| 	} else { | ||||
| 		oxTrace("FileSystemTemplate.remove.fail", "Tried to remove directory without recursive setting."); | ||||
| 		return ox::Error(1); | ||||
| 	} | ||||
| 	return ox::Error(0); | ||||
| } | ||||
|  | ||||
| template<typename FileStore, typename Directory> | ||||
| Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(uint64_t inode) const noexcept { | ||||
| 	auto data = m_fs.read(inode); | ||||
| @@ -384,25 +439,6 @@ Error FileSystemTemplate<FileStore, Directory>::ls(StringViewCR path, F cb) cons | ||||
| 	return dir.ls(cb); | ||||
| } | ||||
|  | ||||
| template<typename FileStore, typename Directory> | ||||
| Error FileSystemTemplate<FileStore, Directory>::remove(StringViewCR path, bool recursive) noexcept { | ||||
| 	OX_REQUIRE(fd, fileSystemData()); | ||||
| 	Directory rootDir(m_fs, fd.rootDirInode); | ||||
| 	OX_REQUIRE(inode, rootDir.find(path)); | ||||
| 	OX_REQUIRE(st, statInode(inode)); | ||||
| 	if (st.fileType == FileType::NormalFile || recursive) { | ||||
| 		if (auto err = rootDir.remove(path)) { | ||||
| 			// removal failed, try putting the index back | ||||
| 			oxLogError(rootDir.write(path, inode)); | ||||
| 			return err; | ||||
| 		} | ||||
| 	} else { | ||||
| 		oxTrace("FileSystemTemplate.remove.fail", "Tried to remove directory without recursive setting."); | ||||
| 		return ox::Error(1); | ||||
| 	} | ||||
| 	return ox::Error(0); | ||||
| } | ||||
|  | ||||
| template<typename FileStore, typename Directory> | ||||
| Error FileSystemTemplate<FileStore, Directory>::resize() noexcept { | ||||
| 	return m_fs.resize(); | ||||
|   | ||||
							
								
								
									
										42
									
								
								deps/ox/src/ox/fs/filesystem/passthroughfs.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								deps/ox/src/ox/fs/filesystem/passthroughfs.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -75,14 +75,6 @@ Result<Vector<String>> PassThroughFS::ls(StringViewCR dir) const noexcept { | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| Error PassThroughFS::remove(StringViewCR path, bool recursive) noexcept { | ||||
| 	if (recursive) { | ||||
| 		return ox::Error(std::filesystem::remove_all(m_path / stripSlash(path)) != 0); | ||||
| 	} else { | ||||
| 		return ox::Error(std::filesystem::remove(m_path / stripSlash(path)) != 0); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| Error PassThroughFS::resize(uint64_t, void*) noexcept { | ||||
| 	// unsupported | ||||
| 	return ox::Error(1, "resize is not supported by PassThroughFS"); | ||||
| @@ -101,7 +93,9 @@ Result<FileStat> PassThroughFS::statPath(StringViewCR path) const noexcept { | ||||
| 	oxTracef("ox.fs.PassThroughFS.statInode", "{} {}", ec.message(), path); | ||||
| 	const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec); | ||||
| 	oxTracef("ox.fs.PassThroughFS.statInode.size", "{} {}", path, size); | ||||
| 	OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: stat failed")); | ||||
| 	if (auto err = ec.value()) { | ||||
| 		return ox::Error{static_cast<ox::ErrorCode>(err), "PassThroughFS: stat failed"}; | ||||
| 	} | ||||
| 	return FileStat{0, 0, size, type}; | ||||
| } | ||||
|  | ||||
| @@ -162,11 +156,38 @@ Error PassThroughFS::readFileInode(uint64_t, void*, std::size_t) noexcept { | ||||
| 	return ox::Error(1, "readFileInode(uint64_t, void*, std::size_t) is not supported by PassThroughFS"); | ||||
| } | ||||
|  | ||||
| Error PassThroughFS::readFilePathRange( | ||||
| 	StringViewCR path, size_t const readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept { | ||||
| 	try { | ||||
| 		std::ifstream file(m_path / stripSlash(path), std::ios::binary | std::ios::ate); | ||||
| 		auto const size = static_cast<size_t>(file.tellg()); | ||||
| 		readSize = ox::min(readSize, size); | ||||
| 		file.seekg(static_cast<off_t>(readStart), std::ios::beg); | ||||
| 		if (readSize > *buffSize) { | ||||
| 			oxTracef("ox.fs.PassThroughFS.read.error", "Read failed: Buffer too small: {}", path); | ||||
| 			return ox::Error{1}; | ||||
| 		} | ||||
| 		file.read(static_cast<char*>(buffer), static_cast<std::streamsize>(readSize)); | ||||
| 		return {}; | ||||
| 	} catch (std::fstream::failure const &f) { | ||||
| 		oxTracef("ox.fs.PassThroughFS.read.error", "Read of {} failed: {}", path, f.what()); | ||||
| 		return ox::Error{2}; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| Error PassThroughFS::readFileInodeRange(uint64_t, std::size_t, std::size_t, void*, std::size_t*) noexcept { | ||||
| 	// unsupported | ||||
| 	return ox::Error(1, "read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) is not supported by PassThroughFS"); | ||||
| } | ||||
|  | ||||
| Error PassThroughFS::removePath(StringViewCR path, bool const recursive) noexcept { | ||||
| 	if (recursive) { | ||||
| 		return ox::Error{std::filesystem::remove_all(m_path / stripSlash(path)) == 0}; | ||||
| 	} else { | ||||
| 		return ox::Error{!std::filesystem::remove(m_path / stripSlash(path))}; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| Error PassThroughFS::writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType) noexcept { | ||||
| 	const auto p = (m_path / stripSlash(path)); | ||||
| 	try { | ||||
| @@ -185,8 +206,7 @@ Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) n | ||||
| } | ||||
|  | ||||
| std::string_view PassThroughFS::stripSlash(StringView path) noexcept { | ||||
| 	const auto pathLen = ox::strlen(path); | ||||
| 	for (auto i = 0u; i < pathLen && path[0] == '/'; i++) { | ||||
| 	for (auto i = 0u; i < path.len() && path[0] == '/'; i++) { | ||||
| 		path = substr(path, 1); | ||||
| 	} | ||||
| 	return {path.data(), path.bytes()}; | ||||
|   | ||||
| @@ -45,8 +45,6 @@ class PassThroughFS: public FileSystem { | ||||
| 		template<typename F> | ||||
| 		Error ls(StringViewCR dir, F cb) const noexcept; | ||||
|  | ||||
| 		Error remove(StringViewCR path, bool recursive) noexcept override; | ||||
|  | ||||
| 		Error resize(uint64_t size, void *buffer) noexcept override; | ||||
|  | ||||
| 		Result<FileStat> statInode(uint64_t inode) const noexcept override; | ||||
| @@ -73,8 +71,13 @@ class PassThroughFS: public FileSystem { | ||||
|  | ||||
| 		Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override; | ||||
|  | ||||
| 		Error readFilePathRange( | ||||
| 			StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept override; | ||||
|  | ||||
| 		Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override; | ||||
|  | ||||
| 		Error removePath(StringViewCR path, bool recursive) noexcept override; | ||||
|  | ||||
| 		Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept override; | ||||
|  | ||||
| 		Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override; | ||||
|   | ||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/logconn/def.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/logconn/def.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -14,7 +14,7 @@ | ||||
|     { \ | ||||
| 		const auto loggerErr = (loggerName).initConn(appName); \ | ||||
| 		if (loggerErr) { \ | ||||
| 			oxErrf("Could not connect to logger: {} ({}:{})\n", toStr(loggerErr), loggerErr.file, loggerErr.line); \ | ||||
| 			oxErrf("Could not connect to logger: {} ({}:{})\n", toStr(loggerErr), loggerErr.src.file_name(), loggerErr.src.line()); \ | ||||
| 		} else { \ | ||||
| 			ox::trace::setLogger(&(loggerName)); \ | ||||
| 		} \ | ||||
|   | ||||
							
								
								
									
										6
									
								
								deps/ox/src/ox/model/typenamecatcher.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/ox/src/ox/model/typenamecatcher.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -140,16 +140,16 @@ constexpr Str getModelTypeName() noexcept { | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| template<typename T, typename Str = const char*> | ||||
| [[nodiscard]] | ||||
| consteval auto requireModelTypeName() noexcept { | ||||
| 	constexpr auto name = getModelTypeName<T>(); | ||||
| 	constexpr auto name = getModelTypeName<T, Str>(); | ||||
| 	static_assert(ox::StringView{name}.len(), "Type lacks required TypeName"); | ||||
| 	return name; | ||||
| } | ||||
|  | ||||
| template<typename T, typename Str = const char*> | ||||
| constexpr auto ModelTypeName_v = getModelTypeName<T, Str>(); | ||||
| constexpr auto ModelTypeName_v = requireModelTypeName<T, Str>(); | ||||
|  | ||||
| template<typename T, typename Str = const char*> | ||||
| constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>(); | ||||
|   | ||||
							
								
								
									
										9
									
								
								deps/ox/src/ox/oc/read.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								deps/ox/src/ox/oc/read.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -144,7 +144,11 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept { | ||||
| 				if (jv.empty()) { | ||||
| 					*val = 0; | ||||
| 				} else if (rightType) { | ||||
| 					*val = static_cast<T>(jv.asUInt()); | ||||
| 					if constexpr(ox::is_signed_v<T>) { | ||||
| 						*val = static_cast<T>(jv.asInt64()); | ||||
| 					} else { | ||||
| 						*val = static_cast<T>(jv.asUInt64()); | ||||
| 					} | ||||
| 				} else { | ||||
| 					err = ox::Error(1, "Type mismatch"); | ||||
| 				} | ||||
| @@ -172,7 +176,8 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept { | ||||
| 				err = ox::Error(1, "Type mismatch"); | ||||
| 			} | ||||
| 		} | ||||
| 	} catch (Json::LogicError const&) { | ||||
| 	} catch (Json::LogicError const&e) { | ||||
| 		oxDebugf("JSON error: {}", e.what()); | ||||
| 		err = ox::Error(1, "error reading JSON data"); | ||||
| 	} | ||||
| 	++m_fieldIt; | ||||
|   | ||||
							
								
								
									
										14
									
								
								deps/ox/src/ox/std/algorithm.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								deps/ox/src/ox/std/algorithm.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -9,13 +9,25 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "def.hpp" | ||||
| #include "error.hpp" | ||||
|  | ||||
| OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage) | ||||
|  | ||||
| namespace ox { | ||||
|  | ||||
| template<typename It, typename T> | ||||
| constexpr It find(It begin, It end, const T &value) { | ||||
| constexpr ox::Result<size_t> findIdx(It begin, It end, T const&value) { | ||||
| 	auto it = begin; | ||||
| 	for (; it != end; ++it) { | ||||
| 		if (*it == value) { | ||||
| 			return it.offset(); | ||||
| 		} | ||||
| 	} | ||||
| 	return ox::Error{1, "item not found"}; | ||||
| } | ||||
|  | ||||
| template<typename It, typename T> | ||||
| constexpr It find(It begin, It end, T const&value) { | ||||
| 	for (; begin != end; ++begin) { | ||||
| 		if (*begin == value) { | ||||
| 			return begin; | ||||
|   | ||||
							
								
								
									
										89
									
								
								deps/ox/src/ox/std/anyptr.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										89
									
								
								deps/ox/src/ox/std/anyptr.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -15,18 +15,22 @@ | ||||
|  | ||||
| namespace ox { | ||||
|  | ||||
| class AnyPtr { | ||||
| namespace detail { | ||||
|  | ||||
| template<bool unique> | ||||
| class AnyPtrT { | ||||
| 	private: | ||||
| 		struct WrapBase { | ||||
| 			virtual constexpr ~WrapBase() = default; | ||||
| 			virtual constexpr WrapBase *copyTo(ox::Span<char> s) noexcept = 0; | ||||
| 			virtual constexpr operator bool() const noexcept = 0; | ||||
| 			virtual void free() noexcept = 0; | ||||
| 		}; | ||||
|  | ||||
| 		template<typename T> | ||||
| 		struct Wrap: public WrapBase { | ||||
| 		struct Wrap final: WrapBase { | ||||
| 			T *data{}; | ||||
| 			constexpr Wrap(T *pData) noexcept: data(pData) { | ||||
| 			explicit constexpr Wrap(T *pData) noexcept: data(pData) { | ||||
| 			} | ||||
| 			constexpr WrapBase *copyTo(ox::Span<char> s) noexcept override { | ||||
| 				oxAssert(s.size() >= sizeof(Wrap), "too small buffer"); | ||||
| @@ -39,39 +43,60 @@ class AnyPtr { | ||||
| 			constexpr operator bool() const noexcept override { | ||||
| 				return data != nullptr; | ||||
| 			} | ||||
| 			constexpr void free() noexcept override { | ||||
| 				safeDelete(data); | ||||
| 				data = {}; | ||||
| 			} | ||||
| 		}; | ||||
|  | ||||
| 		WrapBase *m_wrapPtr{}; | ||||
| 		ox::Array<char, sizeof(Wrap<void*>)> m_wrapData; | ||||
|  | ||||
| 	public: | ||||
| 		constexpr AnyPtr() noexcept = default; | ||||
| 		constexpr AnyPtrT() noexcept = default; | ||||
|  | ||||
| 		template<typename T> | ||||
| 		constexpr AnyPtr(T *ptr) noexcept { | ||||
| 		constexpr AnyPtrT(T *ptr) noexcept { | ||||
| 			if (std::is_constant_evaluated()) { | ||||
| 				m_wrapPtr = new Wrap(ptr); | ||||
| 				m_wrapPtr = new Wrap<T>(ptr); | ||||
| 			} else { | ||||
| 				m_wrapPtr = new(m_wrapData.data()) Wrap(ptr); | ||||
| 				m_wrapPtr = new(m_wrapData.data()) Wrap<T>(ptr); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		constexpr AnyPtr(AnyPtr const&other) noexcept { | ||||
| 		constexpr AnyPtrT(AnyPtrT const&other) noexcept requires(!unique) { | ||||
| 			if (other) { | ||||
| 				m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		constexpr ~AnyPtr() noexcept { | ||||
| 		constexpr AnyPtrT(AnyPtrT &&other) noexcept { | ||||
| 			if (other) { | ||||
| 				m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData); | ||||
| 				if (std::is_constant_evaluated()) { | ||||
| 					ox::safeDelete(m_wrapPtr); | ||||
| 				} | ||||
| 				other.m_wrapPtr = {}; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		constexpr ~AnyPtrT() noexcept { | ||||
| 			if constexpr(unique) { | ||||
| 				free(); | ||||
| 			} | ||||
| 			if (std::is_constant_evaluated()) { | ||||
| 				ox::safeDelete(m_wrapPtr); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		template<typename T> | ||||
| 		constexpr AnyPtr &operator=(T *ptr) noexcept { | ||||
| 			if (std::is_constant_evaluated()) { | ||||
| 		constexpr AnyPtrT &operator=(T *ptr) noexcept { | ||||
| 			if constexpr(unique) { | ||||
| 				free(); | ||||
| 			} else if (std::is_constant_evaluated()) { | ||||
| 				ox::safeDelete(m_wrapPtr); | ||||
| 			} | ||||
| 			if (std::is_constant_evaluated()) { | ||||
| 				m_wrapPtr = new Wrap(ptr); | ||||
| 			} else { | ||||
| 				m_wrapPtr = new(m_wrapData.data()) Wrap(ptr); | ||||
| @@ -79,10 +104,12 @@ class AnyPtr { | ||||
| 			return *this; | ||||
| 		} | ||||
|  | ||||
| 		constexpr AnyPtr &operator=(AnyPtr const&ptr) noexcept { | ||||
| 		constexpr AnyPtrT &operator=(AnyPtrT const&ptr) noexcept requires(!unique) { | ||||
| 			if (this != &ptr) { | ||||
| 				if (ptr) { | ||||
| 				if (std::is_constant_evaluated()) { | ||||
| 					ox::safeDelete(m_wrapPtr); | ||||
| 				} | ||||
| 				if (ptr) { | ||||
| 					m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData); | ||||
| 				} else { | ||||
| 					m_wrapPtr = nullptr; | ||||
| @@ -91,10 +118,40 @@ class AnyPtr { | ||||
| 			return *this; | ||||
| 		} | ||||
|  | ||||
| 		constexpr AnyPtrT &operator=(AnyPtrT &&ptr) noexcept { | ||||
| 			if (this != &ptr) { | ||||
| 				if constexpr(unique) { | ||||
| 					free(); | ||||
| 				} else if (std::is_constant_evaluated()) { | ||||
| 					ox::safeDelete(m_wrapPtr); | ||||
| 				} | ||||
| 				if (ptr) { | ||||
| 					m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData); | ||||
| 					if (std::is_constant_evaluated()) { | ||||
| 						ox::safeDelete(ptr.m_wrapPtr); | ||||
| 						ptr.m_wrapPtr = nullptr; | ||||
| 					} | ||||
| 				} else { | ||||
| 					m_wrapPtr = nullptr; | ||||
| 				} | ||||
| 			} | ||||
| 			return *this; | ||||
| 		} | ||||
|  | ||||
| 		constexpr operator bool() const noexcept { | ||||
| 			return m_wrapPtr && *m_wrapPtr; | ||||
| 		} | ||||
|  | ||||
| 		constexpr void free() noexcept { | ||||
| 			if (m_wrapPtr) { | ||||
| 				m_wrapPtr->free(); | ||||
| 			} | ||||
| 			if (std::is_constant_evaluated()) { | ||||
| 				ox::safeDelete(m_wrapPtr); | ||||
| 			} | ||||
| 			m_wrapPtr = nullptr; | ||||
| 		} | ||||
|  | ||||
| 		template<typename T> | ||||
| 		[[nodiscard]] | ||||
| 		constexpr T *get() const noexcept { | ||||
| @@ -104,6 +161,12 @@ class AnyPtr { | ||||
| 			return dynamic_cast<Wrap<T>*>(m_wrapPtr)->data; | ||||
| #endif | ||||
| 		} | ||||
|  | ||||
| }; | ||||
|  | ||||
| } | ||||
|  | ||||
| using AnyPtr = detail::AnyPtrT<false>; | ||||
| using UAnyPtr = detail::AnyPtrT<true>; | ||||
|  | ||||
| } | ||||
							
								
								
									
										4
									
								
								deps/ox/src/ox/std/array.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/ox/src/ox/std/array.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -181,13 +181,13 @@ constexpr Array<T, ArraySize> &Array<T, ArraySize>::operator=(Array &&other) noe | ||||
|  | ||||
| template<typename T, std::size_t ArraySize> | ||||
| constexpr T &Array<T, ArraySize>::operator[](std::size_t i) noexcept { | ||||
| 	ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Array access overflow"); | ||||
| 	boundsCheck(__FILE__, __LINE__, i, size(), "Array access overflow"); | ||||
| 	return m_items[i]; | ||||
| } | ||||
|  | ||||
| template<typename T, std::size_t ArraySize> | ||||
| constexpr const T &Array<T, ArraySize>::operator[](std::size_t i) const noexcept { | ||||
| 	ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Array access overflow"); | ||||
| 	boundsCheck(__FILE__, __LINE__, i, size(), "Array access overflow"); | ||||
| 	return m_items[i]; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										35
									
								
								deps/ox/src/ox/std/assert.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								deps/ox/src/ox/std/assert.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -7,6 +7,7 @@ | ||||
|  */ | ||||
|  | ||||
| #include "fmt.hpp" | ||||
| #include "realstd.hpp" | ||||
| #include "stacktrace.hpp" | ||||
| #include "trace.hpp" | ||||
|  | ||||
| @@ -14,14 +15,14 @@ | ||||
|  | ||||
| namespace ox { | ||||
|  | ||||
| void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err) noexcept { | ||||
| void panic(StringViewCR file, int const line, StringViewCR panicMsg, Error const&err) noexcept { | ||||
| 	oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", file, line, panicMsg); | ||||
| 	if (err.msg) { | ||||
| 		oxErrf("\tError Message:\t{}\n", err.msg); | ||||
| 	} | ||||
| 	oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err)); | ||||
| 	if (err.file != nullptr) { | ||||
| 		oxErrf("\tError Location:\t{}:{}\n", err.file, err.line); | ||||
| 	if (err.src.file_name() != nullptr) { | ||||
| 		oxErrf("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line()); | ||||
| 	} | ||||
| #ifdef OX_USE_STDLIB | ||||
| 	printStackTrace(2); | ||||
| @@ -32,16 +33,19 @@ void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err) | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void panic(const char *file, int line, const char *panicMsg, const Error &err) noexcept { | ||||
| void panic(const char *file, int const line, char const*panicMsg, Error const&err) noexcept { | ||||
| 	panic(StringView{file}, line, StringView{panicMsg}, err); | ||||
| } | ||||
|  | ||||
| void assertFailFuncRuntime(StringViewCR file, int line, StringViewCR assertTxt, StringViewCR msg) noexcept { | ||||
| void assertFailFuncRuntime( | ||||
| 	StringViewCR file, | ||||
| 	int const line, | ||||
| 	StringViewCR assertTxt, | ||||
| 	StringViewCR msg) noexcept { | ||||
| #ifdef OX_USE_STDLIB | ||||
| 	auto output = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg); | ||||
| 	output += genStackTrace(2); | ||||
| 	oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line); | ||||
| 	std::abort(); | ||||
| 	auto const st = genStackTrace(2); | ||||
| 	oxTracef("assert", "Failed assert: {} ({}) [{}:{}]:\n{}", msg, assertTxt, file, line, st); | ||||
| 	abort(); | ||||
| #else | ||||
| 	oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg); | ||||
| 	oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line); | ||||
| @@ -49,20 +53,25 @@ void assertFailFuncRuntime(StringViewCR file, int line, StringViewCR assertTxt, | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void assertFailFuncRuntime(StringViewCR file, int line, [[maybe_unused]] const Error &err, StringViewCR, StringViewCR assertMsg) noexcept { | ||||
| void assertFailFuncRuntime( | ||||
| 	StringViewCR file, | ||||
| 	int const line, | ||||
| 	[[maybe_unused]] Error const&err, | ||||
| 	StringViewCR, | ||||
| 	StringViewCR assertMsg) noexcept { | ||||
| #if defined(OX_USE_STDLIB) | ||||
| 	auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg); | ||||
| 	if (err.msg) { | ||||
| 		msg += sfmt("\tError Message:\t{}\n", err.msg); | ||||
| 	} | ||||
| 	msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err)); | ||||
| 	if (err.file != nullptr) { | ||||
| 		msg += sfmt("\tError Location:\t{}:{}\n", err.file, err.line); | ||||
| 	if (err.src.file_name() != nullptr) { | ||||
| 		msg += sfmt("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line()); | ||||
| 	} | ||||
| 	msg += genStackTrace(2); | ||||
| 	oxErr(msg); | ||||
| 	oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line); | ||||
| 	std::abort(); | ||||
| 	abort(); | ||||
| #else | ||||
| 	constexprPanic(file, line, assertMsg); | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										43
									
								
								deps/ox/src/ox/std/assert.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								deps/ox/src/ox/std/assert.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -22,9 +22,15 @@ | ||||
|  | ||||
| namespace ox { | ||||
|  | ||||
| void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err = ox::Error(0)) noexcept; | ||||
| [[noreturn]] | ||||
| void panic(StringViewCR file, int line, StringViewCR panicMsg, Error const&err = {}) noexcept; | ||||
|  | ||||
| constexpr void constexprPanic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err = ox::Error(0)) noexcept { | ||||
| [[noreturn]] | ||||
| constexpr void constexprPanic( | ||||
| 	StringViewCR file, | ||||
| 	int const line, | ||||
| 	StringViewCR panicMsg, | ||||
| 	Error const&err = {}) noexcept { | ||||
| 	if (!std::is_constant_evaluated()) { | ||||
| 		panic(file, line, panicMsg, err); | ||||
| 	} else { | ||||
| @@ -32,10 +38,24 @@ constexpr void constexprPanic(StringViewCR file, int line, StringViewCR panicMsg | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void assertFailFuncRuntime(StringViewCR file, int line, StringViewCR assertTxt, StringViewCR msg) noexcept; | ||||
| void assertFailFuncRuntime(StringViewCR file, int line, const Error &err, StringViewCR, StringViewCR assertMsg) noexcept; | ||||
| void assertFailFuncRuntime( | ||||
| 	StringViewCR file, | ||||
| 	int line, | ||||
| 	StringViewCR assertTxt, | ||||
| 	StringViewCR msg) noexcept; | ||||
| void assertFailFuncRuntime( | ||||
| 	StringViewCR file, | ||||
| 	int line, | ||||
| 	Error const&err, | ||||
| 	StringViewCR, | ||||
| 	StringViewCR assertMsg) noexcept; | ||||
|  | ||||
| constexpr void assertFunc(StringViewCR file, int line, bool pass, [[maybe_unused]]StringViewCR assertTxt, [[maybe_unused]]StringViewCR msg) noexcept { | ||||
| constexpr void assertFunc( | ||||
| 	StringViewCR file, | ||||
| 	int const line, | ||||
| 	bool const pass, | ||||
| 	[[maybe_unused]]StringViewCR assertTxt, | ||||
| 	[[maybe_unused]]StringViewCR msg) noexcept { | ||||
| 	if (!pass) { | ||||
| 		if (!std::is_constant_evaluated()) { | ||||
| 			assertFailFuncRuntime(file, line, assertTxt, msg); | ||||
| @@ -45,7 +65,12 @@ constexpr void assertFunc(StringViewCR file, int line, bool pass, [[maybe_unused | ||||
| 	} | ||||
| } | ||||
|  | ||||
| constexpr void assertFunc(StringViewCR file, int line, const Error &err, StringViewCR, StringViewCR assertMsg) noexcept { | ||||
| constexpr void assertFunc( | ||||
| 	StringViewCR file, | ||||
| 	int const line, | ||||
| 	Error const&err, | ||||
| 	StringViewCR, | ||||
| 	StringViewCR assertMsg) noexcept { | ||||
| 	if (err) { | ||||
| 		if (!std::is_constant_evaluated()) { | ||||
| 			assertFailFuncRuntime(file, line, err, {}, assertMsg); | ||||
| @@ -55,7 +80,11 @@ constexpr void assertFunc(StringViewCR file, int line, const Error &err, StringV | ||||
| 	} | ||||
| } | ||||
|  | ||||
| constexpr void expect(StringViewCR file, int line, const auto &actual, const auto &expected) noexcept { | ||||
| constexpr void expect( | ||||
| 	StringViewCR file, | ||||
| 	int const line, | ||||
| 	auto const&actual, | ||||
| 	auto const&expected) noexcept { | ||||
| 	if (actual != expected) { | ||||
| 		 if (!std::is_constant_evaluated()) { | ||||
| #if defined(OX_USE_STDLIB) | ||||
|   | ||||
							
								
								
									
										6
									
								
								deps/ox/src/ox/std/defines.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/ox/src/ox/std/defines.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -41,6 +41,12 @@ constexpr auto Debug = true; | ||||
| constexpr auto Debug = false; | ||||
| #endif | ||||
|  | ||||
| #if defined(OX_CHECK_BOUNDS) | ||||
| constexpr auto CheckBounds = true; | ||||
| #else | ||||
| constexpr auto CheckBounds = Debug; | ||||
| #endif | ||||
|  | ||||
| #if defined(NDEBUG) | ||||
| constexpr auto NDebug = true; | ||||
| #else | ||||
|   | ||||
							
								
								
									
										60
									
								
								deps/ox/src/ox/std/error.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								deps/ox/src/ox/std/error.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -36,28 +36,16 @@ using ErrorCode = uint16_t; | ||||
|  | ||||
|  | ||||
| struct [[nodiscard]] Error { | ||||
| 	std::source_location src; | ||||
| 	ox::CString msg = nullptr; | ||||
| 	ox::CString file = nullptr; | ||||
| 	uint16_t line = 0; | ||||
| 	ErrorCode errCode = 0; | ||||
|  | ||||
| 	constexpr Error() noexcept = default; | ||||
|  | ||||
| 	explicit constexpr Error( | ||||
| 		ox::CString file, | ||||
| 		uint32_t const line, | ||||
| 		ErrorCode const errCode, | ||||
| 		ox::CString msg = nullptr) noexcept: | ||||
| 		msg{msg}, | ||||
| 		file{file}, | ||||
| 		line{static_cast<uint16_t>(line)}, | ||||
| 		errCode{errCode} {} | ||||
|  | ||||
| 	explicit constexpr Error( | ||||
| 		ErrorCode const errCode, | ||||
| 		std::source_location const&src = std::source_location::current()) noexcept: | ||||
| 		file{src.file_name()}, | ||||
| 		line{static_cast<uint16_t>(src.line())}, | ||||
| 		src{src}, | ||||
| 		errCode{errCode} | ||||
| 	{} | ||||
|  | ||||
| @@ -65,9 +53,8 @@ struct [[nodiscard]] Error { | ||||
| 		ErrorCode const errCode, | ||||
| 		ox::CString msg, | ||||
| 		std::source_location const&src = std::source_location::current()) noexcept: | ||||
| 		src{src}, | ||||
| 		msg{msg}, | ||||
| 		file{src.file_name()}, | ||||
| 		line{static_cast<uint16_t>(src.line())}, | ||||
| 		errCode{errCode} | ||||
| 	{} | ||||
|  | ||||
| @@ -89,42 +76,31 @@ constexpr auto toStr(Error const&err) noexcept { | ||||
| } | ||||
|  | ||||
| struct Exception: public std::exception { | ||||
| 	std::source_location src; | ||||
| 	ox::CString msg = nullptr; | ||||
| 	ox::CString file = nullptr; | ||||
| 	uint16_t line = 0; | ||||
| 	ErrorCode errCode = 0; | ||||
|  | ||||
| 	explicit inline Exception(ox::CString file, uint32_t line, ErrorCode errCode, char const*msg = "") noexcept { | ||||
| 		this->file = file; | ||||
| 		this->line = static_cast<uint16_t>(line); | ||||
| 		this->msg = msg; | ||||
| 		this->errCode = errCode; | ||||
| 	} | ||||
|  | ||||
| 	explicit inline Exception( | ||||
| 	explicit Exception( | ||||
| 		ErrorCode const errCode, | ||||
| 		std::source_location const&src = std::source_location::current()) noexcept: | ||||
| 		file{src.file_name()}, | ||||
| 		line{static_cast<uint16_t>(src.line())}, | ||||
| 		src{src}, | ||||
| 		errCode{errCode} {} | ||||
|  | ||||
| 	explicit inline Exception( | ||||
| 	explicit Exception( | ||||
| 		ErrorCode const errCode, | ||||
| 		ox::CString msg, | ||||
| 		std::source_location const&src = std::source_location::current()) noexcept: | ||||
| 		src{src}, | ||||
| 		msg{msg}, | ||||
| 		file{src.file_name()}, | ||||
| 		line{static_cast<uint16_t>(src.line())}, | ||||
| 		errCode{errCode} {} | ||||
|  | ||||
| 	explicit inline Exception(Error const&err) noexcept: | ||||
| 	explicit Exception(Error const&err) noexcept: | ||||
| 		src{err.src}, | ||||
| 		msg{err.msg ? err.msg : ""}, | ||||
| 		file{err.file}, | ||||
| 		line{err.line}, | ||||
| 		errCode{err.errCode} {} | ||||
|  | ||||
| 	constexpr Error toError() const noexcept { | ||||
| 		return Error(file, line, errCode, msg); | ||||
| 		return Error(errCode, msg, src); | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] | ||||
| @@ -133,6 +109,7 @@ struct Exception: public std::exception { | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| [[noreturn]] | ||||
| void panic(char const*file, int line, char const*panicMsg, Error const&err) noexcept; | ||||
|  | ||||
| template<typename T> | ||||
| @@ -353,4 +330,17 @@ constexpr void primitiveAssert(char const*file, int line, bool pass, char const* | ||||
| 	} | ||||
| } | ||||
|  | ||||
| constexpr void boundsCheck( | ||||
| 	char const*file, | ||||
| 	int const line, | ||||
| 	size_t const i, | ||||
| 	size_t const sz, | ||||
| 	char const*msg) noexcept { | ||||
| 	if constexpr(defines::CheckBounds) { | ||||
| 		if (i >= sz) [[unlikely]] { | ||||
| 			panic(file, line, msg, ox::Error{1}); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										6
									
								
								deps/ox/src/ox/std/iterator.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								deps/ox/src/ox/std/iterator.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -133,17 +133,17 @@ struct SpanIterator { | ||||
| 		} | ||||
|  | ||||
| 		constexpr PtrType operator->() const noexcept { | ||||
| 			ox::primitiveAssert(__FILE__, __LINE__, m_offset < m_max, "SpanIterator access overflow"); | ||||
| 			boundsCheck(__FILE__, __LINE__, m_offset, m_max, "SpanIterator access overflow"); | ||||
| 			return &m_t[m_offset]; | ||||
| 		} | ||||
|  | ||||
| 		constexpr RefType operator*() const noexcept { | ||||
| 			ox::primitiveAssert(__FILE__, __LINE__, m_offset < m_max, "SpanIterator access overflow"); | ||||
| 			boundsCheck(__FILE__, __LINE__, m_offset, m_max, "SpanIterator access overflow"); | ||||
| 			return m_t[m_offset]; | ||||
| 		} | ||||
|  | ||||
| 		constexpr RefType operator[](std::size_t s) const noexcept { | ||||
| 			ox::primitiveAssert(__FILE__, __LINE__, s < m_max, "SpanIterator access overflow"); | ||||
| 			boundsCheck(__FILE__, __LINE__, s, m_max, "SpanIterator access overflow"); | ||||
| 			return m_t[s]; | ||||
| 		} | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								deps/ox/src/ox/std/reader.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								deps/ox/src/ox/std/reader.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -31,7 +31,6 @@ concept Reader_c = requires(T v) { | ||||
| class Reader_v { | ||||
| 	public: | ||||
| 		virtual constexpr ~Reader_v() noexcept = default; | ||||
| 		[[nodiscard]] | ||||
| 		virtual constexpr ox::Result<char> peek() const noexcept = 0; | ||||
| 		virtual constexpr ox::Result<std::size_t> read(char*, std::size_t) noexcept = 0; | ||||
| 		virtual constexpr ox::Result<std::size_t> tellg() noexcept = 0; | ||||
|   | ||||
							
								
								
									
										9
									
								
								deps/ox/src/ox/std/realstd.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								deps/ox/src/ox/std/realstd.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -13,3 +13,12 @@ | ||||
| #else | ||||
| #define	assert(e) while (!(e)); | ||||
| #endif | ||||
|  | ||||
| #if __has_include(<cstdlib>) | ||||
| #include <cstdlib> | ||||
| #else | ||||
| extern "C" { | ||||
| [[noreturn]] | ||||
| void abort(); | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										59
									
								
								deps/ox/src/ox/std/smallmap.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								deps/ox/src/ox/std/smallmap.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -62,6 +62,9 @@ class SmallMap { | ||||
| 		[[nodiscard]] | ||||
| 		constexpr Vector<K> keys() const noexcept; | ||||
|  | ||||
| 		[[nodiscard]] | ||||
| 		constexpr Vector<T> values() const noexcept; | ||||
|  | ||||
| 		[[nodiscard]] | ||||
| 		constexpr K const&key(size_t i) const noexcept; | ||||
|  | ||||
| @@ -82,14 +85,22 @@ class SmallMap { | ||||
| 			return m_pairs; | ||||
| 		} | ||||
|  | ||||
| 		[[nodiscard]] | ||||
| 		constexpr ox::Span<Pair> pairs() noexcept { | ||||
| 			return m_pairs; | ||||
| 		} | ||||
|  | ||||
| 		constexpr void clear(); | ||||
|  | ||||
| 	private: | ||||
| 		template<typename KK> | ||||
| 		constexpr Pair const&access(PairVector const&pairs, KK const&key, bool &isNew) const; | ||||
| 		constexpr Pair const*access(PairVector const&pairs, KK const&key, bool &isNew) const; | ||||
|  | ||||
| 		template<typename KK> | ||||
| 		constexpr Pair &access(PairVector &pairs, KK const&key, bool &isNew); | ||||
| 		constexpr Pair *access(PairVector &pairs, KK const&key, bool &isNew); | ||||
|  | ||||
| 		template<typename KK> | ||||
| 		constexpr Pair *accessNoCreate(PairVector &pairs, KK const&key); | ||||
|  | ||||
| }; | ||||
|  | ||||
| @@ -129,7 +140,7 @@ constexpr SmallMap<K, T, SmallSz> &SmallMap<K, T, SmallSz>::operator=(SmallMap<K | ||||
| template<typename K, typename T, size_t SmallSz> | ||||
| constexpr T &SmallMap<K, T, SmallSz>::operator[](MaybeView_t<K> const&k) { | ||||
| 	bool isNew{}; | ||||
| 	auto p = &access(m_pairs, k, isNew); | ||||
| 	auto p = access(m_pairs, k, isNew); | ||||
| 	if (isNew) { | ||||
| 		p->key = k; | ||||
| 	} | ||||
| @@ -138,7 +149,7 @@ constexpr T &SmallMap<K, T, SmallSz>::operator[](MaybeView_t<K> const&k) { | ||||
|  | ||||
| template<typename K, typename T, size_t SmallSz> | ||||
| constexpr Result<T*> SmallMap<K, T, SmallSz>::at(MaybeView_t<K> const&k) noexcept { | ||||
| 	auto p = access(m_pairs, k); | ||||
| 	auto const p = accessNoCreate(m_pairs, k); | ||||
| 	if (!p) { | ||||
| 		return {nullptr, ox::Error(1, "value not found for given key")}; | ||||
| 	} | ||||
| @@ -147,7 +158,8 @@ constexpr Result<T*> SmallMap<K, T, SmallSz>::at(MaybeView_t<K> const&k) noexcep | ||||
|  | ||||
| template<typename K, typename T, size_t SmallSz> | ||||
| constexpr Result<const T*> SmallMap<K, T, SmallSz>::at(MaybeView_t<K> const&k) const noexcept { | ||||
| 	auto p = access(m_pairs, k); | ||||
| 	bool isNew{}; | ||||
| 	auto p = access(m_pairs, k, isNew); | ||||
| 	if (!p) { | ||||
| 		return {nullptr, ox::Error(1, "value not found for given key")}; | ||||
| 	} | ||||
| @@ -168,7 +180,8 @@ constexpr void SmallMap<K, T, SmallSz>::erase(MaybeView_t<K> const&k) { | ||||
|  | ||||
| template<typename K, typename T, size_t SmallSz> | ||||
| constexpr bool SmallMap<K, T, SmallSz>::contains(MaybeView_t<K> const&k) const noexcept { | ||||
| 	return access(m_pairs, k) != nullptr; | ||||
| 	bool isNew{}; | ||||
| 	return access(m_pairs, k, isNew) != nullptr; | ||||
| } | ||||
|  | ||||
| template<typename K, typename T, size_t SmallSz> | ||||
| @@ -186,6 +199,16 @@ constexpr Vector<K> SmallMap<K, T, SmallSz>::keys() const noexcept { | ||||
| 	return keys; | ||||
| } | ||||
|  | ||||
| template<typename K, typename T, size_t SmallSz> | ||||
| constexpr Vector<T> SmallMap<K, T, SmallSz>::values() const noexcept { | ||||
| 	ox::Vector<T> keys; | ||||
| 	keys.reserve(m_pairs.size()); | ||||
| 	for (auto const&p : m_pairs) { | ||||
| 		keys.emplace_back(p.key); | ||||
| 	} | ||||
| 	return keys; | ||||
| } | ||||
|  | ||||
| template<typename K, typename T, size_t SmallSz> | ||||
| constexpr K const&SmallMap<K, T, SmallSz>::key(size_t i) const noexcept { | ||||
| 	return m_pairs[i].key; | ||||
| @@ -218,30 +241,42 @@ constexpr void SmallMap<K, T, SmallSz>::clear() { | ||||
|  | ||||
| template<typename K, typename T, size_t SmallSz> | ||||
| template<typename KK> | ||||
| constexpr typename SmallMap<K, T, SmallSz>::Pair const&SmallMap<K, T, SmallSz>::access( | ||||
| constexpr typename SmallMap<K, T, SmallSz>::Pair const*SmallMap<K, T, SmallSz>::access( | ||||
| 		PairVector const&pairs, KK const&k, bool &isNew) const { | ||||
| 	for (auto const&p : pairs) { | ||||
| 		if (p.key == k) { | ||||
| 			isNew = false; | ||||
| 			return p; | ||||
| 			return &p; | ||||
| 		} | ||||
| 	} | ||||
| 	isNew = true; | ||||
| 	return pairs.emplace_back(); | ||||
| 	return nullptr; | ||||
| } | ||||
|  | ||||
| template<typename K, typename T, size_t SmallSz> | ||||
| template<typename KK> | ||||
| constexpr typename SmallMap<K, T, SmallSz>::Pair &SmallMap<K, T, SmallSz>::access( | ||||
| constexpr typename SmallMap<K, T, SmallSz>::Pair *SmallMap<K, T, SmallSz>::access( | ||||
| 		PairVector &pairs, KK const&k, bool &isNew) { | ||||
| 	for (auto &p : pairs) { | ||||
| 		if (p.key == k) { | ||||
| 			isNew = false; | ||||
| 			return p; | ||||
| 			return &p; | ||||
| 		} | ||||
| 	} | ||||
| 	isNew = true; | ||||
| 	return pairs.emplace_back(); | ||||
| 	return &pairs.emplace_back(); | ||||
| } | ||||
|  | ||||
| template<typename K, typename T, size_t SmallSz> | ||||
| template<typename KK> | ||||
| constexpr typename SmallMap<K, T, SmallSz>::Pair *SmallMap<K, T, SmallSz>::accessNoCreate( | ||||
| 		PairVector &pairs, KK const&k) { | ||||
| 	for (auto &p : pairs) { | ||||
| 		if (p.key == k) { | ||||
| 			return &p; | ||||
| 		} | ||||
| 	} | ||||
| 	return nullptr; | ||||
| } | ||||
|  | ||||
| template<typename T, typename K, typename V, size_t SmallSz> | ||||
|   | ||||
							
								
								
									
										28
									
								
								deps/ox/src/ox/std/span.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								deps/ox/src/ox/std/span.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -14,7 +14,7 @@ | ||||
| #include "iterator.hpp" | ||||
| #include "vector.hpp" | ||||
|  | ||||
| OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage) | ||||
| OX_ALLOW_UNSAFE_BUFFERS_BEGIN | ||||
|  | ||||
| namespace ox { | ||||
|  | ||||
| @@ -129,22 +129,22 @@ class Span { | ||||
| 		} | ||||
|  | ||||
| 		constexpr T &operator[](std::size_t i) noexcept { | ||||
| 			ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow"); | ||||
| 			boundsCheck(__FILE__, __LINE__, i, size(), "Span access overflow"); | ||||
| 			return m_items[i]; | ||||
| 		} | ||||
|  | ||||
| 		constexpr const T &operator[](std::size_t i) const noexcept { | ||||
| 			ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow"); | ||||
| 		constexpr T const&operator[](std::size_t i) const noexcept { | ||||
| 			boundsCheck(__FILE__, __LINE__, i, size(), "Span access overflow"); | ||||
| 			return m_items[i]; | ||||
| 		} | ||||
|  | ||||
| 		constexpr Span operator+(size_t i) const noexcept { | ||||
| 			ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow"); | ||||
| 			boundsCheck(__FILE__, __LINE__, i, size(), "Span access overflow"); | ||||
| 			return {m_items + i, m_size - i}; | ||||
| 		} | ||||
|  | ||||
| 		constexpr Span operator+=(size_t i) noexcept { | ||||
| 			ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow"); | ||||
| 			boundsCheck(__FILE__, __LINE__, i, size(), "Span access overflow"); | ||||
| 			m_items += i; | ||||
| 			m_size -= i; | ||||
| 			return *this; | ||||
| @@ -168,8 +168,20 @@ class Span { | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| using SpanView = Span<const T>; | ||||
| using SpanView = Span<T const>; | ||||
|  | ||||
| template<typename T> | ||||
| constexpr void spancpy(ox::Span<T> const dst, ox::SpanView<T> const src) noexcept { | ||||
| 	auto const sz = ox::min(dst.size(), src.size()); | ||||
| 	if (std::is_constant_evaluated() || std::is_trivially_copyable_v<T>) { | ||||
| 		for (size_t i{}; i < sz; ++i) { | ||||
| 			dst.data()[i] = src.data()[i]; | ||||
| 		} | ||||
| 	} else { | ||||
| 		memcpy(dst.data(), src.data(), sz * sizeof(T)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| } | ||||
|  | ||||
| OX_CLANG_NOWARN_END | ||||
| OX_ALLOW_UNSAFE_BUFFERS_END | ||||
|   | ||||
							
								
								
									
										4
									
								
								deps/ox/src/ox/std/string.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/ox/src/ox/std/string.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -171,7 +171,7 @@ class BasicString { | ||||
|  | ||||
| 		constexpr bool operator>=(BasicString const&other) const noexcept; | ||||
|  | ||||
| 		constexpr char operator[](std::size_t i) const noexcept; | ||||
| 		constexpr char const&operator[](std::size_t i) const noexcept; | ||||
|  | ||||
| 		constexpr char &operator[](std::size_t i) noexcept; | ||||
|  | ||||
| @@ -490,7 +490,7 @@ constexpr bool BasicString<SmallStringSize_v>::operator>=(BasicString const&othe | ||||
| } | ||||
|  | ||||
| template<std::size_t SmallStringSize_v> | ||||
| constexpr char BasicString<SmallStringSize_v>::operator[](std::size_t i) const noexcept { | ||||
| constexpr char const&BasicString<SmallStringSize_v>::operator[](std::size_t i) const noexcept { | ||||
| 	return m_buff[i]; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								deps/ox/src/ox/std/test/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/ox/src/ox/std/test/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -17,6 +17,8 @@ add_test("[ox/std] String" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "String") | ||||
| add_test("[ox/std] SmallMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "SmallMap") | ||||
| add_test("[ox/std] SmallMap2" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "SmallMap2") | ||||
| add_test("[ox/std] Vector" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Vector") | ||||
| add_test("[ox/std] Vector::shrink_to_fit" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Vector::shrink_to_fit") | ||||
| add_test("[ox/std] findIdx" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "findIdx") | ||||
| add_test("[ox/std] HashMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "HashMap") | ||||
| add_test("[ox/std] HeapMgr" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest malloc) | ||||
| add_test("[ox/std] Serialize-Int" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Serialize-Int") | ||||
|   | ||||
							
								
								
									
										57
									
								
								deps/ox/src/ox/std/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								deps/ox/src/ox/std/test/tests.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -237,6 +237,50 @@ OX_CLANG_NOWARN_END | ||||
| 			return ox::Error(0); | ||||
| 		} | ||||
| 	}, | ||||
| 	{ | ||||
| 		"Vector::shrink_to_fit", | ||||
| 		[] { | ||||
| 			{ | ||||
| 				ox::Vector<ox::IString<8>> v; | ||||
| 				v.reserve(50); | ||||
| 				v.emplace_back("asdf"); | ||||
| 				v.emplace_back("aoeu"); | ||||
| 				auto const origData = v.data(); | ||||
| 				v.shrink_to_fit(); | ||||
| 				oxExpect(v[0], "asdf"); | ||||
| 				oxExpect(v[1], "aoeu"); | ||||
| 				oxExpect(v.capacity(), 2u); | ||||
| 				oxAssert(origData != v.data(), "shrink_to_fit did not create a new allocation"); | ||||
| 			} | ||||
| 			{ | ||||
| 				ox::Vector<ox::IString<8>> v; | ||||
| 				v.reserve(2); | ||||
| 				v.emplace_back("asdf"); | ||||
| 				v.emplace_back("aoeu"); | ||||
| 				auto const origData = v.data(); | ||||
| 				v.shrink_to_fit(); | ||||
| 				oxExpect(v[0], "asdf"); | ||||
| 				oxExpect(v[1], "aoeu"); | ||||
| 				oxExpect(v.capacity(), 2u); | ||||
| 				oxAssert(origData == v.data(), "shrink_to_fit inappropriately created a new allocation"); | ||||
| 			} | ||||
| 			return ox::Error{}; | ||||
| 		} | ||||
| 	}, | ||||
| 	{ | ||||
| 		"findIdx", | ||||
| 		[] { | ||||
| 			ox::Vector<ox::IString<8>> const v {"zero", "one", "two", "three", "four"}; | ||||
| 			oxExpect(ox::findIdx(v.begin(), v.end(), "zero").or_value(5), 0u); | ||||
| 			oxExpect(ox::findIdx(v.begin(), v.end(), "one").or_value(5), 1u); | ||||
| 			oxExpect(ox::findIdx(v.begin(), v.end(), "two").or_value(5), 2u); | ||||
| 			oxExpect(ox::findIdx(v.begin(), v.end(), "three").or_value(5), 3u); | ||||
| 			oxExpect(ox::findIdx(v.begin(), v.end(), "four").or_value(5), 4u); | ||||
| 			oxExpect(ox::findIdx(v.begin(), v.end(), "five").or_value(5), 5u); | ||||
| 			oxExpect(ox::findIdx(v.begin(), v.end(), "six").or_value(6), 6u); | ||||
| 			return ox::Error{}; | ||||
| 		} | ||||
| 	}, | ||||
| 	{ | ||||
| 		"SmallMap", | ||||
| 		[] { | ||||
| @@ -246,7 +290,18 @@ OX_CLANG_NOWARN_END | ||||
| 			oxExpect(map.size(), 1u); | ||||
| 			oxExpect(map["aoeu"], ""); | ||||
| 			oxExpect(map.size(), 2u); | ||||
| 			return ox::Error(0); | ||||
| 			ox::SmallMap<ox::String, ox::String> cmap; | ||||
| 			cmap["asdf"] = "aoeu"; | ||||
| 			auto constexpr constTest = [](ox::SmallMap<ox::String, ox::String> const&map) { | ||||
| 				OX_REQUIRE(asdf, map.at("asdf")); | ||||
| 				oxExpect(*asdf, "aoeu"); | ||||
| 				oxExpect(map.size(), 1u); | ||||
| 				auto const aoeu = map.at("aoeu"); | ||||
| 				oxExpect(aoeu.ok(), false); | ||||
| 				oxExpect(map.size(), 1u); | ||||
| 				return ox::Error{}; | ||||
| 			}; | ||||
| 			return constTest(cmap); | ||||
| 		} | ||||
| 	}, | ||||
| 	{ | ||||
|   | ||||
							
								
								
									
										8
									
								
								deps/ox/src/ox/std/trace.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								deps/ox/src/ox/std/trace.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -269,8 +269,8 @@ using TraceStream = NullStream; | ||||
| inline void logError(const char *file, int line, const char *fmt, const Error &err) noexcept { | ||||
| 	if (err) { | ||||
| 		TraceStream trc(file, line, "ox::error"); | ||||
| 		if (err.file != nullptr) { | ||||
| 			trc << "Error: (" << err.file << ":" << err.line << "):"; | ||||
| 		if (err.src.file_name() != nullptr) { | ||||
| 			trc << "Error: (" << err.src.file_name() << ":" << err.src.line() << "):"; | ||||
| 		} else { | ||||
| 			trc <<  "Error:"; | ||||
| 		} | ||||
| @@ -282,8 +282,8 @@ inline void logError(const char *file, int line, const Error &err) noexcept { | ||||
| 	if (err) { | ||||
| 		TraceStream trc(file, line, "ox::error"); | ||||
| 		trc <<  "Error:" << err; | ||||
| 		if (err.file != nullptr) { | ||||
| 			trc << "(" << err.file << ":" << err.line << ")"; | ||||
| 		if (err.src.file_name() != nullptr) { | ||||
| 			trc << "(" << err.src.file_name() << ":" << err.src.line() << ")"; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										10
									
								
								deps/ox/src/ox/std/typetraits.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								deps/ox/src/ox/std/typetraits.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -19,12 +19,15 @@ | ||||
| namespace std { | ||||
|  | ||||
| template<typename T> | ||||
| constexpr bool is_union_v = __is_union(T); | ||||
| inline constexpr bool is_union_v = __is_union(T); | ||||
|  | ||||
| constexpr bool is_constant_evaluated() noexcept { | ||||
| inline constexpr bool is_constant_evaluated() noexcept { | ||||
| 	return __builtin_is_constant_evaluated(); | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T); | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -156,6 +159,9 @@ static_assert(is_class<int>::value == false); | ||||
| template<typename T> | ||||
| constexpr bool is_class_v = is_class<T>(); | ||||
|  | ||||
| template<typename T> | ||||
| inline constexpr bool is_trivially_copyable_v = std::is_trivially_copyable_v<T>; | ||||
|  | ||||
| template<typename T> | ||||
| constexpr bool is_signed_v = integral_constant<bool, T(-1) < T(0)>::value; | ||||
|  | ||||
|   | ||||
							
								
								
									
										42
									
								
								deps/ox/src/ox/std/utility.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								deps/ox/src/ox/std/utility.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -27,6 +27,48 @@ constexpr void swap(T &a, T &b) noexcept { | ||||
| 	b = std::move(temp); | ||||
| } | ||||
|  | ||||
| template<typename T, typename U> | ||||
| constexpr bool cmp_equal(T const t, U const u) noexcept { | ||||
| 	if constexpr(ox::is_signed_v<T> == ox::is_signed_v<U>) { | ||||
| 		return t == u; | ||||
| 	} else if constexpr(ox::is_signed_v<T>) { | ||||
| 		return ox::Signed<T>{t} == u; | ||||
| 	} else { | ||||
| 		return t == ox::Signed<U>{u}; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| template<typename T, typename U> | ||||
| constexpr bool cmp_less(T const t, U const u) noexcept { | ||||
| 	if constexpr(ox::is_signed_v<T> == ox::is_signed_v<U>) { | ||||
| 		return t < u; | ||||
| 	} else if constexpr(ox::is_signed_v<T>) { | ||||
| 		return ox::Signed<T>{t} < u; | ||||
| 	} else { | ||||
| 		return t < ox::Signed<U>{u}; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| template<typename T, typename U> | ||||
| constexpr bool cmp_not_equal(T const t, U const u) noexcept { | ||||
| 	return !std::cmp_equal(t, u); | ||||
| } | ||||
|  | ||||
| template<typename T, typename U> | ||||
| constexpr bool cmp_greater(T const t, U const u) noexcept { | ||||
| 	return std::cmp_less(u, t); | ||||
| } | ||||
|  | ||||
| template<typename T, typename U> | ||||
| constexpr bool cmp_less_equal(T const t, U const u) noexcept { | ||||
| 	return !std::cmp_less(u, t); | ||||
| } | ||||
|  | ||||
| template<typename T, typename U> | ||||
| constexpr bool cmp_greater_equal(T const t, U const u) noexcept { | ||||
| 	return !std::cmp_less(t, u); | ||||
| } | ||||
|  | ||||
| } | ||||
| #endif | ||||
|  | ||||
|   | ||||
							
								
								
									
										25
									
								
								deps/ox/src/ox/std/vector.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								deps/ox/src/ox/std/vector.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -313,6 +313,8 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> { | ||||
|  | ||||
| 		constexpr void reserve(std::size_t cap) noexcept(useNoexcept); | ||||
|  | ||||
| 		constexpr void shrink_to_fit() noexcept(useNoexcept); | ||||
|  | ||||
| 	private: | ||||
| 		constexpr void reserveInsert( | ||||
| 				std::size_t cap, std::size_t pos, std::size_t offset = 1) noexcept(useNoexcept); | ||||
| @@ -341,6 +343,7 @@ constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::size_t size) noexce | ||||
|  | ||||
| template<typename T, std::size_t SmallVectorSize, typename Allocator> | ||||
| constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::initializer_list<T> list) noexcept { | ||||
| 	reserve(list.size()); | ||||
| 	for (auto &item : list) { | ||||
| 		emplace_back(std::move(item)); | ||||
| 	} | ||||
| @@ -424,13 +427,13 @@ constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allo | ||||
|  | ||||
| template<typename T, std::size_t SmallVectorSize, typename Allocator> | ||||
| constexpr T &Vector<T, SmallVectorSize, Allocator>::operator[](std::size_t i) noexcept { | ||||
| 	ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Vector access overflow"); | ||||
| 	boundsCheck(__FILE__, __LINE__, i, size(), "Vector access overflow"); | ||||
| 	return m_items[i]; | ||||
| } | ||||
|  | ||||
| template<typename T, std::size_t SmallVectorSize, typename Allocator> | ||||
| constexpr const T &Vector<T, SmallVectorSize, Allocator>::operator[](std::size_t i) const noexcept { | ||||
| 	ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Vector access overflow"); | ||||
| 	boundsCheck(__FILE__, __LINE__, i, size(), "Vector access overflow"); | ||||
| 	return m_items[i]; | ||||
| } | ||||
|  | ||||
| @@ -675,6 +678,24 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::reserve(std::size_t cap) n | ||||
| 	} | ||||
| } | ||||
|  | ||||
| template<typename T, std::size_t SmallVectorSize, typename Allocator> | ||||
| constexpr void Vector<T, SmallVectorSize, Allocator>::shrink_to_fit() noexcept(useNoexcept)  { | ||||
| 	if (m_size == m_cap) { | ||||
| 		return; | ||||
| 	} | ||||
| 	const auto oldItems = m_items; | ||||
| 	const auto oldCap = m_cap; | ||||
| 	m_cap = m_size; | ||||
| 	this->allocate(&m_items, m_size); | ||||
| 	if (oldItems) { // move over old items | ||||
| 		for (std::size_t i = 0; i < m_size; ++i) { | ||||
| 			std::construct_at(&m_items[i], std::move(oldItems[i])); | ||||
| 			oldItems[i].~T(); | ||||
| 		} | ||||
| 		this->deallocate(oldItems, oldCap); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| template<typename T, std::size_t SmallVectorSize, typename Allocator> | ||||
| constexpr void Vector<T, SmallVectorSize, Allocator>::reserveInsert( | ||||
| 		std::size_t cap, | ||||
|   | ||||
							
								
								
									
										21
									
								
								deps/teagba/src/cstartup.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								deps/teagba/src/cstartup.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -4,17 +4,20 @@ | ||||
|  | ||||
| #include <ox/std/heapmgr.hpp> | ||||
|  | ||||
| #include <teagba/bios.hpp> | ||||
| #include <teagba/registers.hpp> | ||||
|  | ||||
| namespace mgba { | ||||
| void initConsole(); | ||||
| } | ||||
|  | ||||
| #define MEM_EWRAM_BEGIN reinterpret_cast<char*>(0x02000000) | ||||
| #define MEM_EWRAM_END   reinterpret_cast<char*>(0x0203FFFF) | ||||
| #define MEM_HEAP_BEGIN reinterpret_cast<char*>(0x02000000) | ||||
| #define MEM_HEAP_END   reinterpret_cast<char*>(0x0203FFFF) | ||||
|  | ||||
| #define HEAP_BEGIN reinterpret_cast<char*>(MEM_EWRAM_BEGIN) | ||||
| #define HEAP_BEGIN reinterpret_cast<char*>(MEM_HEAP_BEGIN) | ||||
| // set size to half of EWRAM | ||||
| #define HEAP_SIZE ((MEM_EWRAM_END - MEM_EWRAM_BEGIN) / 2) | ||||
| #define HEAP_END  reinterpret_cast<char*>(MEM_EWRAM_BEGIN + HEAP_SIZE) | ||||
| #define HEAP_SIZE ((MEM_HEAP_END - MEM_HEAP_BEGIN) / 2) | ||||
| #define HEAP_END  reinterpret_cast<char*>(MEM_HEAP_BEGIN + HEAP_SIZE) | ||||
|  | ||||
| extern void (*__preinit_array_start[]) (void); | ||||
| extern void (*__preinit_array_end[]) (void); | ||||
| @@ -25,6 +28,14 @@ int main(int argc, const char **argv); | ||||
|  | ||||
| extern "C" { | ||||
|  | ||||
| void abort() { | ||||
| 	REG_IE = 0; | ||||
| 	teagba::intrwait(0, 0); | ||||
| 	while (true); | ||||
| } | ||||
|  | ||||
| void *__gxx_personality_v0{}; | ||||
|  | ||||
| void __libc_init_array() { | ||||
| 	auto preInits = __preinit_array_end - __preinit_array_start; | ||||
| 	for (decltype(preInits) i = 0; i < preInits; i++) { | ||||
|   | ||||
| @@ -162,11 +162,9 @@ The Ox way of doing things is the Olympic way of doing things. | ||||
|  | ||||
| ### Error Handling | ||||
|  | ||||
| The GBA build has exceptions disabled. | ||||
| Instead of throwing exceptions, all engine code should return | ||||
| [ox::Errors](deps/ox/ox-docs.md#error-handling) for error reporting. | ||||
| For the sake of consistency, try to stick to ```ox::Error``` in non-engine code | ||||
| as well, but non-engine code is free to use exceptions when they make sense. | ||||
| Instead of throwing exceptions, generally try to use | ||||
| [ox::Errors](deps/ox/ox-docs.md#error-handling) for error reporting, | ||||
| but exceptions may be used where they make sense. | ||||
|  | ||||
| Exceptions should generally just use ```OxException```, which is bascially an | ||||
| exception form of ```ox::Error```. | ||||
|   | ||||
							
								
								
									
										21
									
								
								release-notes.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								release-notes.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| # d2025.02 | ||||
|  | ||||
| * Rename core namespace to gfx. | ||||
| * Add PaletteV5 to accommodate namespace change. | ||||
| * Add TileSheetV5. TileSheetV5 retains the bpp field for the sake of | ||||
|   CompactTileSheet, but always store it pixel as 8 bpp for itself. | ||||
| * Add ability to move subsheets in the subsheet tree. | ||||
| * Add Flip X and Flip Y functionality to TileSheet Editor. | ||||
| * Add rotate functionality to TileSheet Editor. | ||||
| * Add draw line tool to TileSheet editor | ||||
| * Replace file picker combo boxes with a browse button and file picker, and | ||||
|   support for dragging files from the project explorer. | ||||
| * Add ability to create directories. | ||||
| * Add ability to add files to specific directories. | ||||
| * Add ability to delete files from the project explorer. | ||||
| * Ctrl-<num key> keyboard shortcuts for jumping between tabs. | ||||
| * Fix Palette Editor to ignore keyboard input when popups are open. | ||||
| * Palette Editor move color mechanism now uses drag and drop. | ||||
| * Add ability to reorder Palette pages. | ||||
| * Add warning for closing a tab with unsaved changes. | ||||
| * Add ability to close a tab with Ctrl/Cmd-W | ||||
| @@ -1 +1,28 @@ | ||||
| K1;0f75977f-1c52-45f8-9793-52ea2dc200a0;M2;net.drinkingtea.nostalgia.core.Palette;1;<03><><07><> | ||||
| K1;0f75977f-1c52-45f8-9793-52ea2dc200a0;O1;net.drinkingtea.nostalgia.gfx.Palette;5;{ | ||||
| 	"colorNames" :  | ||||
| 	[ | ||||
| 		"Color 1", | ||||
| 		"Color 2" | ||||
| 	], | ||||
| 	"pages" :  | ||||
| 	[ | ||||
| 		{ | ||||
| 			"colors" :  | ||||
| 			[ | ||||
| 				{ | ||||
| 					"a" : 1, | ||||
| 					"b" : 31, | ||||
| 					"g" : 31, | ||||
| 					"r" : 31 | ||||
| 				}, | ||||
| 				{ | ||||
| 					"a" : 1, | ||||
| 					"b" : 22, | ||||
| 					"g" : 22, | ||||
| 					"r" : 22 | ||||
| 				} | ||||
| 			], | ||||
| 			"name" : "Page 1" | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
| @@ -1 +1,36 @@ | ||||
| K1;c79f21e2-f74f-4ad9-90ed-32b0ef7da6ed;M2;net.drinkingtea.nostalgia.core.Palette;1;P<>{<03><>C<> | ||||
| K1;c79f21e2-f74f-4ad9-90ed-32b0ef7da6ed;O1;net.drinkingtea.nostalgia.gfx.Palette;5;{ | ||||
| 	"colorNames" :  | ||||
| 	[ | ||||
| 		"Color 1", | ||||
| 		"Color 2", | ||||
| 		"Color 3", | ||||
| 		"Color 4" | ||||
| 	], | ||||
| 	"pages" :  | ||||
| 	[ | ||||
| 		{ | ||||
| 			"colors" :  | ||||
| 			[ | ||||
| 				{ | ||||
| 					"b" : 5 | ||||
| 				}, | ||||
| 				{ | ||||
| 					"b" : 22, | ||||
| 					"g" : 22, | ||||
| 					"r" : 22 | ||||
| 				}, | ||||
| 				{ | ||||
| 					"b" : 27, | ||||
| 					"g" : 27, | ||||
| 					"r" : 27 | ||||
| 				}, | ||||
| 				{ | ||||
| 					"b" : 20, | ||||
| 					"g" : 8, | ||||
| 					"r" : 8 | ||||
| 				} | ||||
| 			], | ||||
| 			"name" : "Page 1" | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										352
									
								
								sample_project/TileSheets/Chester.nts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										352
									
								
								sample_project/TileSheets/Chester.nts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,352 @@ | ||||
| K1;5667c759-7ba1-470a-8860-72f0720dc58c;O1;net.drinkingtea.nostalgia.gfx.TileSheet;5;{ | ||||
| 	"bpp" : 4, | ||||
| 	"defaultPalette" : "uuid://14fc3dd8-42ff-4bf9-81f1-a010cc5ac251", | ||||
| 	"idIt" : 7, | ||||
| 	"subsheet" :  | ||||
| 	{ | ||||
| 		"columns" : -1, | ||||
| 		"name" : "Root", | ||||
| 		"rows" : -1, | ||||
| 		"subsheets" :  | ||||
| 		[ | ||||
| 			{ | ||||
| 				"columns" : 1, | ||||
| 				"id" : 5, | ||||
| 				"name" : "Blank", | ||||
| 				"pixels" :  | ||||
| 				[ | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0, | ||||
| 					0 | ||||
| 				], | ||||
| 				"rows" : 1 | ||||
| 			}, | ||||
| 			{ | ||||
| 				"columns" : 2, | ||||
| 				"id" : 6, | ||||
| 				"name" : "Dirt", | ||||
| 				"pixels" :  | ||||
| 				[ | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					2, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					2, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					2, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					2, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					2, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					2, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					2, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					2, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					2, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					2, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1, | ||||
| 					1 | ||||
| 				], | ||||
| 				"rows" : 2 | ||||
| 			} | ||||
| 		] | ||||
| 	} | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										591
									
								
								sample_project/TileSheets/Logo.nts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										591
									
								
								sample_project/TileSheets/Logo.nts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,591 @@ | ||||
| K1;896a7d25-9dc2-46a0-b4da-c6923b6da01b;O1;net.drinkingtea.nostalgia.gfx.TileSheet;5;{ | ||||
| 	"bpp" : 4, | ||||
| 	"defaultPalette" : "uuid://c79f21e2-f74f-4ad9-90ed-32b0ef7da6ed", | ||||
| 	"idIt" : 2, | ||||
| 	"subsheet" :  | ||||
| 	{ | ||||
| 		"columns" : 3, | ||||
| 		"id" : 1, | ||||
| 		"name" : "Root", | ||||
| 		"pixels" :  | ||||
| 		[ | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0 | ||||
| 		], | ||||
| 		"rows" : 3 | ||||
| 	} | ||||
| } | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										591
									
								
								sample_project/TileSheets/NS_Logo.nts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										591
									
								
								sample_project/TileSheets/NS_Logo.nts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,591 @@ | ||||
| K1;f551fb8b-0e9f-45fc-8106-b98b7fd18ff5;O1;net.drinkingtea.nostalgia.gfx.TileSheet;5;{ | ||||
| 	"bpp" : 4, | ||||
| 	"defaultPalette" : "uuid://c79f21e2-f74f-4ad9-90ed-32b0ef7da6ed", | ||||
| 	"idIt" : 2, | ||||
| 	"subsheet" :  | ||||
| 	{ | ||||
| 		"columns" : 3, | ||||
| 		"id" : 1, | ||||
| 		"name" : "Root", | ||||
| 		"pixels" :  | ||||
| 		[ | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			3, | ||||
| 			3, | ||||
| 			3, | ||||
| 			3, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			3, | ||||
| 			3, | ||||
| 			3, | ||||
| 			2, | ||||
| 			3, | ||||
| 			3, | ||||
| 			0, | ||||
| 			0, | ||||
| 			3, | ||||
| 			3, | ||||
| 			2, | ||||
| 			3, | ||||
| 			3, | ||||
| 			3, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			3, | ||||
| 			3, | ||||
| 			3, | ||||
| 			3, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			1, | ||||
| 			1, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0 | ||||
| 		], | ||||
| 		"rows" : 3 | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								sample_project/TileSheets/SC9K_Logo.nts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								sample_project/TileSheets/SC9K_Logo.nts
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,6 +1,7 @@ | ||||
| # module dir list | ||||
|  | ||||
| add_subdirectory(core) | ||||
| add_subdirectory(gfx) | ||||
| add_subdirectory(sound) | ||||
| add_subdirectory(scene) | ||||
|  | ||||
| # module libraries | ||||
| @@ -13,7 +14,7 @@ add_library( | ||||
| target_link_libraries( | ||||
| 	NostalgiaKeelModules PUBLIC | ||||
| 		Keel | ||||
| 		NostalgiaCore-Keel | ||||
| 		NostalgiaGfx-Keel | ||||
| 		NostalgiaScene-Keel | ||||
| ) | ||||
| install( | ||||
| @@ -32,7 +33,8 @@ if(NOSTALGIA_BUILD_STUDIO) | ||||
| 	target_link_libraries( | ||||
| 		NostalgiaStudioModules PUBLIC | ||||
| 			StudioAppLib | ||||
| 			NostalgiaCore-Studio-ImGui | ||||
| 			NostalgiaGfx-Studio-ImGui | ||||
| 			NostalgiaSound-Studio-ImGui | ||||
| 			NostalgiaScene-Studio | ||||
| 	) | ||||
| 	install( | ||||
|   | ||||
| @@ -1,33 +0,0 @@ | ||||
| /* | ||||
|  * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ox/fs/fs.hpp> | ||||
| #include <ox/model/desctypes.hpp> | ||||
| #include <ox/std/buffer.hpp> | ||||
| #include <ox/std/size.hpp> | ||||
|  | ||||
| #include <turbine/context.hpp> | ||||
|  | ||||
| #include "initparams.hpp" | ||||
|  | ||||
| namespace nostalgia::core { | ||||
|  | ||||
| class Context; | ||||
|  | ||||
| struct ContextDeleter { | ||||
| 	void operator()(Context *p) noexcept; | ||||
| }; | ||||
|  | ||||
| using ContextUPtr = ox::UPtr<Context, ContextDeleter>; | ||||
|  | ||||
| ox::Result<ContextUPtr> init(turbine::Context &tctx, InitParams const¶ms = {}) noexcept; | ||||
|  | ||||
| keel::Context &keelCtx(Context &ctx) noexcept; | ||||
|  | ||||
| turbine::Context &turbineCtx(Context &ctx) noexcept; | ||||
|  | ||||
| } | ||||
|  | ||||
| @@ -1,30 +0,0 @@ | ||||
| add_library(NostalgiaCore-Studio) | ||||
|  | ||||
| add_library( | ||||
| 	NostalgiaCore-Studio-ImGui | ||||
| 		studiomodule.cpp | ||||
| 		tilesheeteditor/tilesheeteditor-imgui.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries( | ||||
| 	NostalgiaCore-Studio PUBLIC | ||||
| 		NostalgiaCore | ||||
| 		Studio | ||||
| ) | ||||
|  | ||||
| target_link_libraries( | ||||
| 	NostalgiaCore-Studio-ImGui PUBLIC | ||||
| 		NostalgiaCore-Studio | ||||
| 		Studio | ||||
| ) | ||||
|  | ||||
| install( | ||||
| 	TARGETS | ||||
| 		NostalgiaCore-Studio-ImGui | ||||
| 		NostalgiaCore-Studio | ||||
| 	LIBRARY DESTINATION | ||||
| 		${NOSTALGIA_DIST_MODULE} | ||||
| ) | ||||
|  | ||||
| add_subdirectory(paletteeditor) | ||||
| add_subdirectory(tilesheeteditor) | ||||
| @@ -1,14 +0,0 @@ | ||||
| target_sources( | ||||
| 	NostalgiaCore-Studio PRIVATE | ||||
| 		commands/addcolorcommand.cpp | ||||
| 		commands/addpagecommand.cpp | ||||
| 		commands/applycolorallpagescommand.cpp | ||||
| 		commands/duplicatepagecommand.cpp | ||||
| 		commands/movecolorcommand.cpp | ||||
| 		commands/removecolorcommand.cpp | ||||
| 		commands/removepagecommand.cpp | ||||
| 		commands/renamepagecommand.cpp | ||||
| 		commands/updatecolorcommand.cpp | ||||
| 		commands/updatecolorinfocommand.cpp | ||||
| 		paletteeditor-imgui.cpp | ||||
| ) | ||||
| @@ -1,83 +0,0 @@ | ||||
| /* | ||||
|  * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved. | ||||
|  */ | ||||
|  | ||||
| #include "drawcommand.hpp" | ||||
|  | ||||
| namespace nostalgia::core { | ||||
|  | ||||
| DrawCommand::DrawCommand( | ||||
| 		TileSheet &img, | ||||
| 		TileSheet::SubSheetIdx subSheetIdx, | ||||
| 		std::size_t idx, | ||||
| 		int palIdx) noexcept: | ||||
| 		m_img(img), | ||||
| 		m_subSheetIdx(std::move(subSheetIdx)), | ||||
| 		m_palIdx(palIdx) { | ||||
| 	auto &subsheet = getSubSheet(m_img, m_subSheetIdx); | ||||
| 	m_changes.emplace_back(static_cast<uint32_t>(idx), getPixel(subsheet, m_img.bpp, idx)); | ||||
| } | ||||
|  | ||||
| DrawCommand::DrawCommand( | ||||
| 		TileSheet &img, | ||||
| 		TileSheet::SubSheetIdx subSheetIdx, | ||||
| 		ox::Vector<std::size_t> const&idxList, | ||||
| 		int palIdx) noexcept: | ||||
| 		m_img(img), | ||||
| 		m_subSheetIdx(std::move(subSheetIdx)), | ||||
| 		m_palIdx(palIdx) { | ||||
| 	auto &subsheet = getSubSheet(m_img, m_subSheetIdx); | ||||
| 	for (auto const idx : idxList) { | ||||
| 		m_changes.emplace_back(static_cast<uint32_t>(idx), getPixel(subsheet, m_img.bpp, idx)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool DrawCommand::append(std::size_t idx) noexcept { | ||||
| 	auto &subsheet = getSubSheet(m_img, m_subSheetIdx); | ||||
| 	if (m_changes.back().value->idx != idx && getPixel(subsheet, m_img.bpp, idx) != m_palIdx) { | ||||
| 		// duplicate entries are bad | ||||
| 		auto existing = ox::find_if(m_changes.cbegin(), m_changes.cend(), [idx](auto const&c) { | ||||
| 			return c.idx == idx; | ||||
| 		}); | ||||
| 		if (existing == m_changes.cend()) { | ||||
| 			m_changes.emplace_back(static_cast<uint32_t>(idx), getPixel(subsheet, m_img.bpp, idx)); | ||||
| 			setPixel(subsheet, m_img.bpp, idx, static_cast<uint8_t>(m_palIdx)); | ||||
| 			return true; | ||||
| 		} | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool DrawCommand::append(ox::Vector<std::size_t> const&idxList) noexcept { | ||||
| 	auto out = false; | ||||
| 	for (auto idx : idxList) { | ||||
| 		out = append(idx) || out; | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
|  | ||||
| ox::Error DrawCommand::redo() noexcept { | ||||
| 	auto &subsheet = getSubSheet(m_img, m_subSheetIdx); | ||||
| 	for (auto const&c : m_changes) { | ||||
| 		setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(m_palIdx)); | ||||
| 	} | ||||
| 	return {}; | ||||
| } | ||||
|  | ||||
| ox::Error DrawCommand::undo() noexcept { | ||||
| 	auto &subsheet = getSubSheet(m_img, m_subSheetIdx); | ||||
| 	for (auto const&c : m_changes) { | ||||
| 		setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx)); | ||||
| 	} | ||||
| 	return {}; | ||||
| } | ||||
|  | ||||
| int DrawCommand::commandId() const noexcept { | ||||
| 	return static_cast<int>(CommandId::Draw); | ||||
| } | ||||
|  | ||||
| TileSheet::SubSheetIdx const&DrawCommand::subsheetIdx() const noexcept { | ||||
| 	return m_subSheetIdx; | ||||
| } | ||||
|  | ||||
| } | ||||
| @@ -1,11 +0,0 @@ | ||||
| add_executable( | ||||
| 	NostalgiaCoreTest | ||||
| 		tests.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries( | ||||
| 	NostalgiaCoreTest | ||||
| 		NostalgiaCore | ||||
| ) | ||||
|  | ||||
| add_test("[NostalgiaCore] readWriteTileSheet" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/NostalgiaCoreTest readWriteTileSheet) | ||||
| @@ -7,12 +7,12 @@ | ||||
| #include <ox/std/math.hpp> | ||||
| #include <ox/std/types.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| using Color16 = uint16_t; | ||||
| 
 | ||||
| /**
 | ||||
|  * Nostalgia Core logically uses 16 bit colors, but must translate that to 32 | ||||
|  * Nostalgia logically uses 16 bit colors, but must translate that to 32 | ||||
|  * bit colors in some implementations. | ||||
|  */ | ||||
| using Color32 = uint32_t; | ||||
| @@ -154,7 +154,7 @@ static_assert(color16(16, 32, 8) == 9200); | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr Color16 applySelectionColor(Color16 const color) noexcept { | ||||
| 	namespace core = nostalgia::core; | ||||
| 	namespace core = nostalgia::gfx; | ||||
| 	auto const r = core::red16(color) / 2; | ||||
| 	auto const g = (core::green16(color) + 20) / 2; | ||||
| 	auto const b = (core::blue16(color) + 31) / 2; | ||||
| @@ -6,13 +6,14 @@ | ||||
| 
 | ||||
| #include <ox/std/stringliteral.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| constexpr auto TileWidth = 8; | ||||
| constexpr auto TileHeight = 8; | ||||
| constexpr auto PixelsPerTile = TileWidth * TileHeight; | ||||
| 
 | ||||
| constexpr ox::StringLiteral FileExt_ng("ng"); | ||||
| constexpr ox::StringLiteral FileExt_nts("nts"); | ||||
| constexpr ox::StringLiteral FileExt_npal("npal"); | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/nostalgia/modules/gfx/include/nostalgia/gfx/context.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/nostalgia/modules/gfx/include/nostalgia/gfx/context.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| /* | ||||
|  * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ox/std/memory.hpp> | ||||
|  | ||||
| #include <turbine/context.hpp> | ||||
|  | ||||
| #include "initparams.hpp" | ||||
|  | ||||
| namespace nostalgia::gfx { | ||||
|  | ||||
| class Context; | ||||
|  | ||||
| void safeDelete(Context *ctx) noexcept; | ||||
|  | ||||
| ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const¶ms = {}) noexcept; | ||||
|  | ||||
| keel::Context &keelCtx(Context &ctx) noexcept; | ||||
|  | ||||
| turbine::Context &turbineCtx(Context &ctx) noexcept; | ||||
|  | ||||
| } | ||||
|  | ||||
| @@ -13,10 +13,10 @@ | ||||
| #include "palette.hpp" | ||||
| #include "tilesheet.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| struct Sprite { | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.Sprite"; | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.Sprite"; | ||||
| 	static constexpr auto TypeVersion = 1; | ||||
| 	bool enabled = false; | ||||
| 	int x = 0; | ||||
| @@ -46,7 +46,7 @@ OX_MODEL_BEGIN(Sprite) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| struct BgTile { | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.BgTile"; | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.BgTile"; | ||||
| 	static constexpr auto TypeVersion = 1; | ||||
| 	unsigned tileIdx = 0; | ||||
| 	unsigned palBank = 0; | ||||
| @@ -62,7 +62,7 @@ OX_MODEL_BEGIN(BgTile) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| struct TileSheetSetEntrySection { | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheetSetEntrySection"; | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.TileSheetSetEntrySection"; | ||||
| 	static constexpr auto TypeVersion = 1; | ||||
| 	int32_t begin = 0; | ||||
| 	int32_t tiles = 0; | ||||
| @@ -78,7 +78,7 @@ OX_MODEL_BEGIN(TileSheetSetEntrySection) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| struct TileSheetSetEntry { | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheetSetEntry"; | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.TileSheetSetEntry"; | ||||
| 	static constexpr auto TypeVersion = 1; | ||||
| 	ox::FileAddress tilesheet; | ||||
| 	ox::Vector<TileSheetSetEntrySection> sections; | ||||
| @@ -90,7 +90,7 @@ OX_MODEL_BEGIN(TileSheetSetEntry) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| struct TileSheetSet { | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.TileSheetSet"; | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.TileSheetSet"; | ||||
| 	static constexpr auto TypeVersion = 1; | ||||
| 	static constexpr auto Preloadable = true; | ||||
| 	int32_t bpp = 0; | ||||
| @@ -102,8 +102,6 @@ OX_MODEL_BEGIN(TileSheetSet) | ||||
| 	OX_MODEL_FIELD(entries) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| void addEntry(TileSheetSet &set, ox::FileAddress path, int32_t begin = 0, int32_t size = -1) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| int tileColumns(Context&) noexcept; | ||||
| 
 | ||||
| @@ -144,6 +142,10 @@ ox::Error loadBgTileSheet( | ||||
| 		unsigned cbb, | ||||
| 		TileSheetSet const&set) noexcept; | ||||
| 
 | ||||
| void clearCbb(Context &ctx, unsigned cbb) noexcept; | ||||
| 
 | ||||
| void clearCbbs(Context &ctx) noexcept; | ||||
| 
 | ||||
| ox::Error loadBgTileSheet( | ||||
| 		Context &ctx, | ||||
| 		unsigned cbb, | ||||
| @@ -240,15 +242,15 @@ void puts(Context &ctx, int column, int row, ox::StringViewCR str) noexcept; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| namespace nostalgia::core::gl { | ||||
| namespace nostalgia::gfx::gl { | ||||
| 
 | ||||
| constexpr ox::CStringView GlslVersion = "#version 330"; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| ox::Size drawSize(int scale = 5) noexcept; | ||||
| 
 | ||||
| void draw(core::Context &ctx, ox::Size const&renderSz) noexcept; | ||||
| void draw(gfx::Context &ctx, ox::Size const&renderSz) noexcept; | ||||
| 
 | ||||
| void draw(core::Context&, int scale = 5) noexcept; | ||||
| void draw(gfx::Context&, int scale = 5) noexcept; | ||||
| 
 | ||||
| } | ||||
| @@ -6,7 +6,7 @@ | ||||
| 
 | ||||
| #include <ox/std/types.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| struct InitParams { | ||||
| 	bool glInstallDrawer = true; | ||||
| @@ -6,7 +6,7 @@ | ||||
| 
 | ||||
| #include <keel/module.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| const keel::Module *keelModule() noexcept; | ||||
| 
 | ||||
| @@ -11,7 +11,7 @@ | ||||
| 
 | ||||
| #include "color.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| struct PaletteColorV1 { | ||||
|     static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.PaletteColor"; | ||||
| @@ -33,7 +33,31 @@ OX_MODEL_BEGIN(PaletteColorV1) | ||||
| 	OX_MODEL_FIELD(a) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| using PaletteColor = PaletteColorV1; | ||||
| 
 | ||||
| struct PaletteColorV2 { | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.PaletteColor"; | ||||
| 	static constexpr auto TypeVersion = 2; | ||||
| 	uint8_t r{}, g{}, b{}, a{}; | ||||
| 	constexpr PaletteColorV2() noexcept = default; | ||||
| 	constexpr PaletteColorV2(Color16 const c) noexcept: | ||||
|         r{red16(c)}, | ||||
|         g{green16(c)}, | ||||
|         b{blue16(c)}, | ||||
|         a{alpha16(c)} {} | ||||
| 	constexpr PaletteColorV2(uint8_t const r, uint8_t const g, uint8_t const b, uint8_t const a) noexcept: | ||||
|         r{r}, g{g}, b{b}, a{a} {} | ||||
| 	constexpr operator Color16() const noexcept { return color16(r, g, b, a); } | ||||
| }; | ||||
| 
 | ||||
| OX_MODEL_BEGIN(PaletteColorV2) | ||||
| 	OX_MODEL_FIELD(r) | ||||
| 	OX_MODEL_FIELD(g) | ||||
| 	OX_MODEL_FIELD(b) | ||||
| 	OX_MODEL_FIELD(a) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| 
 | ||||
| using PaletteColor = PaletteColorV2; | ||||
| 
 | ||||
| 
 | ||||
| struct PalettePageV1 { | ||||
| @@ -58,7 +82,31 @@ OX_MODEL_BEGIN(PalettePageV1) | ||||
| 	OX_MODEL_FIELD(colors) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| using PalettePage = PalettePageV1; | ||||
| 
 | ||||
| struct PalettePageV2 { | ||||
|     static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.Palette.PalettePage"; | ||||
|     static constexpr auto TypeVersion = 2; | ||||
|     ox::String name; | ||||
|     ox::Vector<PaletteColorV2> colors; | ||||
|     constexpr PalettePageV2() noexcept = default; | ||||
|     constexpr PalettePageV2(ox::StringParam pName, ox::Vector<PaletteColorV2> pColors) noexcept: | ||||
|         name(std::move(pName)), colors(std::move(pColors)) {} | ||||
|     constexpr PalettePageV2(ox::StringParam pName, ox::Vector<Color16> const&pColors) noexcept: | ||||
|         name(std::move(pName)) { | ||||
|         colors.reserve(pColors.size()); | ||||
|         for (auto const c : pColors) { | ||||
|             colors.emplace_back(c); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| OX_MODEL_BEGIN(PalettePageV2) | ||||
| 	OX_MODEL_FIELD(name) | ||||
| 	OX_MODEL_FIELD(colors) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| 
 | ||||
| using PalettePage = PalettePageV2; | ||||
| 
 | ||||
| 
 | ||||
| struct NostalgiaPalette { | ||||
| @@ -166,11 +214,41 @@ constexpr ox::Error repair(PaletteV4 &p) noexcept { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| using Palette = PaletteV4; | ||||
| struct PaletteV5 { | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.Palette"; | ||||
| 	static constexpr auto TypeVersion = 5; | ||||
| 	static constexpr auto Preloadable = true; | ||||
| 	ox::Vector<ox::String> colorNames; | ||||
| 	ox::Vector<PalettePageV2> pages; | ||||
| }; | ||||
| 
 | ||||
| OX_MODEL_BEGIN(PaletteV5) | ||||
| 	OX_MODEL_FIELD(colorNames) | ||||
| 	OX_MODEL_FIELD(pages) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr bool valid(PaletteV5 const&p) noexcept { | ||||
| 	auto const colors = p.colorNames.size(); | ||||
| 	return ox::all_of(p.pages.begin(), p.pages.end(), [colors](PalettePageV2 const&page) { | ||||
| 		return page.colors.size() == colors; | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| constexpr ox::Error repair(PaletteV5 &p) noexcept { | ||||
| 	auto const colors = p.colorNames.size(); | ||||
| 	for (auto &page : p.pages) { | ||||
| 		page.colors.resize(colors); | ||||
| 	} | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| using Palette = PaletteV5; | ||||
| 
 | ||||
| 
 | ||||
| struct CompactPaletteV1 { | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.CompactPalette"; | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.CompactPalette"; | ||||
| 	static constexpr auto TypeVersion = 1; | ||||
| 	static constexpr auto Preloadable = true; | ||||
| 	ox::Vector<ox::Vector<Color16>> pages{}; | ||||
| @@ -207,7 +285,7 @@ using CompactPalette = CompactPaletteV1; | ||||
| 
 | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr Color16 color(Palette const&pal, size_t page, size_t idx) noexcept { | ||||
| constexpr Color16 color(Palette const&pal, size_t const page, size_t const idx) noexcept { | ||||
| 	if (page < pal.pages.size() && idx < pal.pages[page].colors.size()) [[likely]] { | ||||
| 		return pal.pages[page].colors[idx]; | ||||
| 	} | ||||
| @@ -215,7 +293,7 @@ constexpr Color16 color(Palette const&pal, size_t page, size_t idx) noexcept { | ||||
| } | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr Color16 color(CompactPalette const&pal, size_t page, size_t idx) noexcept { | ||||
| constexpr Color16 color(CompactPalette const&pal, size_t const page, size_t const idx) noexcept { | ||||
| 	if (page < pal.pages.size() && idx < pal.pages[page].size()) [[likely]] { | ||||
| 		return pal.pages[page][idx]; | ||||
| 	} | ||||
| @@ -223,37 +301,37 @@ constexpr Color16 color(CompactPalette const&pal, size_t page, size_t idx) noexc | ||||
| } | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr Color16 color(Palette const&pal, size_t idx) noexcept { | ||||
| constexpr Color16 color(Palette const&pal, size_t const idx) noexcept { | ||||
| 	return color(pal, 0, idx); | ||||
| } | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr Color16 color(CompactPalette const&pal, size_t idx) noexcept { | ||||
| constexpr Color16 color(CompactPalette const&pal, size_t const idx) noexcept { | ||||
| 	return color(pal, 0, idx); | ||||
| } | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr auto &colors(Palette &pal, size_t page = 0) noexcept { | ||||
| constexpr auto &colors(Palette &pal, size_t const page = 0) noexcept { | ||||
| 	return pal.pages[page].colors; | ||||
| } | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr auto &colors(CompactPalette &pal, size_t page = 0) noexcept { | ||||
| constexpr auto &colors(CompactPalette &pal, size_t const page = 0) noexcept { | ||||
| 	return pal.pages[page]; | ||||
| } | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr auto &colors(Palette const&pal, size_t page = 0) noexcept { | ||||
| constexpr auto &colors(Palette const&pal, size_t const page = 0) noexcept { | ||||
| 	return pal.pages[page]; | ||||
| } | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr auto &colors(CompactPalette const&pal, size_t page = 0) noexcept { | ||||
| constexpr auto &colors(CompactPalette const&pal, size_t const page = 0) noexcept { | ||||
| 	return pal.pages[page]; | ||||
| } | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr size_t colorCnt(Palette const&pal, size_t page = 0) noexcept { | ||||
| constexpr size_t colorCnt(Palette const&pal, size_t const page = 0) noexcept { | ||||
| 	if (page < pal.pages.size()) [[likely]] { | ||||
| 		return pal.pages[page].colors.size(); | ||||
| 	} | ||||
| @@ -261,7 +339,7 @@ constexpr size_t colorCnt(Palette const&pal, size_t page = 0) noexcept { | ||||
| } | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr size_t colorCnt(CompactPalette const&pal, size_t page = 0) noexcept { | ||||
| constexpr size_t colorCnt(CompactPalette const&pal, size_t const page = 0) noexcept { | ||||
| 	if (page < pal.pages.size()) [[likely]] { | ||||
| 		return pal.pages[page].size(); | ||||
| 	} | ||||
| @@ -8,7 +8,7 @@ | ||||
| 
 | ||||
| #include "consts.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr std::size_t ptToIdx(int x, int y, int c, int scale = 1) noexcept { | ||||
							
								
								
									
										11
									
								
								src/nostalgia/modules/gfx/include/nostalgia/gfx/studio.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/nostalgia/modules/gfx/include/nostalgia/gfx/studio.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| /* | ||||
|  * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <studio/studio.hpp> | ||||
|  | ||||
| namespace nostalgia::core { | ||||
|  | ||||
| } | ||||
| @@ -6,7 +6,7 @@ | ||||
| 
 | ||||
| #include <studio/studio.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| const studio::Module *studioModule() noexcept; | ||||
| 
 | ||||
| @@ -5,18 +5,33 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <ox/fs/fs.hpp> | ||||
| #include <ox/std/array.hpp> | ||||
| #include <ox/std/point.hpp> | ||||
| #include <ox/std/size.hpp> | ||||
| #include <ox/std/span.hpp> | ||||
| #include <ox/std/types.hpp> | ||||
| #include <ox/model/def.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/ptidxconv.hpp> | ||||
| #include <nostalgia/gfx/ptidxconv.hpp> | ||||
| 
 | ||||
| #include "palette.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| struct SubSheetTemplate { | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.SubSheetTemplate"; | ||||
| 	static constexpr auto TypeVersion = 1; | ||||
| 	ox::String name; | ||||
| 	int32_t width{}; | ||||
| 	int32_t height{}; | ||||
| 	ox::Vector<SubSheetTemplate> subsheets; | ||||
| }; | ||||
| 
 | ||||
| OX_MODEL_BEGIN(SubSheetTemplate) | ||||
| 	OX_MODEL_FIELD(name) | ||||
| 	OX_MODEL_FIELD(width) | ||||
| 	OX_MODEL_FIELD(height) | ||||
| 	OX_MODEL_FIELD(subsheets) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| 
 | ||||
| // Predecessor to TileSheet, kept for backward compatibility
 | ||||
| struct TileSheetV1 { | ||||
| @@ -212,6 +227,10 @@ struct TileSheetV4 { | ||||
| 				pixels(std::move(pPixels)) { | ||||
| 		} | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * | ||||
| 		 * @return the dimensional size of the SubSheet (e.g. width * height) | ||||
| 		 */ | ||||
| 		[[nodiscard]] | ||||
| 		constexpr std::size_t size() const noexcept { | ||||
| 			return static_cast<std::size_t>(columns) * static_cast<std::size_t>(rows); | ||||
| @@ -269,7 +288,109 @@ constexpr ox::Error repair(TileSheetV4 &ts) noexcept { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| using TileSheet = TileSheetV4; | ||||
| struct TileSheetV5 { | ||||
| 	using SubSheetIdx = ox::Vector<uint32_t, 4>; | ||||
| 
 | ||||
| 	struct SubSheet { | ||||
| 		static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.TileSheet.SubSheet"; | ||||
| 		static constexpr auto TypeVersion = 5; | ||||
| 		SubSheetId id = 0; | ||||
| 		ox::String name; | ||||
| 		int columns = 0; | ||||
| 		int rows = 0; | ||||
| 		ox::Vector<SubSheet> subsheets; | ||||
| 		ox::Vector<uint8_t> pixels; | ||||
| 
 | ||||
| 		constexpr SubSheet() noexcept = default; | ||||
| 		SubSheet( | ||||
| 				SubSheetId const pId, | ||||
| 				ox::StringParam pName, | ||||
| 				int const pColumns, | ||||
| 				int const pRows) noexcept: | ||||
| 				id(pId), | ||||
| 				name(std::move(pName)), | ||||
| 				columns(pColumns), | ||||
| 				rows(pRows), | ||||
| 				pixels(static_cast<std::size_t>(columns * rows * PixelsPerTile)) { | ||||
| 		} | ||||
| 		SubSheet( | ||||
| 				SubSheetId const pId, | ||||
| 				ox::StringParam pName, | ||||
| 				int const pColumns, | ||||
| 				int const pRows, | ||||
| 				ox::Vector<uint8_t> pPixels) noexcept: | ||||
| 				id(pId), | ||||
| 				name(std::move(pName)), | ||||
| 				columns(pColumns), | ||||
| 				rows(pRows), | ||||
| 				pixels(std::move(pPixels)) { | ||||
| 		} | ||||
| 
 | ||||
| 		/**
 | ||||
| 		 * | ||||
| 		 * @return the dimensional size of the SubSheet (e.g. width * height) | ||||
| 		 */ | ||||
| 		[[nodiscard]] | ||||
| 		constexpr std::size_t size() const noexcept { | ||||
| 			return static_cast<std::size_t>(columns) * static_cast<std::size_t>(rows); | ||||
| 		} | ||||
| 
 | ||||
| 	}; | ||||
| 
 | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.TileSheet"; | ||||
| 	static constexpr auto TypeVersion = 5; | ||||
| 	/**
 | ||||
| 	 * bpp is unused for TileSheet, but it does get used in CompactTileSheet. | ||||
| 	 * All pixel in TileSheet are 8 bpp, regardless of what the bpp field says. | ||||
| 	 */ | ||||
| 	int8_t bpp = 4; | ||||
| 	SubSheetId idIt = 0; | ||||
| 	ox::String defaultPalette; | ||||
| 	SubSheet subsheet{0, "Root", 1, 1}; | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr bool valid(TileSheetV5::SubSheet const&ss) noexcept { | ||||
| 	if (ss.subsheets.empty()) { | ||||
| 		return static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) == ss.pixels.size(); | ||||
| 	} else { | ||||
| 		return ss.pixels.empty() && ox::all_of(ss.subsheets.begin(), ss.subsheets.end(), | ||||
| 				[](TileSheetV5::SubSheet const&s) { | ||||
| 			return valid(s); | ||||
| 		}); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| constexpr bool valid(TileSheetV5 const&ts) noexcept { | ||||
| 	return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet); | ||||
| } | ||||
| 
 | ||||
| constexpr void repair(TileSheetV5::SubSheet &ss, int const bpp) noexcept { | ||||
| 	if (ss.subsheets.empty()) { | ||||
| 		auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile); | ||||
| 		ss.pixels.resize(bytes); | ||||
| 	} else { | ||||
| 		ss.pixels.clear(); | ||||
| 		ss.columns = -1; | ||||
| 		ss.rows = -1; | ||||
| 	} | ||||
| 	for (auto &s : ss.subsheets) { | ||||
| 		repair(s, bpp); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| constexpr ox::Error repair(TileSheetV5 &ts) noexcept { | ||||
| 	if (ts.bpp != 4 && ts.bpp != 8) { | ||||
| 		return ox::Error{1, "Unable to repair TileSheet"}; | ||||
| 	} | ||||
| 	repair(ts.subsheet, ts.bpp); | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| using TileSheet = TileSheetV5; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| std::size_t idx(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; | ||||
| @@ -281,101 +402,70 @@ size_t getTileCnt(TileSheet const&ts) noexcept; | ||||
| TileSheet::SubSheet const*getSubsheet(TileSheet const&ts, SubSheetId id) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| size_t getTileIdx(TileSheet const&ts, SubSheetId id) noexcept; | ||||
| ox::Optional<size_t> getTileIdx(TileSheet const&ts, SubSheetId id) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept; | ||||
| uint8_t getPixel(TileSheet::SubSheet const&ss, std::size_t idx) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept; | ||||
| uint8_t getPixel(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, std::size_t idx) noexcept; | ||||
| void setPixel(TileSheet::SubSheet &ss, ox::Point const&pt, uint8_t palIdx) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; | ||||
| ox::Error setPixelCount(TileSheet::SubSheet &ss, std::size_t cnt) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; | ||||
| void flipX(TileSheet::SubSheet &ss, ox::Point const &a, ox::Point const &b) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, ox::Point const&pt) noexcept; | ||||
| 
 | ||||
| constexpr void walkPixels(TileSheet::SubSheet const&ss, int8_t pBpp, auto callback) noexcept { | ||||
| 	if (pBpp == 4) { | ||||
| 		const auto pixelCnt = ox::min<std::size_t>( | ||||
| 				static_cast<std::size_t>(ss.columns * ss.rows * PixelsPerTile) / 2, | ||||
| 				ss.pixels.size()); | ||||
| 		//oxAssert(pixels.size() == pixelCnt, "Pixel count does not match rows and columns");
 | ||||
| 		for (std::size_t i = 0; i < pixelCnt; ++i) { | ||||
| 			const auto colorIdx1 = static_cast<uint8_t>(ss.pixels[i] & 0xF); | ||||
| 			const auto colorIdx2 = static_cast<uint8_t>(ss.pixels[i] >> 4); | ||||
| 			callback(i * 2 + 0, colorIdx1); | ||||
| 			callback(i * 2 + 1, colorIdx2); | ||||
| 		} | ||||
| 	} else { | ||||
| 		const auto pixelCnt = ox::min<std::size_t>( | ||||
| 				static_cast<std::size_t>(ss.columns * ss.rows * PixelsPerTile), | ||||
| 				ss.pixels.size()); | ||||
| 		for (std::size_t i = 0; i < pixelCnt; ++i) { | ||||
| 			const auto p = ss.pixels[i]; | ||||
| 			callback(i, p); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept; | ||||
| 
 | ||||
| void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, ox::Point const&pt, uint8_t palIdx) noexcept; | ||||
| 
 | ||||
| ox::Error setPixelCount(TileSheet::SubSheet &ss, int8_t pBpp, std::size_t cnt) noexcept; | ||||
| void flipY(TileSheet::SubSheet &ss, ox::Point const &a, ox::Point const &b) noexcept; | ||||
| 
 | ||||
| /**
 | ||||
|  * Gets a count of the pixels in this sheet, and not that of its children. | ||||
|  * @param pBpp bits per pixel, need for knowing how to count the pixels | ||||
|  * @return a count of the pixels in this sheet | ||||
|  */ | ||||
| [[nodiscard]] | ||||
| unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept; | ||||
| unsigned pixelCnt(TileSheet::SubSheet const&ss) noexcept; | ||||
| 
 | ||||
| /**
 | ||||
|  * | ||||
|  * @param ss | ||||
|  * @param pBpp | ||||
|  * @param sz size of Subsheet in tiles (not pixels) | ||||
|  */ | ||||
| ox::Error resizeSubsheet(TileSheet::SubSheet &ss, int8_t pBpp, ox::Size const&sz) noexcept; | ||||
| ox::Error resizeSubsheet(TileSheet::SubSheet &ss, ox::Size const&sz) noexcept; | ||||
| 
 | ||||
| /**
 | ||||
|  * validateSubSheetIdx takes a SubSheetIdx and moves the index to the | ||||
|  * preceding or parent sheet if the current corresponding sheet does | ||||
|  * not exist. | ||||
|  * @param ts | ||||
|  * @param idx SubSheetIdx to validate and correct | ||||
|  * @return a valid version of idx | ||||
|  */ | ||||
| [[nodiscard]] | ||||
| TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx idx) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| TileSheet::SubSheet const&getSubSheet( | ||||
| 		TileSheet::SubSheetIdx const&idx, | ||||
| 		std::size_t idxIt, | ||||
| 		TileSheet::SubSheet const&pSubsheet) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| TileSheet::SubSheet &getSubSheet( | ||||
| 		TileSheet::SubSheetIdx const&idx, | ||||
| 		ox::SpanView<uint32_t> const&idx, | ||||
| 		std::size_t idxIt, | ||||
| 		TileSheet::SubSheet &pSubsheet) noexcept; | ||||
| 
 | ||||
| #if defined(__GNUC__) && __GNUC__ >= 13 | ||||
| #pragma GCC diagnostic push | ||||
| #pragma GCC diagnostic ignored "-Wdangling-reference" | ||||
| #endif | ||||
| [[nodiscard]] | ||||
| TileSheet::SubSheet const&getSubSheet(TileSheet const&ts, TileSheet::SubSheetIdx const&idx) noexcept; | ||||
| TileSheet::SubSheet const&getSubSheet(TileSheet const&ts, ox::SpanView<uint32_t> const &idx) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| TileSheet::SubSheet &getSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept; | ||||
| TileSheet::SubSheet &getSubSheet(TileSheet &ts, ox::SpanView<uint32_t> const &idx) noexcept; | ||||
| #if defined(__GNUC__) && __GNUC__ >= 13 | ||||
| #pragma GCC diagnostic pop | ||||
| #endif | ||||
| 
 | ||||
| ox::Error addSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const &idx) noexcept; | ||||
| 
 | ||||
| ox::Error insertSubSheet(TileSheet &ts, ox::SpanView<uint32_t> const &idx, TileSheet::SubSheet ss) noexcept; | ||||
| 
 | ||||
| ox::Error rmSubSheet( | ||||
| 		TileSheet &ts, | ||||
| 		TileSheet::SubSheetIdx const&idx, | ||||
| @@ -385,13 +475,7 @@ ox::Error rmSubSheet( | ||||
| ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| uint8_t getPixel4Bpp( | ||||
| 		TileSheet const&ts, | ||||
| 		ox::Point const&pt, | ||||
| 		TileSheet::SubSheetIdx const&subsheetIdx) noexcept; | ||||
| 
 | ||||
| [[nodiscard]] | ||||
| uint8_t getPixel8Bpp( | ||||
| uint8_t getPixel( | ||||
| 		TileSheet const&ts, | ||||
| 		ox::Point const&pt, | ||||
| 		TileSheet::SubSheetIdx const&subsheetIdx) noexcept; | ||||
| @@ -400,6 +484,8 @@ ox::Result<SubSheetId> getIdFor(TileSheet const&ts, ox::StringViewCR path) noexc | ||||
| 
 | ||||
| ox::Result<unsigned> getTileOffset(TileSheet const&ts, ox::StringViewCR pNamePath) noexcept; | ||||
| 
 | ||||
| ox::Result<uint32_t> getTileOffset(TileSheet const&ts, SubSheetId pId) noexcept; | ||||
| 
 | ||||
| ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept; | ||||
| 
 | ||||
| ox::Result<ox::StringView> getNameFor(TileSheet const&ts, SubSheetId pId) noexcept; | ||||
| @@ -409,7 +495,7 @@ ox::Vector<uint8_t> pixels(TileSheet &ts) noexcept; | ||||
| 
 | ||||
| 
 | ||||
| struct CompactTileSheetV1 { | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.CompactTileSheet"; | ||||
| 	static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.CompactTileSheet"; | ||||
| 	static constexpr auto TypeVersion = 1; | ||||
| 	static constexpr auto Preloadable = true; | ||||
| 	int8_t bpp = 0; | ||||
| @@ -499,6 +585,22 @@ OX_MODEL_BEGIN(TileSheetV4) | ||||
| 	OX_MODEL_FIELD(subsheet) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| OX_MODEL_BEGIN(TileSheetV5::SubSheet) | ||||
| 	OX_MODEL_FIELD(id) | ||||
| 	OX_MODEL_FIELD(name) | ||||
| 	OX_MODEL_FIELD(rows) | ||||
| 	OX_MODEL_FIELD(columns) | ||||
| 	OX_MODEL_FIELD(subsheets) | ||||
| 	OX_MODEL_FIELD(pixels) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| OX_MODEL_BEGIN(TileSheetV5) | ||||
| 	OX_MODEL_FIELD(bpp) | ||||
| 	OX_MODEL_FIELD(idIt) | ||||
| 	OX_MODEL_FIELD(defaultPalette) | ||||
| 	OX_MODEL_FIELD(subsheet) | ||||
| OX_MODEL_END() | ||||
| 
 | ||||
| OX_MODEL_BEGIN(CompactTileSheetV1) | ||||
| 	OX_MODEL_FIELD(bpp) | ||||
| 	OX_MODEL_FIELD(defaultPalette) | ||||
| @@ -1,5 +1,5 @@ | ||||
| add_library( | ||||
| 	NostalgiaCore | ||||
| 	NostalgiaGfx | ||||
| 		gfx.cpp | ||||
| 		tilesheet.cpp | ||||
| ) | ||||
| @@ -10,12 +10,12 @@ if(NOT BUILDCORE_TARGET STREQUAL "gba") | ||||
| endif() | ||||
| 
 | ||||
| target_include_directories( | ||||
| 	NostalgiaCore PUBLIC | ||||
| 	NostalgiaGfx PUBLIC | ||||
| 		../include | ||||
| ) | ||||
| 
 | ||||
| target_link_libraries( | ||||
| 	NostalgiaCore PUBLIC | ||||
| 	NostalgiaGfx PUBLIC | ||||
| 		Turbine | ||||
| ) | ||||
| 
 | ||||
| @@ -26,7 +26,7 @@ endif() | ||||
| 
 | ||||
| install( | ||||
| 	TARGETS | ||||
| 		NostalgiaCore | ||||
| 		NostalgiaGfx | ||||
| 	DESTINATION | ||||
| 		LIBRARY DESTINATION lib | ||||
| 		ARCHIVE DESTINATION lib | ||||
| @@ -1,15 +1,15 @@ | ||||
| add_library( | ||||
| 	NostalgiaCore-GBA OBJECT | ||||
| 	NostalgiaGfx-GBA OBJECT | ||||
| 		context.cpp | ||||
| 		gfx.cpp | ||||
| 		panic.cpp | ||||
| ) | ||||
| target_include_directories( | ||||
| 	NostalgiaCore-GBA PUBLIC | ||||
| 	NostalgiaGfx-GBA PUBLIC | ||||
| 		../../include | ||||
| ) | ||||
| target_link_libraries( | ||||
| 	NostalgiaCore-GBA PUBLIC | ||||
| 	NostalgiaGfx-GBA PUBLIC | ||||
| 		TeaGBA | ||||
| 		Keel | ||||
| 		Turbine | ||||
| @@ -17,5 +17,5 @@ target_link_libraries( | ||||
| 
 | ||||
| if(BUILDCORE_TARGET STREQUAL "gba") | ||||
| 	set_source_files_properties(gfx.cpp PROPERTIES COMPILE_FLAGS -marm) | ||||
| 	target_link_libraries(NostalgiaCore PUBLIC NostalgiaCore-GBA) | ||||
| 	target_link_libraries(NostalgiaGfx PUBLIC NostalgiaGfx-GBA) | ||||
| endif() | ||||
| @@ -4,14 +4,14 @@ | ||||
| 
 | ||||
| #include <turbine/turbine.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/gfx.hpp> | ||||
| #include <nostalgia/gfx/gfx.hpp> | ||||
| 
 | ||||
| #include "context.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| void ContextDeleter::operator()(Context *p) noexcept { | ||||
| 	ox::safeDelete(p); | ||||
| void safeDelete(Context *ctx) noexcept { | ||||
| 	delete ctx; | ||||
| } | ||||
| 
 | ||||
| Context::Context(turbine::Context &tctx) noexcept: turbineCtx(tctx) { | ||||
| @@ -19,10 +19,10 @@ Context::Context(turbine::Context &tctx) noexcept: turbineCtx(tctx) { | ||||
| 
 | ||||
| ox::Error initGfx(Context &ctx, InitParams const&) noexcept; | ||||
| 
 | ||||
| ox::Result<ContextUPtr> init(turbine::Context &tctx, InitParams const¶ms) noexcept { | ||||
| ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const¶ms) noexcept { | ||||
| 	auto ctx = ox::make_unique<Context>(tctx); | ||||
| 	OX_RETURN_ERROR(initGfx(*ctx, params)); | ||||
| 	return ContextUPtr(std::move(ctx)); | ||||
| 	return ox::UPtr<Context>(std::move(ctx)); | ||||
| } | ||||
| 
 | ||||
| keel::Context &keelCtx(Context &ctx) noexcept { | ||||
| @@ -4,9 +4,9 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <nostalgia/core/context.hpp> | ||||
| #include <nostalgia/gfx/context.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| struct BgCbbData { | ||||
| 	unsigned bpp = 4; | ||||
| @@ -11,15 +11,15 @@ | ||||
| 
 | ||||
| #include <keel/keel.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/context.hpp> | ||||
| #include <nostalgia/core/gfx.hpp> | ||||
| #include <nostalgia/core/tilesheet.hpp> | ||||
| #include <nostalgia/gfx/context.hpp> | ||||
| #include <nostalgia/gfx/gfx.hpp> | ||||
| #include <nostalgia/gfx/tilesheet.hpp> | ||||
| 
 | ||||
| #include "context.hpp" | ||||
| 
 | ||||
| OX_ALLOW_UNSAFE_BUFFERS_BEGIN | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| static constexpr auto SpriteCount = 128; | ||||
| 
 | ||||
| @@ -63,6 +63,19 @@ ox::Error loadSpritePalette( | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| void clearCbb(Context&, unsigned const cbb) noexcept { | ||||
| 	for (auto &v : MEM_BG_TILES[cbb]) { | ||||
| 		v = 0; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void clearCbbs(Context &ctx) noexcept { | ||||
| 	clearCbb(ctx, 0); | ||||
| 	clearCbb(ctx, 1); | ||||
| 	clearCbb(ctx, 2); | ||||
| 	clearCbb(ctx, 3); | ||||
| } | ||||
| 
 | ||||
| static ox::Error loadTileSheetSet( | ||||
| 		Context &ctx, | ||||
| 		ox::Span<uint16_t> tileMapTargetMem, | ||||
| @@ -99,10 +112,10 @@ ox::Error loadBgTileSheet( | ||||
| 		size_t const tileCnt) noexcept { | ||||
| 	size_t const bppMod = ts.bpp == 4; | ||||
| 	size_t const bytesPerTile = PixelsPerTile >> bppMod; | ||||
| 	auto const pixCnt = tileCnt * bytesPerTile; | ||||
| 	auto const cnt = (tileCnt * bytesPerTile) / 2; | ||||
| 	auto const srcPxIdx = srcTileIdx * bytesPerTile; | ||||
| 	auto const dstPxIdx = (dstTileIdx * bytesPerTile) / 2; | ||||
| 	for (size_t i = 0; i < pixCnt; ++i) { | ||||
| 	for (size_t i = 0; i < cnt; ++i) { | ||||
| 		auto const srcIdx = srcPxIdx + i * 2; | ||||
| 		auto const p1 = static_cast<uint16_t>(ts.pixels[srcIdx]); | ||||
| 		auto const p2 = static_cast<uint16_t>(ts.pixels[srcIdx + 1]); | ||||
| @@ -4,8 +4,8 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <nostalgia/core/context.hpp> | ||||
| #include <nostalgia/gfx/context.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| ox::Error initGfx(Context &ctx, InitParams const&) noexcept; | ||||
| } | ||||
| @@ -4,6 +4,7 @@ | ||||
| 
 | ||||
| 
 | ||||
| #include <ox/std/def.hpp> | ||||
| #include <ox/std/realstd.hpp> | ||||
| 
 | ||||
| #include <keel/media.hpp> | ||||
| #include <turbine/turbine.hpp> | ||||
| @@ -11,7 +12,7 @@ | ||||
| #include <teagba/addresses.hpp> | ||||
| #include <teagba/bios.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/core.hpp> | ||||
| #include <nostalgia/gfx/core.hpp> | ||||
| 
 | ||||
| #include "gfx.hpp" | ||||
| 
 | ||||
| @@ -21,7 +22,7 @@ | ||||
| 
 | ||||
| namespace ox { | ||||
| 
 | ||||
| using namespace nostalgia::core; | ||||
| using namespace nostalgia::gfx; | ||||
| 
 | ||||
| void panic(const char *file, int line, const char *panicMsg, ox::Error const&err) noexcept { | ||||
| 	// reset heap to make sure we have enough memory to allocate context data
 | ||||
| @@ -48,12 +49,10 @@ OX_ALLOW_UNSAFE_BUFFERS_END | ||||
| 		oxErrf("\tError Message:\t{}\n", err.msg); | ||||
| 	} | ||||
| 	oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err)); | ||||
| 	if (err.file != nullptr) { | ||||
| 		oxErrf("\tError Location:\t{}:{}\n", err.file, err.line); | ||||
| 	if (err.src.file_name() != nullptr) { | ||||
| 		oxErrf("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line()); | ||||
| 	} | ||||
| 	// disable all interrupt handling and IntrWait on no interrupts
 | ||||
| 	REG_IE = 0; | ||||
| 	teagba::intrwait(0, 0); | ||||
| 	abort(); | ||||
| } | ||||
| 
 | ||||
| } | ||||
| @@ -3,9 +3,9 @@ | ||||
|  */ | ||||
| 
 | ||||
| #include <keel/media.hpp> | ||||
| #include <nostalgia/core/gfx.hpp> | ||||
| #include <nostalgia/gfx/gfx.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| constexpr auto GbaTileColumns = 32; | ||||
| constexpr auto GbaTileRows = 32; | ||||
| @@ -1,18 +1,18 @@ | ||||
| add_library( | ||||
| 	NostalgiaCore-Keel | ||||
| 	NostalgiaGfx-Keel | ||||
| 		keelmodule.cpp | ||||
| 		typeconv.cpp | ||||
| ) | ||||
| 
 | ||||
| target_link_libraries( | ||||
| 	NostalgiaCore-Keel PUBLIC | ||||
| 	NostalgiaGfx-Keel PUBLIC | ||||
| 		Keel | ||||
| 		NostalgiaCore | ||||
| 		NostalgiaGfx | ||||
| ) | ||||
| 
 | ||||
| install( | ||||
| 	TARGETS | ||||
| 		NostalgiaCore-Keel | ||||
| 		NostalgiaGfx-Keel | ||||
| 	DESTINATION | ||||
| 		LIBRARY DESTINATION lib | ||||
| 		ARCHIVE DESTINATION lib | ||||
| @@ -4,15 +4,14 @@ | ||||
| 
 | ||||
| #include <ox/model/model.hpp> | ||||
| 
 | ||||
| #include <keel/asset.hpp> | ||||
| #include <keel/module.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/palette.hpp> | ||||
| #include <nostalgia/core/tilesheet.hpp> | ||||
| #include <nostalgia/gfx/palette.hpp> | ||||
| #include <nostalgia/gfx/tilesheet.hpp> | ||||
| 
 | ||||
| #include "typeconv.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| static class: public keel::Module { | ||||
| 	private: | ||||
| @@ -20,16 +19,18 @@ static class: public keel::Module { | ||||
| 		PaletteV1ToPaletteV2Converter m_paletteV1ToPaletteV2Converter; | ||||
| 		PaletteV2ToPaletteV3Converter m_paletteV2ToPaletteV3Converter; | ||||
| 		PaletteV3ToPaletteV4Converter m_paletteV3ToPaletteV4Converter; | ||||
| 		PaletteV4ToPaletteV5Converter m_paletteV4ToPaletteV5Converter; | ||||
| 		PaletteToCompactPaletteConverter m_paletteToCompactPaletteConverter; | ||||
| 		TileSheetV1ToTileSheetV2Converter m_tileSheetV1ToTileSheetV2Converter; | ||||
| 		TileSheetV2ToTileSheetV3Converter m_tileSheetV2ToTileSheetV3Converter; | ||||
| 		TileSheetV3ToTileSheetV4Converter m_tileSheetV3ToTileSheetV4Converter; | ||||
| 		TileSheetV4ToTileSheetV5Converter m_tileSheetV4ToTileSheetV5Converter; | ||||
| 		TileSheetToCompactTileSheetConverter m_tileSheetToCompactTileSheetConverter; | ||||
| 
 | ||||
| 	public: | ||||
| 		[[nodiscard]] | ||||
| 		ox::String id() const noexcept override { | ||||
| 			return ox::String("net.drinkingtea.nostalgia.core"); | ||||
| 			return ox::String{"net.drinkingtea.nostalgia.gfx"}; | ||||
| 		} | ||||
| 
 | ||||
| 		[[nodiscard]] | ||||
| @@ -39,11 +40,13 @@ static class: public keel::Module { | ||||
| 				keel::generateTypeDesc<TileSheetV2>, | ||||
| 				keel::generateTypeDesc<TileSheetV3>, | ||||
| 				keel::generateTypeDesc<TileSheetV4>, | ||||
| 				keel::generateTypeDesc<TileSheetV5>, | ||||
| 				keel::generateTypeDesc<CompactTileSheetV1>, | ||||
| 				keel::generateTypeDesc<PaletteV1>, | ||||
| 				keel::generateTypeDesc<PaletteV2>, | ||||
| 				keel::generateTypeDesc<PaletteV3>, | ||||
| 				keel::generateTypeDesc<PaletteV4>, | ||||
| 				keel::generateTypeDesc<PaletteV5>, | ||||
| 				keel::generateTypeDesc<CompactPaletteV1>, | ||||
| 			}; | ||||
| 		} | ||||
| @@ -55,10 +58,12 @@ static class: public keel::Module { | ||||
| 				&m_paletteV1ToPaletteV2Converter, | ||||
| 				&m_paletteV2ToPaletteV3Converter, | ||||
| 				&m_paletteV3ToPaletteV4Converter, | ||||
| 				&m_paletteV4ToPaletteV5Converter, | ||||
| 				&m_paletteToCompactPaletteConverter, | ||||
| 				&m_tileSheetV1ToTileSheetV2Converter, | ||||
| 				&m_tileSheetV2ToTileSheetV3Converter, | ||||
| 				&m_tileSheetV3ToTileSheetV4Converter, | ||||
| 				&m_tileSheetV4ToTileSheetV5Converter, | ||||
| 				&m_tileSheetToCompactTileSheetConverter, | ||||
| 			}; | ||||
| 		} | ||||
| @@ -67,23 +72,25 @@ static class: public keel::Module { | ||||
| 		ox::Vector<keel::PackTransform> packTransforms() const noexcept final { | ||||
| 			return { | ||||
| 				// convert tilesheets to CompactTileSheets
 | ||||
| 				[](keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) -> ox::Result<bool> { | ||||
| 				[](keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) -> ox::Result<bool> { | ||||
| 					if (typeId == ox::ModelTypeId_v<TileSheetV1> || | ||||
| 					    typeId == ox::ModelTypeId_v<TileSheetV2> || | ||||
| 					    typeId == ox::ModelTypeId_v<TileSheetV3> || | ||||
| 					    typeId == ox::ModelTypeId_v<TileSheetV4>) { | ||||
| 					    typeId == ox::ModelTypeId_v<TileSheetV4> || | ||||
| 					    typeId == ox::ModelTypeId_v<TileSheetV5>) { | ||||
| 						OX_RETURN_ERROR(keel::convertBuffToBuff<CompactTileSheet>( | ||||
| 								ctx, buff, ox::ClawFormat::Metal).moveTo(buff)); | ||||
| 						return true; | ||||
| 					} | ||||
| 					return false; | ||||
| 				}, | ||||
| 				[](keel::Context &ctx, ox::Buffer &buff, ox::StringView typeId) -> ox::Result<bool> { | ||||
| 				[](keel::Context &ctx, ox::Buffer &buff, ox::StringViewCR typeId) -> ox::Result<bool> { | ||||
| 					if (typeId == ox::ModelTypeId_v<NostalgiaPalette> || | ||||
| 					    typeId == ox::ModelTypeId_v<PaletteV1> || | ||||
| 					    typeId == ox::ModelTypeId_v<PaletteV2> || | ||||
| 					    typeId == ox::ModelTypeId_v<PaletteV3> || | ||||
| 					    typeId == ox::ModelTypeId_v<PaletteV4>) { | ||||
| 					    typeId == ox::ModelTypeId_v<PaletteV4> || | ||||
| 					    typeId == ox::ModelTypeId_v<PaletteV5>) { | ||||
| 						OX_RETURN_ERROR(keel::convertBuffToBuff<CompactPalette>( | ||||
| 								ctx, buff, ox::ClawFormat::Metal).moveTo(buff)); | ||||
| 						return true; | ||||
| @@ -92,6 +99,7 @@ static class: public keel::Module { | ||||
| 				}, | ||||
| 			}; | ||||
| 		} | ||||
| 
 | ||||
| } const mod; | ||||
| 
 | ||||
| keel::Module const*keelModule() noexcept { | ||||
| @@ -4,7 +4,7 @@ | ||||
| 
 | ||||
| #include "typeconv.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| ox::Error NostalgiaPaletteToPaletteV1Converter::convert( | ||||
| 		keel::Context&, | ||||
| @@ -52,6 +52,26 @@ ox::Error PaletteV3ToPaletteV4Converter::convert( | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| ox::Error PaletteV4ToPaletteV5Converter::convert( | ||||
| 		keel::Context&, | ||||
| 		PaletteV4 &src, | ||||
| 		PaletteV5 &dst) const noexcept { | ||||
| 	dst.colorNames = std::move(src.colorNames); | ||||
| 	dst.pages.reserve(src.pages.size()); | ||||
| 	for (auto &s : src.pages) { | ||||
| 		ox::Vector<PaletteColorV2> colors; | ||||
| 		colors.reserve(s.colors.size()); | ||||
| 		for (auto const&c : s.colors) { | ||||
| 			colors.emplace_back(c.r, c.g, c.b, c.a); | ||||
| 		} | ||||
| 		dst.pages.emplace_back(PalettePageV2{ | ||||
| 			std::move(s.name), | ||||
| 			std::move(colors), | ||||
| 		}); | ||||
| 	} | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| ox::Error PaletteToCompactPaletteConverter::convert( | ||||
| 		keel::Context&, | ||||
| 		Palette &src, | ||||
| @@ -133,12 +153,50 @@ ox::Error TileSheetV3ToTileSheetV4Converter::convert( | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void TileSheetV4ToTileSheetV5Converter::convertSubsheet( | ||||
| 		int const bpp, | ||||
| 		TileSheetV4::SubSheet &src, | ||||
| 		TileSheetV5::SubSheet &dst) noexcept { | ||||
| 	dst.id      = src.id; | ||||
| 	dst.name    = std::move(src.name); | ||||
| 	dst.columns = src.columns; | ||||
| 	dst.rows    = src.rows; | ||||
| 	if (bpp == 4) { | ||||
| 		dst.pixels.reserve(2 * src.pixels.size()); | ||||
| 		dst.pixels.resize(0); | ||||
| 		for (auto const p : src.pixels) { | ||||
| 			dst.pixels.emplace_back(static_cast<uint8_t>(p & 0xf)); | ||||
| 			dst.pixels.emplace_back(static_cast<uint8_t>(p >> 4)); | ||||
| 		} | ||||
| 		oxAssert(dst.pixels.size() == src.pixels.size() *2, "mismatch"); | ||||
| 	} else { | ||||
| 		dst.pixels = std::move(src.pixels); | ||||
| 	} | ||||
| 	dst.subsheets.resize(src.subsheets.size()); | ||||
| 	for (auto i = 0u; i < src.subsheets.size(); ++i) { | ||||
| 		convertSubsheet(bpp, src.subsheets[i], dst.subsheets[i]); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| ox::Error TileSheetV4ToTileSheetV5Converter::convert( | ||||
| 		keel::Context&, | ||||
| 		TileSheetV4 &src, | ||||
| 		TileSheetV5 &dst) const noexcept { | ||||
| 	dst.bpp            = src.bpp; | ||||
| 	dst.idIt           = src.idIt; | ||||
| 	OX_RETURN_ERROR(src.defaultPalette.getPath().moveTo(dst.defaultPalette)); | ||||
| 	convertSubsheet(dst.bpp, src.subsheet, dst.subsheet); | ||||
| 	return {}; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| ox::Error TileSheetToCompactTileSheetConverter::convert( | ||||
| 		keel::Context&, | ||||
| 		TileSheet &src, | ||||
| 		CompactTileSheet &dst) const noexcept { | ||||
| 	dst.bpp            = src.bpp; | ||||
| 	dst.defaultPalette = std::move(src.defaultPalette); | ||||
| 	dst.defaultPalette = ox::FileAddress{src.defaultPalette}; | ||||
| 	dst.pixels         = pixels(src); | ||||
| 	return {}; | ||||
| } | ||||
| @@ -8,11 +8,11 @@ | ||||
| 
 | ||||
| #include <keel/typeconv.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/context.hpp> | ||||
| #include <nostalgia/core/palette.hpp> | ||||
| #include <nostalgia/core/tilesheet.hpp> | ||||
| #include <nostalgia/gfx/context.hpp> | ||||
| #include <nostalgia/gfx/palette.hpp> | ||||
| #include <nostalgia/gfx/tilesheet.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| // Type converters
 | ||||
| 
 | ||||
| @@ -32,6 +32,10 @@ class PaletteV3ToPaletteV4Converter: public keel::Converter<PaletteV3, PaletteV4 | ||||
| 	ox::Error convert(keel::Context&, PaletteV3 &src, PaletteV4 &dst) const noexcept final; | ||||
| }; | ||||
| 
 | ||||
| class PaletteV4ToPaletteV5Converter: public keel::Converter<PaletteV4, PaletteV5> { | ||||
| 	ox::Error convert(keel::Context&, PaletteV4 &src, PaletteV5 &dst) const noexcept final; | ||||
| }; | ||||
| 
 | ||||
| class PaletteToCompactPaletteConverter: public keel::Converter<Palette, CompactPalette> { | ||||
| 	ox::Error convert(keel::Context&, Palette &src, CompactPalette &dst) const noexcept final; | ||||
| }; | ||||
| @@ -56,6 +60,14 @@ class TileSheetV3ToTileSheetV4Converter: public keel::Converter<TileSheetV3, Til | ||||
| 	ox::Error convert(keel::Context&, TileSheetV3 &src, TileSheetV4 &dst) const noexcept final; | ||||
| }; | ||||
| 
 | ||||
| class TileSheetV4ToTileSheetV5Converter final: public keel::Converter<TileSheetV4, TileSheetV5> { | ||||
| 	static void convertSubsheet( | ||||
| 			int bpp, | ||||
| 			TileSheetV4::SubSheet &src, | ||||
| 			TileSheetV5::SubSheet &dst) noexcept; | ||||
| 	ox::Error convert(keel::Context&, TileSheetV4 &src, TileSheetV5 &dst) const noexcept override; | ||||
| }; | ||||
| 
 | ||||
| class TileSheetToCompactTileSheetConverter: public keel::Converter<TileSheet, CompactTileSheet> { | ||||
| 	ox::Error convert(keel::Context&, TileSheet &src, CompactTileSheet &dst) const noexcept final; | ||||
| }; | ||||
| @@ -1,9 +1,9 @@ | ||||
| target_sources( | ||||
| 	NostalgiaCore PRIVATE | ||||
| 	NostalgiaGfx PRIVATE | ||||
| 		context.cpp | ||||
| 		gfx.cpp | ||||
| ) | ||||
| target_link_libraries( | ||||
| 	NostalgiaCore PUBLIC | ||||
| 	NostalgiaGfx PUBLIC | ||||
| 		GlUtils | ||||
| ) | ||||
| @@ -5,10 +5,10 @@ | ||||
| #include "context.hpp" | ||||
| #include "gfx.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| void ContextDeleter::operator()(Context *p) noexcept { | ||||
| 	ox::safeDelete(p); | ||||
| void safeDelete(Context *ctx) noexcept { | ||||
| 	delete ctx; | ||||
| } | ||||
| 
 | ||||
| Context::Context(turbine::Context &tctx, InitParams const¶ms) noexcept: | ||||
| @@ -23,10 +23,10 @@ Context::~Context() noexcept { | ||||
| 	shutdownGfx(*this); | ||||
| } | ||||
| 
 | ||||
| ox::Result<ContextUPtr> init(turbine::Context &tctx, InitParams const¶ms) noexcept { | ||||
| ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const¶ms) noexcept { | ||||
| 	auto ctx = ox::make_unique<Context>(tctx, params); | ||||
| 	OX_RETURN_ERROR(initGfx(*ctx, params)); | ||||
| 	return ContextUPtr(ctx.release()); | ||||
| 	return ox::UPtr<Context>(ctx.release()); | ||||
| } | ||||
| 
 | ||||
| keel::Context &keelCtx(Context &ctx) noexcept { | ||||
| @@ -8,12 +8,12 @@ | ||||
| 
 | ||||
| #include <glutils/glutils.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/gfx.hpp> | ||||
| #include <nostalgia/core/context.hpp> | ||||
| #include <nostalgia/gfx/gfx.hpp> | ||||
| #include <nostalgia/gfx/context.hpp> | ||||
| 
 | ||||
| #include "gfx.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| class Context { | ||||
| 
 | ||||
| @@ -10,15 +10,15 @@ | ||||
| 
 | ||||
| #include <glutils/glutils.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/context.hpp> | ||||
| #include <nostalgia/core/gfx.hpp> | ||||
| #include <nostalgia/core/palette.hpp> | ||||
| #include <nostalgia/core/tilesheet.hpp> | ||||
| #include <nostalgia/gfx/context.hpp> | ||||
| #include <nostalgia/gfx/gfx.hpp> | ||||
| #include <nostalgia/gfx/palette.hpp> | ||||
| #include <nostalgia/gfx/tilesheet.hpp> | ||||
| 
 | ||||
| #include "context.hpp" | ||||
| #include "gfx.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| namespace renderer { | ||||
| 
 | ||||
| @@ -28,7 +28,7 @@ static constexpr auto PriorityScale = 0.01f; | ||||
| Drawer::Drawer(Context &ctx) noexcept: m_ctx(ctx) {} | ||||
| 
 | ||||
| void Drawer::draw(turbine::Context &tctx) noexcept { | ||||
| 	core::gl::draw(m_ctx, turbine::getScreenSize(tctx)); | ||||
| 	gfx::gl::draw(m_ctx, turbine::getScreenSize(tctx)); | ||||
| } | ||||
| 
 | ||||
| static constexpr ox::CStringView bgvshadTmpl = R"glsl( | ||||
| @@ -111,15 +111,15 @@ static constexpr auto bgVertexRow(uint_t x, uint_t y) noexcept { | ||||
| } | ||||
| 
 | ||||
| static void setSpriteBufferObject( | ||||
| 		uint_t vi, | ||||
| 		float enabled, | ||||
| 		uint_t const vi, | ||||
| 		float const enabled, | ||||
| 		float x, | ||||
| 		float y, | ||||
| 		uint_t textureRow, | ||||
| 		uint_t flipX, | ||||
| 		uint_t priority, | ||||
| 		float *vbo, | ||||
| 		GLuint *ebo) noexcept { | ||||
| 		uint_t const textureRow, | ||||
| 		uint_t const flipX, | ||||
| 		uint_t const priority, | ||||
| 		ox::Span<float> const vbo, | ||||
| 		ox::Span<GLuint> const ebo) noexcept { | ||||
| 	// don't worry, this memcpy gets optimized to something much more ideal
 | ||||
| 	constexpr float xmod = 0.1f; | ||||
| 	constexpr float ymod = 0.1f; | ||||
| @@ -138,25 +138,25 @@ static void setSpriteBufferObject( | ||||
| 	    enabled, x + xmod, y + ymod, prif, R, textureRowf + 0, // top right
 | ||||
| 	    enabled,        x, y + ymod, prif, L, textureRowf + 0, // top left
 | ||||
| 	}; | ||||
| 	memcpy(vbo, vertices.data(), sizeof(vertices)); | ||||
| 	ox::spancpy<float>(vbo, vertices); | ||||
| 	ox::Array<GLuint, SpriteVertexEboLength> const elms { | ||||
| 		vi + 0, vi + 1, vi + 2, | ||||
| 		vi + 2, vi + 3, vi + 0, | ||||
| 	}; | ||||
| 	memcpy(ebo, elms.data(), sizeof(elms)); | ||||
| 	ox::spancpy<GLuint>(ebo, elms); | ||||
| } | ||||
| 
 | ||||
| static void setTileBufferObject( | ||||
| 		uint_t vi, | ||||
| 		uint_t const vi, | ||||
| 		float x, | ||||
| 		float y, | ||||
| 		float textureTileIdx, | ||||
| 		float priority, | ||||
| 		float palOffset, | ||||
| 		bool flipX, | ||||
| 		bool flipY, | ||||
| 		float *vbo, | ||||
| 		GLuint *ebo) noexcept { | ||||
| 		float const textureTileIdx, | ||||
| 		float const priority, | ||||
| 		float const palOffset, | ||||
| 		bool const flipX, | ||||
| 		bool const flipY, | ||||
| 		ox::Span<float> const vbo, | ||||
| 		ox::Span<GLuint> const ebo) noexcept { | ||||
| 	// don't worry, this memcpy gets optimized to something much more ideal
 | ||||
| 	constexpr float ymod = 0.1f; | ||||
| 	constexpr float xmod = 0.1f; | ||||
| @@ -175,19 +175,30 @@ static void setTileBufferObject( | ||||
| 		x + xmod, y + ymod, prif, R, T, textureTileIdx, palOffset, // top right
 | ||||
| 		       x, y + ymod, prif, L, T, textureTileIdx, palOffset, // top left
 | ||||
| 	}; | ||||
| 	memcpy(vbo, vertices.data(), sizeof(vertices)); | ||||
| 	ox::spancpy<float>(vbo, vertices); | ||||
| 	ox::Array<GLuint, BgVertexEboLength> const elms { | ||||
| 		vi + 0, vi + 1, vi + 2, | ||||
| 		vi + 2, vi + 3, vi + 0, | ||||
| 	}; | ||||
| 	memcpy(ebo, elms.data(), sizeof(elms)); | ||||
| 	ox::spancpy<GLuint>(ebo, elms); | ||||
| } | ||||
| 
 | ||||
| static void initSpriteBufferObjects(Context &ctx, glutils::BufferSet &bs) noexcept { | ||||
| 	for (auto i = 0u; i < ctx.spriteCount; ++i) { | ||||
| 		auto vbo = &bs.vertices[i * static_cast<std::size_t>(SpriteVertexVboLength)]; | ||||
| 		auto ebo = &bs.elements[i * static_cast<std::size_t>(SpriteVertexEboLength)]; | ||||
| 		setSpriteBufferObject(i * static_cast<uint_t>(SpriteVertexVboRows) * ctx.blocksPerSprite, 0, 0, 0, 0, false, 0, vbo, ebo); | ||||
| 		auto const vbo = ox::Span{bs.vertices} | ||||
| 			+ i * static_cast<std::size_t>(SpriteVertexVboLength); | ||||
| 		auto const ebo = ox::Span{bs.elements} | ||||
| 			+ i * static_cast<std::size_t>(SpriteVertexEboLength); | ||||
| 		setSpriteBufferObject( | ||||
| 			i * static_cast<uint_t>(SpriteVertexVboRows) * ctx.blocksPerSprite, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			0, | ||||
| 			false, | ||||
| 			0, | ||||
| 			vbo, | ||||
| 			ebo); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @@ -195,8 +206,10 @@ static void initBackgroundBufferObjects(glutils::BufferSet &bs) noexcept { | ||||
| 	for (auto x = 0u; x < TileColumns; ++x) { | ||||
| 		for (auto y = 0u; y < TileRows; ++y) { | ||||
| 			const auto i = bgVertexRow(x, y); | ||||
| 			auto vbo = &bs.vertices[i * static_cast<std::size_t>(BgVertexVboLength)]; | ||||
| 			auto ebo = &bs.elements[i * static_cast<std::size_t>(BgVertexEboLength)]; | ||||
| 			auto const vbo = ox::Span{bs.vertices} | ||||
| 				+ i * static_cast<std::size_t>(BgVertexVboLength); | ||||
| 			auto const ebo = ox::Span{bs.elements} | ||||
| 				+ i * static_cast<std::size_t>(BgVertexEboLength); | ||||
| 			setTileBufferObject( | ||||
| 				static_cast<uint_t>(i * BgVertexVboRows), | ||||
| 				static_cast<float>(x), | ||||
| @@ -421,8 +434,8 @@ static void setSprite( | ||||
| 		auto const eboIdx = eboBase + renderer::SpriteVertexEboLength * i; | ||||
| 		oxAssert(vboIdx < ctx.spriteBlocks.vertices.size(), "vbo overflow"); | ||||
| 		oxAssert(eboIdx < ctx.spriteBlocks.elements.size(), "ebo overflow"); | ||||
| 		auto const vbo = &ctx.spriteBlocks.vertices[vboIdx]; | ||||
| 		auto const ebo = &ctx.spriteBlocks.elements[eboIdx]; | ||||
| 		auto const vbo = ox::Span{ctx.spriteBlocks.vertices} + vboIdx; | ||||
| 		auto const ebo = ox::Span{ctx.spriteBlocks.elements} + eboIdx; | ||||
| 		renderer::setSpriteBufferObject( | ||||
| 				static_cast<uint_t>(vboIdx), | ||||
| 				enabled, | ||||
| @@ -436,7 +449,7 @@ static void setSprite( | ||||
| 		++i; | ||||
| 	}; | ||||
| 	if (!s.flipX) { | ||||
| 		for (auto yIt = 0; yIt < static_cast<int>(dim.y); ++yIt) { | ||||
| 		for (auto yIt = 0u; yIt < dim.y; ++yIt) { | ||||
| 			for (auto xIt = 0u; xIt < dim.x; ++xIt) { | ||||
| 				set(static_cast<int>(xIt), static_cast<int>(yIt), s.enabled); | ||||
| 			} | ||||
| @@ -556,7 +569,7 @@ static void copyPixels( | ||||
| 		CompactTileSheet const&ts, | ||||
| 		ox::Span<uint32_t> dst, | ||||
| 		size_t const srcPxIdx, | ||||
| 		size_t pxlCnt) noexcept { | ||||
| 		size_t const pxlCnt) noexcept { | ||||
| 	size_t idx{}; | ||||
| 	if (ts.bpp == 4) { | ||||
| 		for (size_t i = 0; i < pxlCnt; i += 2) { | ||||
| @@ -573,6 +586,18 @@ static void copyPixels( | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void clearCbb(Context &ctx, unsigned const cbb) noexcept { | ||||
| 	for (auto &v : ctx.cbbs[cbb].pixels) { | ||||
| 		v = 0; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void clearCbbs(Context &ctx) noexcept { | ||||
| 	for (unsigned i = 0 ; i < ctx.cbbs.size(); ++i) { | ||||
| 		clearCbb(ctx, i); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| ox::Error loadBgTileSheet( | ||||
| 		Context &ctx, | ||||
| 		unsigned const cbb, | ||||
| @@ -625,7 +650,7 @@ ox::Error loadSpriteTileSheet( | ||||
| 		CompactTileSheet const&ts, | ||||
| 		bool loadDefaultPalette) noexcept { | ||||
| 	OX_REQUIRE(tsd, normalizeTileSheet(ts)); | ||||
| 	oxTracef("nostalgia.core.gfx.gl", "loadSpriteTexture: { w: {}, h: {} }", tsd.width, tsd.height); | ||||
| 	oxTracef("nostalgia.gfx.gl", "loadSpriteTexture: { w: {}, h: {} }", tsd.width, tsd.height); | ||||
| 	ctx.spriteBlocks.tex = renderer::createTexture(tsd.width, tsd.height, tsd.pixels.data()); | ||||
| 	if (loadDefaultPalette) { | ||||
| 		OX_RETURN_ERROR(loadSpritePalette(ctx, ts.defaultPalette)); | ||||
| @@ -648,7 +673,7 @@ void setBgTile( | ||||
| 		int row, | ||||
| 		BgTile const&tile) noexcept { | ||||
| 	oxTracef( | ||||
| 			"nostalgia.core.gfx.setBgTile", | ||||
| 			"nostalgia.gfx.setBgTile", | ||||
| 			"bgIdx: {}, column: {}, row: {}, tile: {}, palBank: {}", | ||||
| 			bgIdx, column, row, tile.tileIdx, tile.palBank); | ||||
| 	const auto z = static_cast<uint_t>(bgIdx); | ||||
| @@ -656,8 +681,8 @@ void setBgTile( | ||||
| 	const auto x = static_cast<uint_t>(column); | ||||
| 	const auto i = renderer::bgVertexRow(x, y); | ||||
| 	auto &cbb = ctx.cbbs[z]; | ||||
| 	const auto vbo = &cbb.vertices[i * renderer::BgVertexVboLength]; | ||||
| 	const auto ebo = &cbb.elements[i * renderer::BgVertexEboLength]; | ||||
| 	const auto vbo = ox::Span{cbb.vertices} + i * renderer::BgVertexVboLength; | ||||
| 	const auto ebo = ox::Span{cbb.elements} + i * renderer::BgVertexEboLength; | ||||
| 	auto &bg = ctx.backgrounds[bgIdx]; | ||||
| 	renderer::setTileBufferObject( | ||||
| 			static_cast<uint_t>(i * renderer::BgVertexVboRows), | ||||
| @@ -743,7 +768,7 @@ ox::Size drawSize(int scale) noexcept { | ||||
| 	return {240 * scale, 160 * scale}; | ||||
| } | ||||
| 
 | ||||
| void draw(core::Context &ctx, ox::Size const&renderSz) noexcept { | ||||
| void draw(gfx::Context &ctx, ox::Size const&renderSz) noexcept { | ||||
| 	glViewport(0, 0, renderSz.width, renderSz.height); | ||||
| 	glEnable(GL_DEPTH_TEST); | ||||
| 	glEnable(GL_BLEND); | ||||
| @@ -758,7 +783,7 @@ void draw(core::Context &ctx, ox::Size const&renderSz) noexcept { | ||||
| 	glDisable(GL_BLEND); | ||||
| } | ||||
| 
 | ||||
| void draw(core::Context &ctx, int scale) noexcept { | ||||
| void draw(gfx::Context &ctx, int scale) noexcept { | ||||
| 	draw(ctx, drawSize(scale)); | ||||
| } | ||||
| 
 | ||||
| @@ -10,9 +10,9 @@ | ||||
| 
 | ||||
| #include <glutils/glutils.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/context.hpp> | ||||
| #include <nostalgia/gfx/context.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core::renderer { | ||||
| namespace nostalgia::gfx::renderer { | ||||
| 
 | ||||
| constexpr uint64_t TileRows = 128; | ||||
| constexpr uint64_t TileColumns = 128; | ||||
| @@ -59,7 +59,7 @@ class Drawer: public turbine::gl::Drawer { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| ox::Error initGfx(Context &ctx, InitParams const&) noexcept; | ||||
| void shutdownGfx(Context &ctx) noexcept; | ||||
| } | ||||
							
								
								
									
										28
									
								
								src/nostalgia/modules/gfx/src/studio/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/nostalgia/modules/gfx/src/studio/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| add_library(NostalgiaGfx-Studio) | ||||
|  | ||||
| add_library( | ||||
| 	NostalgiaGfx-Studio-ImGui | ||||
| 		studiomodule.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries( | ||||
| 	NostalgiaGfx-Studio PUBLIC | ||||
| 		NostalgiaGfx | ||||
| 		Studio | ||||
| ) | ||||
|  | ||||
| target_link_libraries( | ||||
| 	NostalgiaGfx-Studio-ImGui PUBLIC | ||||
| 		NostalgiaGfx-Studio | ||||
| ) | ||||
|  | ||||
| install( | ||||
| 	TARGETS | ||||
| 		NostalgiaGfx-Studio-ImGui | ||||
| 		NostalgiaGfx-Studio | ||||
| 	LIBRARY DESTINATION | ||||
| 		${NOSTALGIA_DIST_MODULE} | ||||
| ) | ||||
|  | ||||
| add_subdirectory(paletteeditor) | ||||
| add_subdirectory(tilesheeteditor) | ||||
| @@ -0,0 +1,6 @@ | ||||
| target_sources( | ||||
| 	NostalgiaGfx-Studio-ImGui PRIVATE | ||||
| 		paletteeditor-imgui.cpp | ||||
| ) | ||||
|  | ||||
| add_subdirectory(commands) | ||||
| @@ -0,0 +1,15 @@ | ||||
|  | ||||
| target_sources( | ||||
|     NostalgiaGfx-Studio PRIVATE | ||||
|         addcolorcommand.cpp | ||||
|         addpagecommand.cpp | ||||
|         applycolorallpagescommand.cpp | ||||
|         duplicatepagecommand.cpp | ||||
|         movecolorcommand.cpp | ||||
|         movepagecommand.cpp | ||||
|         removecolorcommand.cpp | ||||
|         removepagecommand.cpp | ||||
|         renamepagecommand.cpp | ||||
|         updatecolorcommand.cpp | ||||
|         updatecolorinfocommand.cpp | ||||
| ) | ||||
| @@ -5,7 +5,7 @@ | ||||
| #include "commands.hpp" | ||||
| #include "addcolorcommand.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| AddColorCommand::AddColorCommand(Palette &pal, Color16 const color, size_t const idx) noexcept: | ||||
| 	m_pal(pal), | ||||
| @@ -6,9 +6,9 @@ | ||||
| 
 | ||||
| #include <studio/studio.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/palette.hpp> | ||||
| #include <nostalgia/gfx/palette.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| class AddColorCommand: public studio::UndoCommand { | ||||
| 	private: | ||||
| @@ -6,7 +6,7 @@ | ||||
| 
 | ||||
| #include "addpagecommand.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| AddPageCommand::AddPageCommand(Palette &pal) noexcept: | ||||
| 		m_pal(pal) {} | ||||
| @@ -6,9 +6,9 @@ | ||||
| 
 | ||||
| #include <studio/studio.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/palette.hpp> | ||||
| #include <nostalgia/gfx/palette.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| class AddPageCommand: public studio::UndoCommand { | ||||
| 	private: | ||||
| @@ -5,7 +5,7 @@ | ||||
| #include "commands.hpp" | ||||
| #include "applycolorallpagescommand.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| ApplyColorAllPagesCommand::ApplyColorAllPagesCommand(Palette &pal, size_t const page, size_t const idx): | ||||
| 	m_pal(pal), | ||||
| @@ -6,9 +6,9 @@ | ||||
| 
 | ||||
| #include <studio/studio.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/palette.hpp> | ||||
| #include <nostalgia/gfx/palette.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| class ApplyColorAllPagesCommand: public studio::UndoCommand { | ||||
| 	private: | ||||
| @@ -4,7 +4,7 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| enum class PaletteEditorCommandId { | ||||
| 	ApplyColorAllPages, | ||||
| @@ -12,6 +12,7 @@ enum class PaletteEditorCommandId { | ||||
| 	AddPage, | ||||
| 	DuplicatePage, | ||||
| 	RemovePage, | ||||
| 	MovePage, | ||||
| 	AddColor, | ||||
| 	RemoveColor, | ||||
| 	UpdateColorInfo, | ||||
| @@ -6,7 +6,7 @@ | ||||
| 
 | ||||
| #include "duplicatepagecommand.hpp" | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| DuplicatePageCommand::DuplicatePageCommand(Palette &pal, size_t srcIdx, size_t dstIdx) noexcept: | ||||
| 		m_pal(pal), | ||||
| @@ -6,9 +6,9 @@ | ||||
| 
 | ||||
| #include <studio/studio.hpp> | ||||
| 
 | ||||
| #include <nostalgia/core/palette.hpp> | ||||
| #include <nostalgia/gfx/palette.hpp> | ||||
| 
 | ||||
| namespace nostalgia::core { | ||||
| namespace nostalgia::gfx { | ||||
| 
 | ||||
| class DuplicatePageCommand: public studio::UndoCommand { | ||||
| 	private: | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user