Compare commits
216 Commits
release-d2
...
release-d2
Author | SHA1 | Date | |
---|---|---|---|
13e256b3a9 | |||
6bd74611cd | |||
c3f9cf9a64 | |||
646ab1283f | |||
74cf055610 | |||
0d8ba1b154 | |||
20edbb7f38 | |||
6febc7cc73 | |||
b94d6b5061 | |||
b3952cabbc | |||
2ffc11b04e | |||
96cace2cbb | |||
472f5702bd | |||
c0ac4345d3 | |||
fbebf4ef83 | |||
20513f7749 | |||
25a7873ea2 | |||
d0a32e247e | |||
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:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: nostalgia
|
runs-on: olympic
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@ -17,3 +17,10 @@ jobs:
|
|||||||
- run: make purge configure-release
|
- run: make purge configure-release
|
||||||
- run: make build
|
- run: make build
|
||||||
- run: make test
|
- run: make test
|
||||||
|
- run: make install
|
||||||
|
- run: mv dist/linux-x86_64-release nostalgia-linux-x86_64
|
||||||
|
- run: tar cf nostalgia-linux-x86_64.tar nostalgia-linux-x86_64
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: nostalgia-linux-x86_64
|
||||||
|
path: nostalgia-linux-x86_64.tar
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,7 +6,7 @@
|
|||||||
.mypy_cache
|
.mypy_cache
|
||||||
.stfolder
|
.stfolder
|
||||||
.stignore
|
.stignore
|
||||||
scripts/__pycache__
|
util/scripts/__pycache__
|
||||||
pyenv
|
pyenv
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
ROM.oxfs
|
ROM.oxfs
|
||||||
|
19
Makefile
19
Makefile
@ -1,26 +1,31 @@
|
|||||||
BC_VAR_PROJECT_NAME=nostalgia
|
BC_VAR_PROJECT_NAME=nostalgia
|
||||||
BC_VAR_PROJECT_NAME_CAP=Nostalgia
|
BC_VAR_PROJECT_NAME_CAP=Nostalgia
|
||||||
|
BC_VAR_DEVENV_ROOT=util
|
||||||
BUILDCORE_PATH=deps/buildcore
|
BUILDCORE_PATH=deps/buildcore
|
||||||
include ${BUILDCORE_PATH}/base.mk
|
include ${BUILDCORE_PATH}/base.mk
|
||||||
|
|
||||||
ifeq ($(BC_VAR_OS),darwin)
|
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
|
MGBA=/Applications/mGBA.app/Contents/MacOS/mGBA
|
||||||
else
|
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
|
MGBA=mgba-qt
|
||||||
endif
|
endif
|
||||||
|
PROJECT_PLAYER=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}
|
||||||
|
|
||||||
.PHONY: pkg-gba
|
.PHONY: pkg-gba
|
||||||
pkg-gba: build
|
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
|
.PHONY: run
|
||||||
run: build
|
run: build-player
|
||||||
./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME} sample_project
|
${PROJECT_PLAYER} sample_project
|
||||||
.PHONY: run-studio
|
.PHONY: run-studio
|
||||||
run-studio: build
|
run-studio: build
|
||||||
${NOSTALGIA_STUDIO}
|
${PROJECT_STUDIO}
|
||||||
.PHONY: gba-run
|
.PHONY: gba-run
|
||||||
gba-run: pkg-gba
|
gba-run: pkg-gba
|
||||||
${MGBA} ${BC_VAR_PROJECT_NAME}.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
|
${BC_CMD_HOST_DEBUGGER} ./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME} sample_project
|
||||||
.PHONY: debug-studio
|
.PHONY: debug-studio
|
||||||
debug-studio: build
|
debug-studio: build
|
||||||
${BC_CMD_HOST_DEBUGGER} ${NOSTALGIA_STUDIO}
|
${BC_CMD_HOST_DEBUGGER} ${PROJECT_STUDIO}
|
||||||
|
|
||||||
.PHONY: configure-gba
|
.PHONY: configure-gba
|
||||||
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
|
${BC_CMD_RM_RF} compile_commands.json
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: build
|
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
|
${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} test
|
||||||
.PHONY: test-verbose
|
.PHONY: test-verbose
|
||||||
test-verbose: build
|
test-verbose: build
|
||||||
|
2
deps/buildcore/scripts/util.py
vendored
2
deps/buildcore/scripts/util.py
vendored
@ -35,4 +35,6 @@ def get_arch() -> str:
|
|||||||
arch = platform.machine().lower()
|
arch = platform.machine().lower()
|
||||||
if arch == 'amd64':
|
if arch == 'amd64':
|
||||||
arch = 'x86_64'
|
arch = 'x86_64'
|
||||||
|
elif arch == 'aarch64':
|
||||||
|
arch = 'arm64'
|
||||||
return arch
|
return arch
|
||||||
|
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)
|
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} -nostdlib")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++")
|
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-unwind-tables")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
|
#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-rtti")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb-interwork")
|
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)
|
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
|
# DrinkingTea: end
|
||||||
|
|
||||||
add_library(
|
add_library(
|
||||||
imgui OBJECT
|
imgui
|
||||||
imgui.cpp
|
imgui.cpp
|
||||||
imgui_demo.cpp
|
imgui_demo.cpp
|
||||||
imgui_draw.cpp
|
imgui_draw.cpp
|
||||||
@ -20,3 +20,11 @@ target_include_directories(
|
|||||||
imgui SYSTEM PUBLIC
|
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)
|
project(nativefiledialog-extended VERSION 1.1.1)
|
||||||
|
|
||||||
set(nfd_ROOT_PROJECT OFF)
|
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
|
# 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:"
|
# 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")
|
set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.2")
|
||||||
cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION})
|
cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION})
|
||||||
if("${CMAKE_VERSION}" VERSION_LESS "${JSONCPP_NEWEST_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;
|
Error disconnectObject(const void *receiver) const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
size_t connectionCnt() const noexcept {
|
||||||
|
return m_slots.size();
|
||||||
|
}
|
||||||
|
|
||||||
void emit(Args... args) const;
|
void emit(Args... args) const;
|
||||||
|
|
||||||
Error emitCheckError(Args... args) const noexcept;
|
Error emitCheckError(Args... args) const noexcept;
|
||||||
@ -215,7 +220,7 @@ Error Signal<Args...>::emitCheckError(Args... args) const noexcept {
|
|||||||
}
|
}
|
||||||
return ox::Error(0);
|
return ox::Error(0);
|
||||||
} catch (const ox::Exception &ex) {
|
} 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;
|
Error disconnectObject(const void *receiver) const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
size_t connectionCnt() const noexcept {
|
||||||
|
return m_slots.size();
|
||||||
|
}
|
||||||
|
|
||||||
void emit(Args... args) const noexcept;
|
void emit(Args... args) const noexcept;
|
||||||
|
|
||||||
Error emitCheckError(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 {
|
Result<Buffer> FileSystem::read(const FileAddress &addr) noexcept {
|
||||||
OX_REQUIRE(s, stat(addr));
|
OX_REQUIRE(s, stat(addr));
|
||||||
Buffer buff(static_cast<std::size_t>(s.size));
|
Buffer buff(static_cast<std::size_t>(s.size));
|
||||||
@ -51,28 +75,31 @@ Result<Buffer> FileSystem::read(StringViewCR path) noexcept {
|
|||||||
return buff;
|
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()) {
|
switch (addr.type()) {
|
||||||
case FileAddressType::Inode:
|
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::ConstPath:
|
||||||
case FileAddressType::Path:
|
case FileAddressType::Path:
|
||||||
return ox::Error(2, "Unsupported for path lookups");
|
return readFilePathRange(addr.getPath().value, readStart, readSize, buffer, size);
|
||||||
default:
|
default:
|
||||||
return ox::Error(1);
|
return ox::Error(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Error FileSystem::remove(const FileAddress &addr, bool recursive) noexcept {
|
Result<size_t> FileSystem::read(
|
||||||
switch (addr.type()) {
|
StringViewCR path,
|
||||||
case FileAddressType::Inode:
|
std::size_t const readStart,
|
||||||
return remove(addr.getInode().value, recursive);
|
std::size_t const readSize,
|
||||||
case FileAddressType::ConstPath:
|
Span<char> buff) noexcept {
|
||||||
case FileAddressType::Path:
|
size_t szOut{buff.size()};
|
||||||
return remove(StringView(addr.getPath().value), recursive);
|
OX_RETURN_ERROR(readFilePathRange(path, readStart, readSize, buff.data(), &szOut));
|
||||||
default:
|
return szOut;
|
||||||
return ox::Error(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType) noexcept {
|
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;
|
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(const FileAddress &addr) noexcept;
|
||||||
|
|
||||||
Result<Buffer> read(StringViewCR path) noexcept;
|
Result<Buffer> read(StringViewCR path) noexcept;
|
||||||
@ -53,13 +57,30 @@ class FileSystem {
|
|||||||
return readFileInode(inode, buffer, buffSize);
|
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 Result<Vector<String>> ls(StringViewCR dir) const noexcept = 0;
|
||||||
|
|
||||||
virtual Error remove(StringViewCR path, bool recursive) noexcept = 0;
|
Error remove(StringViewCR path, bool recursive = false) noexcept {
|
||||||
|
return removePath(path, recursive);
|
||||||
Error remove(const FileAddress &addr, bool recursive = false) noexcept;
|
}
|
||||||
|
|
||||||
virtual Error resize(uint64_t size, void *buffer) noexcept = 0;
|
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 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;
|
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 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<const char*> directAccessInode(uint64_t) const noexcept override;
|
||||||
|
|
||||||
Result<Vector<String>> ls(StringViewCR dir) const noexcept override;
|
Result<Vector<String>> ls(StringViewCR dir) const noexcept override;
|
||||||
@ -216,8 +247,6 @@ class FileSystemTemplate: public MemFS {
|
|||||||
template<typename F>
|
template<typename F>
|
||||||
Error ls(StringViewCR path, F cb) const;
|
Error ls(StringViewCR path, F cb) const;
|
||||||
|
|
||||||
Error remove(StringViewCR path, bool recursive) noexcept override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resizes FileSystem to minimum possible size.
|
* 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);
|
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>
|
template<typename FileStore, typename Directory>
|
||||||
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(uint64_t inode) const noexcept {
|
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(uint64_t inode) const noexcept {
|
||||||
auto data = m_fs.read(inode);
|
auto data = m_fs.read(inode);
|
||||||
@ -384,25 +439,6 @@ Error FileSystemTemplate<FileStore, Directory>::ls(StringViewCR path, F cb) cons
|
|||||||
return dir.ls(cb);
|
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>
|
template<typename FileStore, typename Directory>
|
||||||
Error FileSystemTemplate<FileStore, Directory>::resize() noexcept {
|
Error FileSystemTemplate<FileStore, Directory>::resize() noexcept {
|
||||||
return m_fs.resize();
|
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;
|
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 {
|
Error PassThroughFS::resize(uint64_t, void*) noexcept {
|
||||||
// unsupported
|
// unsupported
|
||||||
return ox::Error(1, "resize is not supported by PassThroughFS");
|
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);
|
oxTracef("ox.fs.PassThroughFS.statInode", "{} {}", ec.message(), path);
|
||||||
const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec);
|
const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec);
|
||||||
oxTracef("ox.fs.PassThroughFS.statInode.size", "{} {}", path, size);
|
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};
|
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");
|
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 {
|
Error PassThroughFS::readFileInodeRange(uint64_t, std::size_t, std::size_t, void*, std::size_t*) noexcept {
|
||||||
// unsupported
|
// unsupported
|
||||||
return ox::Error(1, "read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) is not supported by PassThroughFS");
|
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 {
|
Error PassThroughFS::writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType) noexcept {
|
||||||
const auto p = (m_path / stripSlash(path));
|
const auto p = (m_path / stripSlash(path));
|
||||||
try {
|
try {
|
||||||
@ -185,8 +206,7 @@ Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) n
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string_view PassThroughFS::stripSlash(StringView path) noexcept {
|
std::string_view PassThroughFS::stripSlash(StringView path) noexcept {
|
||||||
const auto pathLen = ox::strlen(path);
|
for (auto i = 0u; i < path.len() && path[0] == '/'; i++) {
|
||||||
for (auto i = 0u; i < pathLen && path[0] == '/'; i++) {
|
|
||||||
path = substr(path, 1);
|
path = substr(path, 1);
|
||||||
}
|
}
|
||||||
return {path.data(), path.bytes()};
|
return {path.data(), path.bytes()};
|
||||||
|
@ -45,8 +45,6 @@ class PassThroughFS: public FileSystem {
|
|||||||
template<typename F>
|
template<typename F>
|
||||||
Error ls(StringViewCR dir, F cb) const noexcept;
|
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;
|
Error resize(uint64_t size, void *buffer) noexcept override;
|
||||||
|
|
||||||
Result<FileStat> statInode(uint64_t inode) const 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 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 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 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;
|
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); \
|
const auto loggerErr = (loggerName).initConn(appName); \
|
||||||
if (loggerErr) { \
|
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 { \
|
} else { \
|
||||||
ox::trace::setLogger(&(loggerName)); \
|
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;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename Str = const char*>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
consteval auto requireModelTypeName() noexcept {
|
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");
|
static_assert(ox::StringView{name}.len(), "Type lacks required TypeName");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Str = const char*>
|
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*>
|
template<typename T, typename Str = const char*>
|
||||||
constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();
|
constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();
|
||||||
|
6
deps/ox/src/ox/model/typestore.hpp
vendored
6
deps/ox/src/ox/model/typestore.hpp
vendored
@ -58,7 +58,11 @@ class TypeStore {
|
|||||||
if (!std::is_constant_evaluated()) {
|
if (!std::is_constant_evaluated()) {
|
||||||
OX_REQUIRE_M(dt, loadDescriptor(typeId));
|
OX_REQUIRE_M(dt, loadDescriptor(typeId));
|
||||||
for (auto &f : dt->fieldList) {
|
for (auto &f : dt->fieldList) {
|
||||||
OX_RETURN_ERROR(this->getLoad(f.typeId).moveTo(f.type));
|
if (typeId == f.typeId) {
|
||||||
|
f.type = dt.get();
|
||||||
|
} else {
|
||||||
|
OX_RETURN_ERROR(this->getLoad(f.typeId).moveTo(f.type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
auto &out = m_cache[typeId];
|
auto &out = m_cache[typeId];
|
||||||
out = std::move(dt);
|
out = std::move(dt);
|
||||||
|
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()) {
|
if (jv.empty()) {
|
||||||
*val = 0;
|
*val = 0;
|
||||||
} else if (rightType) {
|
} 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 {
|
} else {
|
||||||
err = ox::Error(1, "Type mismatch");
|
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");
|
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");
|
err = ox::Error(1, "error reading JSON data");
|
||||||
}
|
}
|
||||||
++m_fieldIt;
|
++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
|
#pragma once
|
||||||
|
|
||||||
#include "def.hpp"
|
#include "def.hpp"
|
||||||
|
#include "error.hpp"
|
||||||
|
|
||||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
template<typename It, typename T>
|
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) {
|
for (; begin != end; ++begin) {
|
||||||
if (*begin == value) {
|
if (*begin == value) {
|
||||||
return begin;
|
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 {
|
namespace ox {
|
||||||
|
|
||||||
class AnyPtr {
|
namespace detail {
|
||||||
|
|
||||||
|
template<bool unique>
|
||||||
|
class AnyPtrT {
|
||||||
private:
|
private:
|
||||||
struct WrapBase {
|
struct WrapBase {
|
||||||
virtual constexpr ~WrapBase() = default;
|
virtual constexpr ~WrapBase() = default;
|
||||||
virtual constexpr WrapBase *copyTo(ox::Span<char> s) noexcept = 0;
|
virtual constexpr WrapBase *copyTo(ox::Span<char> s) noexcept = 0;
|
||||||
virtual constexpr operator bool() const noexcept = 0;
|
virtual constexpr operator bool() const noexcept = 0;
|
||||||
|
virtual void free() noexcept = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Wrap: public WrapBase {
|
struct Wrap final: WrapBase {
|
||||||
T *data{};
|
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 {
|
constexpr WrapBase *copyTo(ox::Span<char> s) noexcept override {
|
||||||
oxAssert(s.size() >= sizeof(Wrap), "too small buffer");
|
oxAssert(s.size() >= sizeof(Wrap), "too small buffer");
|
||||||
@ -39,39 +43,60 @@ class AnyPtr {
|
|||||||
constexpr operator bool() const noexcept override {
|
constexpr operator bool() const noexcept override {
|
||||||
return data != nullptr;
|
return data != nullptr;
|
||||||
}
|
}
|
||||||
|
constexpr void free() noexcept override {
|
||||||
|
safeDelete(data);
|
||||||
|
data = {};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
WrapBase *m_wrapPtr{};
|
WrapBase *m_wrapPtr{};
|
||||||
ox::Array<char, sizeof(Wrap<void*>)> m_wrapData;
|
ox::Array<char, sizeof(Wrap<void*>)> m_wrapData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr AnyPtr() noexcept = default;
|
constexpr AnyPtrT() noexcept = default;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr AnyPtr(T *ptr) noexcept {
|
constexpr AnyPtrT(T *ptr) noexcept {
|
||||||
if (std::is_constant_evaluated()) {
|
if (std::is_constant_evaluated()) {
|
||||||
m_wrapPtr = new Wrap(ptr);
|
m_wrapPtr = new Wrap<T>(ptr);
|
||||||
} else {
|
} 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) {
|
if (other) {
|
||||||
m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData);
|
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()) {
|
if (std::is_constant_evaluated()) {
|
||||||
ox::safeDelete(m_wrapPtr);
|
ox::safeDelete(m_wrapPtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr AnyPtr &operator=(T *ptr) noexcept {
|
constexpr AnyPtrT &operator=(T *ptr) noexcept {
|
||||||
if (std::is_constant_evaluated()) {
|
if constexpr(unique) {
|
||||||
|
free();
|
||||||
|
} else if (std::is_constant_evaluated()) {
|
||||||
ox::safeDelete(m_wrapPtr);
|
ox::safeDelete(m_wrapPtr);
|
||||||
|
}
|
||||||
|
if (std::is_constant_evaluated()) {
|
||||||
m_wrapPtr = new Wrap(ptr);
|
m_wrapPtr = new Wrap(ptr);
|
||||||
} else {
|
} else {
|
||||||
m_wrapPtr = new(m_wrapData.data()) Wrap(ptr);
|
m_wrapPtr = new(m_wrapData.data()) Wrap(ptr);
|
||||||
@ -79,10 +104,12 @@ class AnyPtr {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr AnyPtr &operator=(AnyPtr const&ptr) noexcept {
|
constexpr AnyPtrT &operator=(AnyPtrT const&ptr) noexcept requires(!unique) {
|
||||||
if (this != &ptr) {
|
if (this != &ptr) {
|
||||||
if (ptr) {
|
if (std::is_constant_evaluated()) {
|
||||||
ox::safeDelete(m_wrapPtr);
|
ox::safeDelete(m_wrapPtr);
|
||||||
|
}
|
||||||
|
if (ptr) {
|
||||||
m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData);
|
m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData);
|
||||||
} else {
|
} else {
|
||||||
m_wrapPtr = nullptr;
|
m_wrapPtr = nullptr;
|
||||||
@ -91,10 +118,40 @@ class AnyPtr {
|
|||||||
return *this;
|
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 {
|
constexpr operator bool() const noexcept {
|
||||||
return m_wrapPtr && *m_wrapPtr;
|
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>
|
template<typename T>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr T *get() const noexcept {
|
constexpr T *get() const noexcept {
|
||||||
@ -104,6 +161,12 @@ class AnyPtr {
|
|||||||
return dynamic_cast<Wrap<T>*>(m_wrapPtr)->data;
|
return dynamic_cast<Wrap<T>*>(m_wrapPtr)->data;
|
||||||
#endif
|
#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>
|
template<typename T, std::size_t ArraySize>
|
||||||
constexpr T &Array<T, ArraySize>::operator[](std::size_t i) noexcept {
|
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];
|
return m_items[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, std::size_t ArraySize>
|
template<typename T, std::size_t ArraySize>
|
||||||
constexpr const T &Array<T, ArraySize>::operator[](std::size_t i) const noexcept {
|
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];
|
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 "fmt.hpp"
|
||||||
|
#include "realstd.hpp"
|
||||||
#include "stacktrace.hpp"
|
#include "stacktrace.hpp"
|
||||||
#include "trace.hpp"
|
#include "trace.hpp"
|
||||||
|
|
||||||
@ -14,14 +15,14 @@
|
|||||||
|
|
||||||
namespace ox {
|
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);
|
oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", file, line, panicMsg);
|
||||||
if (err.msg) {
|
if (err.msg) {
|
||||||
oxErrf("\tError Message:\t{}\n", err.msg);
|
oxErrf("\tError Message:\t{}\n", err.msg);
|
||||||
}
|
}
|
||||||
oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
|
oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
|
||||||
if (err.file != nullptr) {
|
if (err.src.file_name() != nullptr) {
|
||||||
oxErrf("\tError Location:\t{}:{}\n", err.file, err.line);
|
oxErrf("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line());
|
||||||
}
|
}
|
||||||
#ifdef OX_USE_STDLIB
|
#ifdef OX_USE_STDLIB
|
||||||
printStackTrace(2);
|
printStackTrace(2);
|
||||||
@ -32,16 +33,19 @@ void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err)
|
|||||||
#endif
|
#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);
|
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
|
#ifdef OX_USE_STDLIB
|
||||||
auto output = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
|
auto const st = genStackTrace(2);
|
||||||
output += genStackTrace(2);
|
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]:\n{}", msg, assertTxt, file, line, st);
|
||||||
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
|
abort();
|
||||||
std::abort();
|
|
||||||
#else
|
#else
|
||||||
oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
|
oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
|
||||||
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
|
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
|
||||||
@ -49,20 +53,25 @@ void assertFailFuncRuntime(StringViewCR file, int line, StringViewCR assertTxt,
|
|||||||
#endif
|
#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)
|
#if defined(OX_USE_STDLIB)
|
||||||
auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg);
|
auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg);
|
||||||
if (err.msg) {
|
if (err.msg) {
|
||||||
msg += sfmt("\tError Message:\t{}\n", err.msg);
|
msg += sfmt("\tError Message:\t{}\n", err.msg);
|
||||||
}
|
}
|
||||||
msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
|
msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
|
||||||
if (err.file != nullptr) {
|
if (err.src.file_name() != nullptr) {
|
||||||
msg += sfmt("\tError Location:\t{}:{}\n", err.file, err.line);
|
msg += sfmt("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line());
|
||||||
}
|
}
|
||||||
msg += genStackTrace(2);
|
msg += genStackTrace(2);
|
||||||
oxErr(msg);
|
oxErr(msg);
|
||||||
oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line);
|
oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line);
|
||||||
std::abort();
|
abort();
|
||||||
#else
|
#else
|
||||||
constexprPanic(file, line, assertMsg);
|
constexprPanic(file, line, assertMsg);
|
||||||
#endif
|
#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 {
|
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()) {
|
if (!std::is_constant_evaluated()) {
|
||||||
panic(file, line, panicMsg, err);
|
panic(file, line, panicMsg, err);
|
||||||
} else {
|
} 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(
|
||||||
void assertFailFuncRuntime(StringViewCR file, int line, const Error &err, StringViewCR, StringViewCR assertMsg) noexcept;
|
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 (!pass) {
|
||||||
if (!std::is_constant_evaluated()) {
|
if (!std::is_constant_evaluated()) {
|
||||||
assertFailFuncRuntime(file, line, assertTxt, msg);
|
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 (err) {
|
||||||
if (!std::is_constant_evaluated()) {
|
if (!std::is_constant_evaluated()) {
|
||||||
assertFailFuncRuntime(file, line, err, {}, assertMsg);
|
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 (actual != expected) {
|
||||||
if (!std::is_constant_evaluated()) {
|
if (!std::is_constant_evaluated()) {
|
||||||
#if defined(OX_USE_STDLIB)
|
#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;
|
constexpr auto Debug = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(OX_CHECK_BOUNDS)
|
||||||
|
constexpr auto CheckBounds = true;
|
||||||
|
#else
|
||||||
|
constexpr auto CheckBounds = Debug;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(NDEBUG)
|
#if defined(NDEBUG)
|
||||||
constexpr auto NDebug = true;
|
constexpr auto NDebug = true;
|
||||||
#else
|
#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 {
|
struct [[nodiscard]] Error {
|
||||||
|
std::source_location src;
|
||||||
ox::CString msg = nullptr;
|
ox::CString msg = nullptr;
|
||||||
ox::CString file = nullptr;
|
|
||||||
uint16_t line = 0;
|
|
||||||
ErrorCode errCode = 0;
|
ErrorCode errCode = 0;
|
||||||
|
|
||||||
constexpr Error() noexcept = default;
|
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(
|
explicit constexpr Error(
|
||||||
ErrorCode const errCode,
|
ErrorCode const errCode,
|
||||||
std::source_location const&src = std::source_location::current()) noexcept:
|
std::source_location const&src = std::source_location::current()) noexcept:
|
||||||
file{src.file_name()},
|
src{src},
|
||||||
line{static_cast<uint16_t>(src.line())},
|
|
||||||
errCode{errCode}
|
errCode{errCode}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -65,9 +53,8 @@ struct [[nodiscard]] Error {
|
|||||||
ErrorCode const errCode,
|
ErrorCode const errCode,
|
||||||
ox::CString msg,
|
ox::CString msg,
|
||||||
std::source_location const&src = std::source_location::current()) noexcept:
|
std::source_location const&src = std::source_location::current()) noexcept:
|
||||||
|
src{src},
|
||||||
msg{msg},
|
msg{msg},
|
||||||
file{src.file_name()},
|
|
||||||
line{static_cast<uint16_t>(src.line())},
|
|
||||||
errCode{errCode}
|
errCode{errCode}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -89,42 +76,31 @@ constexpr auto toStr(Error const&err) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Exception: public std::exception {
|
struct Exception: public std::exception {
|
||||||
|
std::source_location src;
|
||||||
ox::CString msg = nullptr;
|
ox::CString msg = nullptr;
|
||||||
ox::CString file = nullptr;
|
|
||||||
uint16_t line = 0;
|
|
||||||
ErrorCode errCode = 0;
|
ErrorCode errCode = 0;
|
||||||
|
|
||||||
explicit inline Exception(ox::CString file, uint32_t line, ErrorCode errCode, char const*msg = "") noexcept {
|
explicit Exception(
|
||||||
this->file = file;
|
|
||||||
this->line = static_cast<uint16_t>(line);
|
|
||||||
this->msg = msg;
|
|
||||||
this->errCode = errCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit inline Exception(
|
|
||||||
ErrorCode const errCode,
|
ErrorCode const errCode,
|
||||||
std::source_location const&src = std::source_location::current()) noexcept:
|
std::source_location const&src = std::source_location::current()) noexcept:
|
||||||
file{src.file_name()},
|
src{src},
|
||||||
line{static_cast<uint16_t>(src.line())},
|
|
||||||
errCode{errCode} {}
|
errCode{errCode} {}
|
||||||
|
|
||||||
explicit inline Exception(
|
explicit Exception(
|
||||||
ErrorCode const errCode,
|
ErrorCode const errCode,
|
||||||
ox::CString msg,
|
ox::CString msg,
|
||||||
std::source_location const&src = std::source_location::current()) noexcept:
|
std::source_location const&src = std::source_location::current()) noexcept:
|
||||||
|
src{src},
|
||||||
msg{msg},
|
msg{msg},
|
||||||
file{src.file_name()},
|
|
||||||
line{static_cast<uint16_t>(src.line())},
|
|
||||||
errCode{errCode} {}
|
errCode{errCode} {}
|
||||||
|
|
||||||
explicit inline Exception(Error const&err) noexcept:
|
explicit Exception(Error const&err) noexcept:
|
||||||
|
src{err.src},
|
||||||
msg{err.msg ? err.msg : ""},
|
msg{err.msg ? err.msg : ""},
|
||||||
file{err.file},
|
|
||||||
line{err.line},
|
|
||||||
errCode{err.errCode} {}
|
errCode{err.errCode} {}
|
||||||
|
|
||||||
constexpr Error toError() const noexcept {
|
constexpr Error toError() const noexcept {
|
||||||
return Error(file, line, errCode, msg);
|
return Error(errCode, msg, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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;
|
void panic(char const*file, int line, char const*panicMsg, Error const&err) noexcept;
|
||||||
|
|
||||||
template<typename T>
|
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});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
132
deps/ox/src/ox/std/hashmap.hpp
vendored
132
deps/ox/src/ox/std/hashmap.hpp
vendored
@ -11,6 +11,7 @@
|
|||||||
#include "algorithm.hpp"
|
#include "algorithm.hpp"
|
||||||
#include "hash.hpp"
|
#include "hash.hpp"
|
||||||
#include "ignore.hpp"
|
#include "ignore.hpp"
|
||||||
|
#include "optional.hpp"
|
||||||
#include "stringview.hpp"
|
#include "stringview.hpp"
|
||||||
#include "strops.hpp"
|
#include "strops.hpp"
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
@ -26,11 +27,12 @@ class HashMap {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct Pair {
|
struct Pair {
|
||||||
|
UPtr<Pair> next;
|
||||||
K key = {};
|
K key = {};
|
||||||
T value{};
|
T value{};
|
||||||
};
|
};
|
||||||
Vector<K> m_keys;
|
Vector<K> m_keys;
|
||||||
Vector<Pair*> m_pairs;
|
Vector<UPtr<Pair>> m_pairs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit constexpr HashMap(std::size_t size = 127);
|
explicit constexpr HashMap(std::size_t size = 127);
|
||||||
@ -73,10 +75,10 @@ class HashMap {
|
|||||||
constexpr void expand();
|
constexpr void expand();
|
||||||
|
|
||||||
template<typename KK>
|
template<typename KK>
|
||||||
constexpr Pair *const&access(Vector<Pair*> const&pairs, KK const&key) const;
|
constexpr UPtr<Pair> const &access(Vector<UPtr<Pair>> const &pairs, KK const &key) const;
|
||||||
|
|
||||||
template<typename KK>
|
template<typename KK>
|
||||||
constexpr Pair *&access(Vector<Pair*> &pairs, KK const&key);
|
constexpr UPtr<Pair> &access(Vector<UPtr<Pair>> &pairs, KK const &key);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,14 +87,13 @@ constexpr HashMap<K, T>::HashMap(std::size_t size): m_pairs(size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr HashMap<K, T>::HashMap(HashMap<K, T> const&other) {
|
constexpr HashMap<K, T>::HashMap(HashMap const &other) {
|
||||||
m_pairs = other.m_pairs;
|
operator=(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr HashMap<K, T>::HashMap(HashMap<K, T> &&other) noexcept {
|
constexpr HashMap<K, T>::HashMap(HashMap &&other) noexcept {
|
||||||
m_keys = std::move(other.m_keys);
|
operator=(std::move(other));
|
||||||
m_pairs = std::move(other.m_pairs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
@ -101,7 +102,7 @@ constexpr HashMap<K, T>::~HashMap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr bool HashMap<K, T>::operator==(HashMap const&other) const {
|
constexpr bool HashMap<K, T>::operator==(HashMap const &other) const {
|
||||||
if (m_keys != other.m_keys) {
|
if (m_keys != other.m_keys) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -115,19 +116,25 @@ constexpr bool HashMap<K, T>::operator==(HashMap const&other) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr HashMap<K, T> &HashMap<K, T>::operator=(HashMap<K, T> const&other) {
|
constexpr HashMap<K, T> &HashMap<K, T>::operator=(HashMap const &other) {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
clear();
|
clear();
|
||||||
m_keys = other.m_keys;
|
m_keys = other.m_keys;
|
||||||
m_pairs = other.m_pairs;
|
m_pairs.resize(other.m_pairs.size());
|
||||||
|
for (auto const&k : m_keys) {
|
||||||
|
auto const &src = access(other.m_pairs, k);
|
||||||
|
auto &dst = access(m_pairs, k);
|
||||||
|
dst = ox::make_unique<Pair>();
|
||||||
|
dst->key = src->key;
|
||||||
|
dst->value = src->value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr HashMap<K, T> &HashMap<K, T>::operator=(HashMap<K, T> &&other) noexcept {
|
constexpr HashMap<K, T> &HashMap<K, T>::operator=(HashMap &&other) noexcept {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
clear();
|
|
||||||
m_keys = std::move(other.m_keys);
|
m_keys = std::move(other.m_keys);
|
||||||
m_pairs = std::move(other.m_pairs);
|
m_pairs = std::move(other.m_pairs);
|
||||||
}
|
}
|
||||||
@ -135,60 +142,52 @@ constexpr HashMap<K, T> &HashMap<K, T>::operator=(HashMap<K, T> &&other) noexcep
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr T &HashMap<K, T>::operator[](MaybeView_t<K> const&k) {
|
constexpr T &HashMap<K, T>::operator[](MaybeView_t<K> const &key) {
|
||||||
auto p = &access(m_pairs, k);
|
auto p = &access(m_pairs, key);
|
||||||
if (*p == nullptr) {
|
if (*p == nullptr) {
|
||||||
if (static_cast<double>(m_pairs.size()) * 0.7 <
|
if (static_cast<double>(m_pairs.size()) * 0.7 <
|
||||||
static_cast<double>(m_keys.size())) {
|
static_cast<double>(m_keys.size())) {
|
||||||
expand();
|
expand();
|
||||||
p = &access(m_pairs, k);
|
p = &access(m_pairs, key);
|
||||||
}
|
}
|
||||||
*p = new Pair;
|
*p = ox::make_unique<Pair>();
|
||||||
(*p)->key = k;
|
(*p)->key = key;
|
||||||
m_keys.emplace_back(k);
|
m_keys.emplace_back(key);
|
||||||
}
|
}
|
||||||
return (*p)->value;
|
return (*p)->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr Result<T*> HashMap<K, T>::at(MaybeView_t<K> const&k) noexcept {
|
constexpr Result<T*> HashMap<K, T>::at(MaybeView_t<K> const &key) noexcept {
|
||||||
auto p = access(m_pairs, k);
|
auto &p = access(m_pairs, key);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return {nullptr, ox::Error(1, "value not found for given key")};
|
return ox::Error{1, "value not found for given key"};
|
||||||
}
|
}
|
||||||
return &p->value;
|
return &p->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr Result<const T*> HashMap<K, T>::at(MaybeView_t<K> const&k) const noexcept {
|
constexpr Result<const T*> HashMap<K, T>::at(MaybeView_t<K> const &key) const noexcept {
|
||||||
auto p = access(m_pairs, k);
|
auto &p = access(m_pairs, key);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return {nullptr, ox::Error(1, "value not found for given key")};
|
return ox::Error{1, "value not found for given key"};
|
||||||
}
|
}
|
||||||
return &p->value;
|
return &p->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr void HashMap<K, T>::erase(MaybeView_t<K> const&k) {
|
constexpr void HashMap<K, T>::erase(MaybeView_t<K> const &key) {
|
||||||
if (!contains(k)) {
|
if (!contains(key)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto h = ox::hash<MaybeView_t<K>>{}(k) % m_pairs.size();
|
auto &c = access(m_pairs, key);
|
||||||
while (true) {
|
c = std::move(c->next);
|
||||||
const auto &p = m_pairs[h];
|
std::ignore = m_keys.erase(ox::find(m_keys.begin(), m_keys.end(), key));
|
||||||
if (p == nullptr || p->key == k) {
|
|
||||||
std::ignore = m_pairs.erase(h);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
h = ox::hash<MaybeView_t<K>>{}(k) % m_pairs.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::ignore = m_keys.erase(ox::find(m_keys.begin(), m_keys.end(), k));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr bool HashMap<K, T>::contains(MaybeView_t<K> const&k) const noexcept {
|
constexpr bool HashMap<K, T>::contains(MaybeView_t<K> const &key) const noexcept {
|
||||||
return access(m_pairs, k) != nullptr;
|
return access(m_pairs, key).get() != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
@ -204,27 +203,26 @@ constexpr Vector<K> const&HashMap<K, T>::keys() const noexcept {
|
|||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr Vector<T> HashMap<K, T>::values() const noexcept {
|
constexpr Vector<T> HashMap<K, T>::values() const noexcept {
|
||||||
Vector<T> out;
|
Vector<T> out;
|
||||||
out.reserve(m_pairs.size());
|
out.reserve(m_keys.size());
|
||||||
for (auto const&p : m_pairs) {
|
for (auto const &p : m_pairs) {
|
||||||
out.emplace_back(p->value);
|
if (out) {
|
||||||
|
out.emplace_back(p->value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr void HashMap<K, T>::clear() {
|
constexpr void HashMap<K, T>::clear() {
|
||||||
for (std::size_t i = 0; i < m_pairs.size(); i++) {
|
|
||||||
delete m_pairs[i];
|
|
||||||
}
|
|
||||||
m_pairs.clear();
|
m_pairs.clear();
|
||||||
m_pairs.resize(127);
|
m_pairs.resize(127);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
constexpr void HashMap<K, T>::expand() {
|
constexpr void HashMap<K, T>::expand() {
|
||||||
Vector<Pair*> r(m_pairs.size() * 2);
|
Vector<UPtr<Pair>> r{m_pairs.size() * 2};
|
||||||
for (std::size_t i = 0; i < m_keys.size(); ++i) {
|
for (std::size_t i = 0; i < m_keys.size(); ++i) {
|
||||||
auto const&k = m_keys[i];
|
auto const &k = m_keys[i];
|
||||||
access(r, k) = std::move(access(m_pairs, k));
|
access(r, k) = std::move(access(m_pairs, k));
|
||||||
}
|
}
|
||||||
m_pairs = std::move(r);
|
m_pairs = std::move(r);
|
||||||
@ -232,29 +230,39 @@ constexpr void HashMap<K, T>::expand() {
|
|||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
template<typename KK>
|
template<typename KK>
|
||||||
constexpr typename HashMap<K, T>::Pair *const&HashMap<K, T>::access(Vector<Pair*> const&pairs, KK const&k) const {
|
constexpr UPtr<typename HashMap<K, T>::Pair> const &HashMap<K, T>::access(
|
||||||
auto h = static_cast<std::size_t>(ox::hash<KK>{}(k) % pairs.size());
|
Vector<UPtr<Pair>> const& pairs,
|
||||||
|
KK const &key) const {
|
||||||
|
auto const h = static_cast<std::size_t>(ox::hash<KK>{}(key) % pairs.size());
|
||||||
|
auto const &p = *pairs.at(h).unwrap();
|
||||||
|
if (p == nullptr || p->key == key) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
auto c = &p->next;
|
||||||
while (true) {
|
while (true) {
|
||||||
auto const&p = *pairs.at(h).unwrap();
|
if (*c == nullptr || (*c)->key == key) {
|
||||||
if (p == nullptr || p->key == k) {
|
return *c;
|
||||||
return p;
|
|
||||||
} else {
|
|
||||||
h = (h + 1) % pairs.size();
|
|
||||||
}
|
}
|
||||||
|
c = &(*c)->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T>
|
template<typename K, typename T>
|
||||||
template<typename KK>
|
template<typename KK>
|
||||||
constexpr typename HashMap<K, T>::Pair *&HashMap<K, T>::access(Vector<Pair*> &pairs, KK const&k) {
|
constexpr UPtr<typename HashMap<K, T>::Pair> &HashMap<K, T>::access(
|
||||||
auto h = static_cast<std::size_t>(ox::hash<KK>{}(k) % pairs.size());
|
Vector<UPtr<Pair>> &pairs,
|
||||||
|
KK const &key) {
|
||||||
|
auto const h = static_cast<std::size_t>(ox::hash<KK>{}(key) % pairs.size());
|
||||||
|
auto &p = *pairs.at(h).unwrap();
|
||||||
|
if (p == nullptr || p->key == key) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
auto c = &p->next;
|
||||||
while (true) {
|
while (true) {
|
||||||
auto &p = *pairs.at(h).unwrap();
|
if (*c == nullptr || (*c)->key == key) {
|
||||||
if (p == nullptr || p->key == k) {
|
return *c;
|
||||||
return p;
|
|
||||||
} else {
|
|
||||||
h = (h + 1) % pairs.size();
|
|
||||||
}
|
}
|
||||||
|
c = &(*c)->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
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];
|
return &m_t[m_offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr RefType operator*() const noexcept {
|
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];
|
return m_t[m_offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr RefType operator[](std::size_t s) const noexcept {
|
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];
|
return m_t[s];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
deps/ox/src/ox/std/memory.hpp
vendored
4
deps/ox/src/ox/std/memory.hpp
vendored
@ -260,12 +260,12 @@ constexpr bool operator==(const UniquePtr<T> &p1, const UniquePtr<T> &p2) noexce
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr bool operator==(const UniquePtr<T> &p1, std::nullptr_t) noexcept {
|
constexpr bool operator==(const UniquePtr<T> &p1, std::nullptr_t) noexcept {
|
||||||
return p1.get();
|
return p1.get() == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr bool operator==(std::nullptr_t, const UniquePtr<T> &p2) noexcept {
|
constexpr bool operator==(std::nullptr_t, const UniquePtr<T> &p2) noexcept {
|
||||||
return p2.get();
|
return p2.get() == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
class Reader_v {
|
||||||
public:
|
public:
|
||||||
virtual constexpr ~Reader_v() noexcept = default;
|
virtual constexpr ~Reader_v() noexcept = default;
|
||||||
[[nodiscard]]
|
|
||||||
virtual constexpr ox::Result<char> peek() const noexcept = 0;
|
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> read(char*, std::size_t) noexcept = 0;
|
||||||
virtual constexpr ox::Result<std::size_t> tellg() 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
|
#else
|
||||||
#define assert(e) while (!(e));
|
#define assert(e) while (!(e));
|
||||||
#endif
|
#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]]
|
[[nodiscard]]
|
||||||
constexpr Vector<K> keys() const noexcept;
|
constexpr Vector<K> keys() const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr Vector<T> values() const noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr K const&key(size_t i) const noexcept;
|
constexpr K const&key(size_t i) const noexcept;
|
||||||
|
|
||||||
@ -82,14 +85,22 @@ class SmallMap {
|
|||||||
return m_pairs;
|
return m_pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr ox::Span<Pair> pairs() noexcept {
|
||||||
|
return m_pairs;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr void clear();
|
constexpr void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename KK>
|
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>
|
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>
|
template<typename K, typename T, size_t SmallSz>
|
||||||
constexpr T &SmallMap<K, T, SmallSz>::operator[](MaybeView_t<K> const&k) {
|
constexpr T &SmallMap<K, T, SmallSz>::operator[](MaybeView_t<K> const&k) {
|
||||||
bool isNew{};
|
bool isNew{};
|
||||||
auto p = &access(m_pairs, k, isNew);
|
auto p = access(m_pairs, k, isNew);
|
||||||
if (isNew) {
|
if (isNew) {
|
||||||
p->key = k;
|
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>
|
template<typename K, typename T, size_t SmallSz>
|
||||||
constexpr Result<T*> SmallMap<K, T, SmallSz>::at(MaybeView_t<K> const&k) noexcept {
|
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) {
|
if (!p) {
|
||||||
return {nullptr, ox::Error(1, "value not found for given key")};
|
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>
|
template<typename K, typename T, size_t SmallSz>
|
||||||
constexpr Result<const T*> SmallMap<K, T, SmallSz>::at(MaybeView_t<K> const&k) const noexcept {
|
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) {
|
if (!p) {
|
||||||
return {nullptr, ox::Error(1, "value not found for given key")};
|
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>
|
template<typename K, typename T, size_t SmallSz>
|
||||||
constexpr bool SmallMap<K, T, SmallSz>::contains(MaybeView_t<K> const&k) const noexcept {
|
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>
|
template<typename K, typename T, size_t SmallSz>
|
||||||
@ -186,6 +199,16 @@ constexpr Vector<K> SmallMap<K, T, SmallSz>::keys() const noexcept {
|
|||||||
return keys;
|
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>
|
template<typename K, typename T, size_t SmallSz>
|
||||||
constexpr K const&SmallMap<K, T, SmallSz>::key(size_t i) const noexcept {
|
constexpr K const&SmallMap<K, T, SmallSz>::key(size_t i) const noexcept {
|
||||||
return m_pairs[i].key;
|
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 K, typename T, size_t SmallSz>
|
||||||
template<typename KK>
|
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 {
|
PairVector const&pairs, KK const&k, bool &isNew) const {
|
||||||
for (auto const&p : pairs) {
|
for (auto const&p : pairs) {
|
||||||
if (p.key == k) {
|
if (p.key == k) {
|
||||||
isNew = false;
|
isNew = false;
|
||||||
return p;
|
return &p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isNew = true;
|
isNew = true;
|
||||||
return pairs.emplace_back();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K, typename T, size_t SmallSz>
|
template<typename K, typename T, size_t SmallSz>
|
||||||
template<typename KK>
|
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) {
|
PairVector &pairs, KK const&k, bool &isNew) {
|
||||||
for (auto &p : pairs) {
|
for (auto &p : pairs) {
|
||||||
if (p.key == k) {
|
if (p.key == k) {
|
||||||
isNew = false;
|
isNew = false;
|
||||||
return p;
|
return &p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isNew = true;
|
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>
|
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 "iterator.hpp"
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
|
|
||||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
@ -129,22 +129,22 @@ class Span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr T &operator[](std::size_t i) noexcept {
|
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];
|
return m_items[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const T &operator[](std::size_t i) const noexcept {
|
constexpr T const&operator[](std::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];
|
return m_items[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Span operator+(size_t i) const noexcept {
|
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};
|
return {m_items + i, m_size - i};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Span operator+=(size_t i) noexcept {
|
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_items += i;
|
||||||
m_size -= i;
|
m_size -= i;
|
||||||
return *this;
|
return *this;
|
||||||
@ -168,8 +168,20 @@ class Span {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
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
|
||||||
|
12
deps/ox/src/ox/std/string.hpp
vendored
12
deps/ox/src/ox/std/string.hpp
vendored
@ -171,7 +171,7 @@ class BasicString {
|
|||||||
|
|
||||||
constexpr bool operator>=(BasicString const&other) const noexcept;
|
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;
|
constexpr char &operator[](std::size_t i) noexcept;
|
||||||
|
|
||||||
@ -392,7 +392,7 @@ template<std::size_t SmallStringSize_v>
|
|||||||
constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operator+(const char *str) const noexcept {
|
constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operator+(const char *str) const noexcept {
|
||||||
const std::size_t strLen = ox::strlen(str);
|
const std::size_t strLen = ox::strlen(str);
|
||||||
const auto currentLen = len();
|
const auto currentLen = len();
|
||||||
BasicString<SmallStringSize_v> cpy(currentLen + strLen);
|
BasicString<SmallStringSize_v> cpy;
|
||||||
cpy.m_buff.resize(m_buff.size() + strLen);
|
cpy.m_buff.resize(m_buff.size() + strLen);
|
||||||
ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
||||||
ox::listcpy(&cpy.m_buff[currentLen], str, strLen);
|
ox::listcpy(&cpy.m_buff[currentLen], str, strLen);
|
||||||
@ -425,7 +425,8 @@ constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operato
|
|||||||
BasicString<SmallStringSize_v> cpy(currentLen + strLen);
|
BasicString<SmallStringSize_v> cpy(currentLen + strLen);
|
||||||
cpy.m_buff.resize(m_buff.size() + strLen);
|
cpy.m_buff.resize(m_buff.size() + strLen);
|
||||||
ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
||||||
ox::listcpy(&cpy.m_buff[currentLen], src.data(), strLen + 1);
|
ox::listcpy(&cpy.m_buff[currentLen], src.data(), strLen);
|
||||||
|
cpy.m_buff[cpy.m_buff.size() - 1] = 0;
|
||||||
return cpy;
|
return cpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +437,8 @@ constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operato
|
|||||||
BasicString<SmallStringSize_v> cpy(currentLen + strLen);
|
BasicString<SmallStringSize_v> cpy(currentLen + strLen);
|
||||||
cpy.m_buff.resize(m_buff.size() + strLen);
|
cpy.m_buff.resize(m_buff.size() + strLen);
|
||||||
ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen);
|
||||||
ox::listcpy(&cpy.m_buff[currentLen], src.data(), strLen + 1);
|
ox::listcpy(&cpy.m_buff[currentLen], src.data(), strLen);
|
||||||
|
cpy.m_buff[cpy.m_buff.size() - 1] = 0;
|
||||||
return cpy;
|
return cpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,7 +490,7 @@ constexpr bool BasicString<SmallStringSize_v>::operator>=(BasicString const&othe
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
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];
|
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] SmallMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "SmallMap")
|
||||||
add_test("[ox/std] SmallMap2" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "SmallMap2")
|
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" ${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] HashMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "HashMap")
|
||||||
add_test("[ox/std] HeapMgr" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest malloc)
|
add_test("[ox/std] HeapMgr" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest malloc)
|
||||||
add_test("[ox/std] Serialize-Int" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Serialize-Int")
|
add_test("[ox/std] Serialize-Int" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Serialize-Int")
|
||||||
|
67
deps/ox/src/ox/std/test/tests.cpp
vendored
67
deps/ox/src/ox/std/test/tests.cpp
vendored
@ -237,6 +237,50 @@ OX_CLANG_NOWARN_END
|
|||||||
return ox::Error(0);
|
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",
|
"SmallMap",
|
||||||
[] {
|
[] {
|
||||||
@ -246,7 +290,18 @@ OX_CLANG_NOWARN_END
|
|||||||
oxExpect(map.size(), 1u);
|
oxExpect(map.size(), 1u);
|
||||||
oxExpect(map["aoeu"], "");
|
oxExpect(map["aoeu"], "");
|
||||||
oxExpect(map.size(), 2u);
|
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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -273,6 +328,16 @@ OX_CLANG_NOWARN_END
|
|||||||
si["aoeu"] = 100;
|
si["aoeu"] = 100;
|
||||||
oxAssert(si["asdf"] == 42, "asdf != 42");
|
oxAssert(si["asdf"] == 42, "asdf != 42");
|
||||||
oxAssert(si["aoeu"] == 100, "aoeu != 100");
|
oxAssert(si["aoeu"] == 100, "aoeu != 100");
|
||||||
|
si.erase("asdf");
|
||||||
|
oxAssert(!si.contains("asdf"), "wrongly contains asdf");
|
||||||
|
oxAssert(si.contains("aoeu"), "does not contains aoeu");
|
||||||
|
oxAssert(!si.at("asdf").ok(), "asdf != 0");
|
||||||
|
oxExpect(si["asdf"], 0);
|
||||||
|
oxAssert(si["aoeu"] == 100, "aoeu != 100");
|
||||||
|
auto si2 = si;
|
||||||
|
oxDebugf("{}", si2["asdf"]);
|
||||||
|
oxExpect(si2["asdf"], 0);
|
||||||
|
oxAssert(si2["aoeu"] == 100, "aoeu != 100");
|
||||||
ox::HashMap<int, int> ii;
|
ox::HashMap<int, int> ii;
|
||||||
ii[4] = 42;
|
ii[4] = 42;
|
||||||
ii[5] = 100;
|
ii[5] = 100;
|
||||||
|
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 {
|
inline void logError(const char *file, int line, const char *fmt, const Error &err) noexcept {
|
||||||
if (err) {
|
if (err) {
|
||||||
TraceStream trc(file, line, "ox::error");
|
TraceStream trc(file, line, "ox::error");
|
||||||
if (err.file != nullptr) {
|
if (err.src.file_name() != nullptr) {
|
||||||
trc << "Error: (" << err.file << ":" << err.line << "):";
|
trc << "Error: (" << err.src.file_name() << ":" << err.src.line() << "):";
|
||||||
} else {
|
} else {
|
||||||
trc << "Error:";
|
trc << "Error:";
|
||||||
}
|
}
|
||||||
@ -282,8 +282,8 @@ inline void logError(const char *file, int line, const Error &err) noexcept {
|
|||||||
if (err) {
|
if (err) {
|
||||||
TraceStream trc(file, line, "ox::error");
|
TraceStream trc(file, line, "ox::error");
|
||||||
trc << "Error:" << err;
|
trc << "Error:" << err;
|
||||||
if (err.file != nullptr) {
|
if (err.src.file_name() != nullptr) {
|
||||||
trc << "(" << err.file << ":" << err.line << ")";
|
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 {
|
namespace std {
|
||||||
|
|
||||||
template<typename T>
|
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();
|
return __builtin_is_constant_evaluated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -156,6 +159,9 @@ static_assert(is_class<int>::value == false);
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr bool is_class_v = is_class<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>
|
template<typename T>
|
||||||
constexpr bool is_signed_v = integral_constant<bool, T(-1) < T(0)>::value;
|
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);
|
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
|
#endif
|
||||||
|
|
||||||
|
38
deps/ox/src/ox/std/vector.hpp
vendored
38
deps/ox/src/ox/std/vector.hpp
vendored
@ -311,8 +311,12 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|||||||
*/
|
*/
|
||||||
constexpr Error unordered_erase(std::size_t pos) noexcept(useNoexcept);
|
constexpr Error unordered_erase(std::size_t pos) noexcept(useNoexcept);
|
||||||
|
|
||||||
|
constexpr Error remove(T const &val);
|
||||||
|
|
||||||
constexpr void reserve(std::size_t cap) noexcept(useNoexcept);
|
constexpr void reserve(std::size_t cap) noexcept(useNoexcept);
|
||||||
|
|
||||||
|
constexpr void shrink_to_fit() noexcept(useNoexcept);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
constexpr void reserveInsert(
|
constexpr void reserveInsert(
|
||||||
std::size_t cap, std::size_t pos, std::size_t offset = 1) noexcept(useNoexcept);
|
std::size_t cap, std::size_t pos, std::size_t offset = 1) noexcept(useNoexcept);
|
||||||
@ -341,6 +345,7 @@ constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::size_t size) noexce
|
|||||||
|
|
||||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||||
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::initializer_list<T> list) noexcept {
|
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::initializer_list<T> list) noexcept {
|
||||||
|
reserve(list.size());
|
||||||
for (auto &item : list) {
|
for (auto &item : list) {
|
||||||
emplace_back(std::move(item));
|
emplace_back(std::move(item));
|
||||||
}
|
}
|
||||||
@ -424,13 +429,13 @@ constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allo
|
|||||||
|
|
||||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||||
constexpr T &Vector<T, SmallVectorSize, Allocator>::operator[](std::size_t i) noexcept {
|
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];
|
return m_items[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||||
constexpr const T &Vector<T, SmallVectorSize, Allocator>::operator[](std::size_t i) const noexcept {
|
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];
|
return m_items[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,6 +661,17 @@ constexpr Error Vector<T, SmallVectorSize, Allocator>::unordered_erase(std::size
|
|||||||
return ox::Error(0);
|
return ox::Error(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||||
|
constexpr ox::Error Vector<T, SmallVectorSize, Allocator>::remove(T const &val) {
|
||||||
|
for (size_t i{}; auto const &v : *this) {
|
||||||
|
if (v == val) {
|
||||||
|
return erase(i).error;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return ox::Error{1, "element not found"};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||||
constexpr void Vector<T, SmallVectorSize, Allocator>::reserve(std::size_t cap) noexcept(useNoexcept) {
|
constexpr void Vector<T, SmallVectorSize, Allocator>::reserve(std::size_t cap) noexcept(useNoexcept) {
|
||||||
if (cap <= m_cap) {
|
if (cap <= m_cap) {
|
||||||
@ -675,6 +691,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>
|
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||||
constexpr void Vector<T, SmallVectorSize, Allocator>::reserveInsert(
|
constexpr void Vector<T, SmallVectorSize, Allocator>::reserveInsert(
|
||||||
std::size_t cap,
|
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 <ox/std/heapmgr.hpp>
|
||||||
|
|
||||||
|
#include <teagba/bios.hpp>
|
||||||
|
#include <teagba/registers.hpp>
|
||||||
|
|
||||||
namespace mgba {
|
namespace mgba {
|
||||||
void initConsole();
|
void initConsole();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MEM_EWRAM_BEGIN reinterpret_cast<char*>(0x02000000)
|
#define MEM_HEAP_BEGIN reinterpret_cast<char*>(0x02000000)
|
||||||
#define MEM_EWRAM_END reinterpret_cast<char*>(0x0203FFFF)
|
#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
|
// set size to half of EWRAM
|
||||||
#define HEAP_SIZE ((MEM_EWRAM_END - MEM_EWRAM_BEGIN) / 2)
|
#define HEAP_SIZE ((MEM_HEAP_END - MEM_HEAP_BEGIN) / 2)
|
||||||
#define HEAP_END reinterpret_cast<char*>(MEM_EWRAM_BEGIN + HEAP_SIZE)
|
#define HEAP_END reinterpret_cast<char*>(MEM_HEAP_BEGIN + HEAP_SIZE)
|
||||||
|
|
||||||
extern void (*__preinit_array_start[]) (void);
|
extern void (*__preinit_array_start[]) (void);
|
||||||
extern void (*__preinit_array_end[]) (void);
|
extern void (*__preinit_array_end[]) (void);
|
||||||
@ -25,6 +28,14 @@ int main(int argc, const char **argv);
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
void abort() {
|
||||||
|
REG_IE = 0;
|
||||||
|
teagba::intrwait(0, 0);
|
||||||
|
while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *__gxx_personality_v0{};
|
||||||
|
|
||||||
void __libc_init_array() {
|
void __libc_init_array() {
|
||||||
auto preInits = __preinit_array_end - __preinit_array_start;
|
auto preInits = __preinit_array_end - __preinit_array_start;
|
||||||
for (decltype(preInits) i = 0; i < preInits; i++) {
|
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
|
### Error Handling
|
||||||
|
|
||||||
The GBA build has exceptions disabled.
|
Instead of throwing exceptions, generally try to use
|
||||||
Instead of throwing exceptions, all engine code should return
|
[ox::Errors](deps/ox/ox-docs.md#error-handling) for error reporting,
|
||||||
[ox::Errors](deps/ox/ox-docs.md#error-handling) for error reporting.
|
but exceptions may be used where they make sense.
|
||||||
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.
|
|
||||||
|
|
||||||
Exceptions should generally just use ```OxException```, which is bascially an
|
Exceptions should generally just use ```OxException```, which is bascially an
|
||||||
exception form of ```ox::Error```.
|
exception form of ```ox::Error```.
|
||||||
|
23
release-notes.md
Normal file
23
release-notes.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# 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 jump to a color in a Palette by double clicking on the
|
||||||
|
color from the TileSheet editor
|
||||||
|
* 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
|
@ -0,0 +1,23 @@
|
|||||||
|
O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
||||||
|
"fieldList" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fieldName" : "pages",
|
||||||
|
"subscriptLevels" : 2,
|
||||||
|
"subscriptStack" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeId" : "B.uint16;0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preloadable" : true,
|
||||||
|
"primitiveType" : 5,
|
||||||
|
"typeName" : "net.drinkingtea.nostalgia.gfx.CompactPalette",
|
||||||
|
"typeVersion" : 1
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
||||||
|
"fieldList" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fieldName" : "bpp",
|
||||||
|
"typeId" : "B.int8;0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "defaultPalette",
|
||||||
|
"typeId" : "net.drinkingtea.ox.FileAddress;1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "pixels",
|
||||||
|
"subscriptLevels" : 1,
|
||||||
|
"subscriptStack" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeId" : "B.uint8;0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preloadable" : true,
|
||||||
|
"primitiveType" : 5,
|
||||||
|
"typeName" : "net.drinkingtea.nostalgia.gfx.CompactTileSheet",
|
||||||
|
"typeVersion" : 1
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
||||||
|
"fieldList" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fieldName" : "name",
|
||||||
|
"typeId" : "net.drinkingtea.ox.BasicString#8#;1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "colors",
|
||||||
|
"subscriptLevels" : 1,
|
||||||
|
"subscriptStack" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeId" : "net.drinkingtea.nostalgia.gfx.PaletteColor;2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primitiveType" : 5,
|
||||||
|
"typeName" : "net.drinkingtea.nostalgia.gfx.Palette.PalettePage",
|
||||||
|
"typeVersion" : 2
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
||||||
|
"fieldList" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fieldName" : "colorNames",
|
||||||
|
"subscriptLevels" : 1,
|
||||||
|
"subscriptStack" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeId" : "net.drinkingtea.ox.BasicString#8#;1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "pages",
|
||||||
|
"subscriptLevels" : 1,
|
||||||
|
"subscriptStack" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeId" : "net.drinkingtea.nostalgia.gfx.Palette.PalettePage;2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preloadable" : true,
|
||||||
|
"primitiveType" : 5,
|
||||||
|
"typeName" : "net.drinkingtea.nostalgia.gfx.Palette",
|
||||||
|
"typeVersion" : 5
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
||||||
|
"fieldList" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fieldName" : "r",
|
||||||
|
"typeId" : "B.uint8;0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "g",
|
||||||
|
"typeId" : "B.uint8;0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "b",
|
||||||
|
"typeId" : "B.uint8;0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "a",
|
||||||
|
"typeId" : "B.uint8;0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primitiveType" : 5,
|
||||||
|
"typeName" : "net.drinkingtea.nostalgia.gfx.PaletteColor",
|
||||||
|
"typeVersion" : 2
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
||||||
|
"fieldList" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fieldName" : "id",
|
||||||
|
"typeId" : "B.int32;0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "name",
|
||||||
|
"typeId" : "net.drinkingtea.ox.BasicString#8#;1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "rows",
|
||||||
|
"typeId" : "B.int32;0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "columns",
|
||||||
|
"typeId" : "B.int32;0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "subsheets",
|
||||||
|
"subscriptLevels" : 1,
|
||||||
|
"subscriptStack" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeId" : "net.drinkingtea.nostalgia.gfx.TileSheet.SubSheet;5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "pixels",
|
||||||
|
"subscriptLevels" : 1,
|
||||||
|
"subscriptStack" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"subscriptType" : 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeId" : "B.uint8;0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primitiveType" : 5,
|
||||||
|
"typeName" : "net.drinkingtea.nostalgia.gfx.TileSheet.SubSheet",
|
||||||
|
"typeVersion" : 5
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
O1;net.drinkingtea.ox.TypeDescriptor;1;{
|
||||||
|
"fieldList" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fieldName" : "bpp",
|
||||||
|
"typeId" : "B.int8;0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "idIt",
|
||||||
|
"typeId" : "B.int32;0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "defaultPalette",
|
||||||
|
"typeId" : "net.drinkingtea.ox.BasicString#8#;1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName" : "subsheet",
|
||||||
|
"typeId" : "net.drinkingtea.nostalgia.gfx.TileSheet.SubSheet;5"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primitiveType" : 5,
|
||||||
|
"typeName" : "net.drinkingtea.nostalgia.gfx.TileSheet",
|
||||||
|
"typeVersion" : 5
|
||||||
|
}
|
@ -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,7 +1,7 @@
|
|||||||
# module dir list
|
# module dir list
|
||||||
|
|
||||||
add_subdirectory(core)
|
add_subdirectory(gfx)
|
||||||
add_subdirectory(scene)
|
add_subdirectory(sound)
|
||||||
|
|
||||||
# module libraries
|
# module libraries
|
||||||
|
|
||||||
@ -13,8 +13,8 @@ add_library(
|
|||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
NostalgiaKeelModules PUBLIC
|
NostalgiaKeelModules PUBLIC
|
||||||
Keel
|
Keel
|
||||||
NostalgiaCore-Keel
|
NostalgiaGfx-Keel
|
||||||
NostalgiaScene-Keel
|
NostalgiaSound-Keel
|
||||||
)
|
)
|
||||||
install(
|
install(
|
||||||
FILES
|
FILES
|
||||||
@ -32,8 +32,8 @@ if(NOSTALGIA_BUILD_STUDIO)
|
|||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
NostalgiaStudioModules PUBLIC
|
NostalgiaStudioModules PUBLIC
|
||||||
StudioAppLib
|
StudioAppLib
|
||||||
NostalgiaCore-Studio-ImGui
|
NostalgiaGfx-Studio-ImGui
|
||||||
NostalgiaScene-Studio
|
NostalgiaSound-Studio-ImGui
|
||||||
)
|
)
|
||||||
install(
|
install(
|
||||||
FILES
|
FILES
|
||||||
|
@ -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,13 +0,0 @@
|
|||||||
target_sources(
|
|
||||||
NostalgiaCore-Studio PRIVATE
|
|
||||||
commands/addcolorcommand.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,323 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <ox/claw/read.hpp>
|
|
||||||
#include <ox/std/algorithm.hpp>
|
|
||||||
#include <ox/std/buffer.hpp>
|
|
||||||
#include <ox/std/memory.hpp>
|
|
||||||
|
|
||||||
#include <turbine/clipboard.hpp>
|
|
||||||
#include <keel/media.hpp>
|
|
||||||
|
|
||||||
#include <nostalgia/core/ptidxconv.hpp>
|
|
||||||
|
|
||||||
#include "commands/commands.hpp"
|
|
||||||
#include "commands/addsubsheetcommand.hpp"
|
|
||||||
#include "commands/cutpastecommand.hpp"
|
|
||||||
#include "commands/deletetilescommand.hpp"
|
|
||||||
#include "commands/drawcommand.hpp"
|
|
||||||
#include "commands/inserttilescommand.hpp"
|
|
||||||
#include "commands/palettechangecommand.hpp"
|
|
||||||
#include "commands/rmsubsheetcommand.hpp"
|
|
||||||
#include "commands/updatesubsheetcommand.hpp"
|
|
||||||
#include "tilesheeteditormodel.hpp"
|
|
||||||
|
|
||||||
namespace nostalgia::core {
|
|
||||||
|
|
||||||
Palette const TileSheetEditorModel::s_defaultPalette = {
|
|
||||||
.colorNames = {ox::Vector<ox::String>{{}}},
|
|
||||||
.pages = {{"Page 1", ox::Vector<Color16>(128)}},
|
|
||||||
};
|
|
||||||
|
|
||||||
// delete pixels of all non-leaf nodes
|
|
||||||
static void normalizeSubsheets(TileSheet::SubSheet &ss) noexcept {
|
|
||||||
if (ss.subsheets.empty()) {
|
|
||||||
for (auto &child : ss.subsheets) {
|
|
||||||
normalizeSubsheets(child);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ss.pixels.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TileSheetEditorModel::TileSheetEditorModel(studio::StudioContext &sctx, ox::StringView path, studio::UndoStack &undoStack):
|
|
||||||
m_sctx(sctx),
|
|
||||||
m_tctx(m_sctx.tctx),
|
|
||||||
m_path(path),
|
|
||||||
m_img(*readObj<TileSheet>(keelCtx(m_tctx), m_path).unwrapThrow()),
|
|
||||||
// ignore failure to load palette
|
|
||||||
m_pal(readObj<Palette>(keelCtx(m_tctx), m_img.defaultPalette).value),
|
|
||||||
m_undoStack(undoStack) {
|
|
||||||
normalizeSubsheets(m_img.subsheet);
|
|
||||||
m_pal.updated.connect(this, &TileSheetEditorModel::markUpdated);
|
|
||||||
m_undoStack.changeTriggered.connect(this, &TileSheetEditorModel::markUpdatedCmdId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::cut() {
|
|
||||||
if (!m_selection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
TileSheetClipboard blankCb;
|
|
||||||
auto cb = ox::make_unique<TileSheetClipboard>();
|
|
||||||
auto const&s = activeSubSheet();
|
|
||||||
iterateSelectionRows(*m_selection, [&](int x, int y) {
|
|
||||||
auto pt = ox::Point{x, y};
|
|
||||||
auto const idx = core::idx(s, pt);
|
|
||||||
auto const c = getPixel(s, m_img.bpp, idx);
|
|
||||||
pt -= m_selection->a;
|
|
||||||
cb->addPixel(pt, c);
|
|
||||||
blankCb.addPixel(pt, 0);
|
|
||||||
});
|
|
||||||
auto const pt1 = m_selection->a;
|
|
||||||
auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight};
|
|
||||||
turbine::setClipboardObject(m_tctx, std::move(cb));
|
|
||||||
pushCommand(ox::make<CutPasteCommand>(CommandId::Cut, m_img, m_activeSubsSheetIdx, pt1, pt2, blankCb));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::copy() {
|
|
||||||
if (!m_selection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto cb = ox::make_unique<TileSheetClipboard>();
|
|
||||||
iterateSelectionRows(*m_selection, [&](int x, int y) {
|
|
||||||
auto pt = ox::Point{x, y};
|
|
||||||
const auto&s = activeSubSheet();
|
|
||||||
const auto idx = core::idx(s, pt);
|
|
||||||
const auto c = getPixel(s, m_img.bpp, idx);
|
|
||||||
pt -= m_selection->a;
|
|
||||||
cb->addPixel(pt, c);
|
|
||||||
});
|
|
||||||
turbine::setClipboardObject(m_tctx, std::move(cb));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::paste() {
|
|
||||||
if (!m_selection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto [cb, err] = turbine::getClipboardObject<TileSheetClipboard>(m_tctx);
|
|
||||||
if (err) {
|
|
||||||
oxLogError(err);
|
|
||||||
oxErrf("Could not read clipboard: {}", toStr(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto const&s = activeSubSheet();
|
|
||||||
auto const pt1 = m_selection->a;
|
|
||||||
auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight};
|
|
||||||
pushCommand(ox::make<CutPasteCommand>(CommandId::Paste, m_img, m_activeSubsSheetIdx, pt1, pt2, *cb));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TileSheetEditorModel::acceptsClipboardPayload() const noexcept {
|
|
||||||
auto const cb = getClipboardObject<TileSheetClipboard>(m_tctx);
|
|
||||||
return cb.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::StringView TileSheetEditorModel::palPath() const noexcept {
|
|
||||||
auto [path, err] = m_img.defaultPalette.getPath();
|
|
||||||
if (err) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
constexpr ox::StringView uuidPrefix = "uuid://";
|
|
||||||
if (ox::beginsWith(path, uuidPrefix)) {
|
|
||||||
auto uuid = ox::StringView(&path[uuidPrefix.bytes()], path.bytes() - uuidPrefix.bytes());
|
|
||||||
auto out = keelCtx(m_tctx).uuidToPath.at(uuid);
|
|
||||||
if (out.error) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return *out.value;
|
|
||||||
} else {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::setPalette(ox::StringView path) noexcept {
|
|
||||||
OX_REQUIRE(uuid, keelCtx(m_tctx).pathToUuid.at(path));
|
|
||||||
pushCommand(ox::make<PaletteChangeCommand>(activeSubSheetIdx(), m_img, uuid->toString()));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::setPalettePage(size_t pg) noexcept {
|
|
||||||
m_palettePage = ox::clamp<size_t>(pg, 0, m_pal->pages.size() - 1);
|
|
||||||
m_updated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t TileSheetEditorModel::palettePage() const noexcept {
|
|
||||||
return m_palettePage;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::drawCommand(ox::Point const&pt, std::size_t palIdx) noexcept {
|
|
||||||
const auto &activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx);
|
|
||||||
if (pt.x >= activeSubSheet.columns * TileWidth || pt.y >= activeSubSheet.rows * TileHeight) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto idx = core::idx(activeSubSheet, pt);
|
|
||||||
if (m_ongoingDrawCommand) {
|
|
||||||
m_updated = m_updated || m_ongoingDrawCommand->append(idx);
|
|
||||||
} else if (getPixel(activeSubSheet, m_img.bpp, idx) != palIdx) {
|
|
||||||
pushCommand(ox::make<DrawCommand>(m_img, m_activeSubsSheetIdx, idx, static_cast<int>(palIdx)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::endDrawCommand() noexcept {
|
|
||||||
m_ongoingDrawCommand = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::addSubsheet(TileSheet::SubSheetIdx const&parentIdx) noexcept {
|
|
||||||
pushCommand(ox::make<AddSubSheetCommand>(m_img, parentIdx));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::rmSubsheet(TileSheet::SubSheetIdx const&idx) noexcept {
|
|
||||||
pushCommand(ox::make<RmSubSheetCommand>(m_img, idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::insertTiles(TileSheet::SubSheetIdx const&idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
|
||||||
pushCommand(ox::make<InsertTilesCommand>(m_img, idx, tileIdx, tileCnt));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::deleteTiles(TileSheet::SubSheetIdx const&idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
|
||||||
pushCommand(ox::make<DeleteTilesCommand>(m_img, idx, tileIdx, tileCnt));
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::updateSubsheet(TileSheet::SubSheetIdx const&idx, ox::StringView const&name, int cols, int rows) noexcept {
|
|
||||||
pushCommand(ox::make<UpdateSubSheetCommand>(m_img, idx, ox::String(name), cols, rows));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::setActiveSubsheet(TileSheet::SubSheetIdx const&idx) noexcept {
|
|
||||||
m_activeSubsSheetIdx = idx;
|
|
||||||
this->activeSubsheetChanged.emit(m_activeSubsSheetIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::fill(ox::Point const&pt, int palIdx) noexcept {
|
|
||||||
auto const&activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx);
|
|
||||||
// build idx list
|
|
||||||
if (pt.x >= activeSubSheet.columns * TileWidth || pt.y >= activeSubSheet.rows * TileHeight) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ox::Array<bool, PixelsPerTile> updateMap = {};
|
|
||||||
auto const oldColor = getPixel(activeSubSheet, m_img.bpp, pt);
|
|
||||||
getFillPixels(updateMap, pt, oldColor);
|
|
||||||
ox::Vector<std::size_t> idxList;
|
|
||||||
auto i = core::idx(activeSubSheet, pt) / PixelsPerTile * PixelsPerTile;
|
|
||||||
for (auto u : updateMap) {
|
|
||||||
if (u) {
|
|
||||||
idxList.emplace_back(i);
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
// do updates to sheet
|
|
||||||
if (m_ongoingDrawCommand) {
|
|
||||||
m_updated = m_updated || m_ongoingDrawCommand->append(idxList);
|
|
||||||
} else if (getPixel(activeSubSheet, m_img.bpp, pt) != palIdx) {
|
|
||||||
pushCommand(ox::make<DrawCommand>(m_img, m_activeSubsSheetIdx, idxList, palIdx));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::setSelection(studio::Selection const&sel) noexcept {
|
|
||||||
m_selection.emplace(sel);
|
|
||||||
m_updated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::select(ox::Point const&pt) noexcept {
|
|
||||||
if (m_selTracker.updateCursorPoint(pt)) {
|
|
||||||
setSelection(m_selTracker.selection());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::completeSelection() noexcept {
|
|
||||||
if (m_selTracker.selectionOngoing()) {
|
|
||||||
m_selTracker.finishSelection();
|
|
||||||
m_selection.emplace(m_selTracker.selection());
|
|
||||||
auto&pt = m_selection->b;
|
|
||||||
auto&s = activeSubSheet();
|
|
||||||
pt.x = ox::min(s.columns * TileWidth - 1, pt.x);
|
|
||||||
pt.y = ox::min(s.rows * TileHeight - 1, pt.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::clearSelection() noexcept {
|
|
||||||
m_updated = true;
|
|
||||||
m_selTracker.reset();
|
|
||||||
m_selection.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TileSheetEditorModel::updated() const noexcept {
|
|
||||||
return m_updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::markUpdatedCmdId(studio::UndoCommand const*cmd) noexcept {
|
|
||||||
m_updated = true;
|
|
||||||
const auto cmdId = cmd->commandId();
|
|
||||||
if (static_cast<CommandId>(cmdId) == CommandId::PaletteChange) {
|
|
||||||
OX_RETURN_ERROR(readObj<Palette>(keelCtx(m_tctx), m_img.defaultPalette).moveTo(m_pal));
|
|
||||||
m_palettePage = ox::min<size_t>(m_pal->pages.size(), 0);
|
|
||||||
paletteChanged.emit();
|
|
||||||
}
|
|
||||||
auto tsCmd = dynamic_cast<const TileSheetCommand*>(cmd);
|
|
||||||
auto idx = validateSubSheetIdx(m_img, tsCmd->subsheetIdx());
|
|
||||||
if (idx != m_activeSubsSheetIdx) {
|
|
||||||
setActiveSubsheet(idx);
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::markUpdated() noexcept {
|
|
||||||
m_updated = true;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::ackUpdate() noexcept {
|
|
||||||
m_updated = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::saveFile() noexcept {
|
|
||||||
return m_sctx.project->writeObj(m_path, m_img, ox::ClawFormat::Metal);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TileSheetEditorModel::pixelSelected(std::size_t idx) const noexcept {
|
|
||||||
auto const&s = activeSubSheet();
|
|
||||||
auto const pt = idxToPt(static_cast<int>(idx), s.columns);
|
|
||||||
return m_selection && m_selection->contains(pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::getFillPixels(ox::Span<bool> pixels, ox::Point const&pt, int oldColor) const noexcept {
|
|
||||||
const auto &activeSubSheet = this->activeSubSheet();
|
|
||||||
const auto tileIdx = [activeSubSheet](const ox::Point &pt) noexcept {
|
|
||||||
return ptToIdx(pt, activeSubSheet.columns) / PixelsPerTile;
|
|
||||||
};
|
|
||||||
// get points
|
|
||||||
const auto leftPt = pt + ox::Point(-1, 0);
|
|
||||||
const auto rightPt = pt + ox::Point(1, 0);
|
|
||||||
const auto topPt = pt + ox::Point(0, -1);
|
|
||||||
const auto bottomPt = pt + ox::Point(0, 1);
|
|
||||||
// calculate indices
|
|
||||||
const auto idx = ptToIdx(pt, activeSubSheet.columns);
|
|
||||||
const auto leftIdx = ptToIdx(leftPt, activeSubSheet.columns);
|
|
||||||
const auto rightIdx = ptToIdx(rightPt, activeSubSheet.columns);
|
|
||||||
const auto topIdx = ptToIdx(topPt, activeSubSheet.columns);
|
|
||||||
const auto bottomIdx = ptToIdx(bottomPt, activeSubSheet.columns);
|
|
||||||
const auto tile = tileIdx(pt);
|
|
||||||
// mark pixels to update
|
|
||||||
pixels[idx % PixelsPerTile] = true;
|
|
||||||
if (!pixels[leftIdx % PixelsPerTile] && tile == tileIdx(leftPt) && getPixel(activeSubSheet, m_img.bpp, leftIdx) == oldColor) {
|
|
||||||
getFillPixels(pixels, leftPt, oldColor);
|
|
||||||
}
|
|
||||||
if (!pixels[rightIdx % PixelsPerTile] && tile == tileIdx(rightPt) && getPixel(activeSubSheet, m_img.bpp, rightIdx) == oldColor) {
|
|
||||||
getFillPixels(pixels, rightPt, oldColor);
|
|
||||||
}
|
|
||||||
if (!pixels[topIdx % PixelsPerTile] && tile == tileIdx(topPt) && getPixel(activeSubSheet, m_img.bpp, topIdx) == oldColor) {
|
|
||||||
getFillPixels(pixels, topPt, oldColor);
|
|
||||||
}
|
|
||||||
if (!pixels[bottomIdx % PixelsPerTile] && tile == tileIdx(bottomPt) && getPixel(activeSubSheet, m_img.bpp, bottomIdx) == oldColor) {
|
|
||||||
getFillPixels(pixels, bottomPt, oldColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TileSheetEditorModel::pushCommand(studio::UndoCommand *cmd) noexcept {
|
|
||||||
std::ignore = m_undoStack.push(ox::UPtr<studio::UndoCommand>(cmd));
|
|
||||||
m_ongoingDrawCommand = dynamic_cast<DrawCommand*>(cmd);
|
|
||||||
m_updated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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/math.hpp>
|
||||||
#include <ox/std/types.hpp>
|
#include <ox/std/types.hpp>
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
using Color16 = uint16_t;
|
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.
|
* bit colors in some implementations.
|
||||||
*/
|
*/
|
||||||
using Color32 = uint32_t;
|
using Color32 = uint32_t;
|
||||||
@ -154,7 +154,7 @@ static_assert(color16(16, 32, 8) == 9200);
|
|||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr Color16 applySelectionColor(Color16 const color) noexcept {
|
constexpr Color16 applySelectionColor(Color16 const color) noexcept {
|
||||||
namespace core = nostalgia::core;
|
namespace core = nostalgia::gfx;
|
||||||
auto const r = core::red16(color) / 2;
|
auto const r = core::red16(color) / 2;
|
||||||
auto const g = (core::green16(color) + 20) / 2;
|
auto const g = (core::green16(color) + 20) / 2;
|
||||||
auto const b = (core::blue16(color) + 31) / 2;
|
auto const b = (core::blue16(color) + 31) / 2;
|
@ -6,13 +6,14 @@
|
|||||||
|
|
||||||
#include <ox/std/stringliteral.hpp>
|
#include <ox/std/stringliteral.hpp>
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
constexpr auto TileWidth = 8;
|
constexpr auto TileWidth = 8;
|
||||||
constexpr auto TileHeight = 8;
|
constexpr auto TileHeight = 8;
|
||||||
constexpr auto PixelsPerTile = TileWidth * TileHeight;
|
constexpr auto PixelsPerTile = TileWidth * TileHeight;
|
||||||
|
|
||||||
constexpr ox::StringLiteral FileExt_ng("ng");
|
constexpr ox::StringLiteral FileExt_ng("ng");
|
||||||
|
constexpr ox::StringLiteral FileExt_nts("nts");
|
||||||
constexpr ox::StringLiteral FileExt_npal("npal");
|
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 "palette.hpp"
|
||||||
#include "tilesheet.hpp"
|
#include "tilesheet.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
struct Sprite {
|
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;
|
static constexpr auto TypeVersion = 1;
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
@ -46,7 +46,7 @@ OX_MODEL_BEGIN(Sprite)
|
|||||||
OX_MODEL_END()
|
OX_MODEL_END()
|
||||||
|
|
||||||
struct BgTile {
|
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;
|
static constexpr auto TypeVersion = 1;
|
||||||
unsigned tileIdx = 0;
|
unsigned tileIdx = 0;
|
||||||
unsigned palBank = 0;
|
unsigned palBank = 0;
|
||||||
@ -62,7 +62,7 @@ OX_MODEL_BEGIN(BgTile)
|
|||||||
OX_MODEL_END()
|
OX_MODEL_END()
|
||||||
|
|
||||||
struct TileSheetSetEntrySection {
|
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;
|
static constexpr auto TypeVersion = 1;
|
||||||
int32_t begin = 0;
|
int32_t begin = 0;
|
||||||
int32_t tiles = 0;
|
int32_t tiles = 0;
|
||||||
@ -78,7 +78,7 @@ OX_MODEL_BEGIN(TileSheetSetEntrySection)
|
|||||||
OX_MODEL_END()
|
OX_MODEL_END()
|
||||||
|
|
||||||
struct TileSheetSetEntry {
|
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;
|
static constexpr auto TypeVersion = 1;
|
||||||
ox::FileAddress tilesheet;
|
ox::FileAddress tilesheet;
|
||||||
ox::Vector<TileSheetSetEntrySection> sections;
|
ox::Vector<TileSheetSetEntrySection> sections;
|
||||||
@ -90,7 +90,7 @@ OX_MODEL_BEGIN(TileSheetSetEntry)
|
|||||||
OX_MODEL_END()
|
OX_MODEL_END()
|
||||||
|
|
||||||
struct TileSheetSet {
|
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 TypeVersion = 1;
|
||||||
static constexpr auto Preloadable = true;
|
static constexpr auto Preloadable = true;
|
||||||
int32_t bpp = 0;
|
int32_t bpp = 0;
|
||||||
@ -102,8 +102,6 @@ OX_MODEL_BEGIN(TileSheetSet)
|
|||||||
OX_MODEL_FIELD(entries)
|
OX_MODEL_FIELD(entries)
|
||||||
OX_MODEL_END()
|
OX_MODEL_END()
|
||||||
|
|
||||||
void addEntry(TileSheetSet &set, ox::FileAddress path, int32_t begin = 0, int32_t size = -1) noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
int tileColumns(Context&) noexcept;
|
int tileColumns(Context&) noexcept;
|
||||||
|
|
||||||
@ -144,6 +142,10 @@ ox::Error loadBgTileSheet(
|
|||||||
unsigned cbb,
|
unsigned cbb,
|
||||||
TileSheetSet const&set) noexcept;
|
TileSheetSet const&set) noexcept;
|
||||||
|
|
||||||
|
void clearCbb(Context &ctx, unsigned cbb) noexcept;
|
||||||
|
|
||||||
|
void clearCbbs(Context &ctx) noexcept;
|
||||||
|
|
||||||
ox::Error loadBgTileSheet(
|
ox::Error loadBgTileSheet(
|
||||||
Context &ctx,
|
Context &ctx,
|
||||||
unsigned cbb,
|
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";
|
constexpr ox::CStringView GlslVersion = "#version 330";
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
ox::Size drawSize(int scale = 5) noexcept;
|
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>
|
#include <ox/std/types.hpp>
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
struct InitParams {
|
struct InitParams {
|
||||||
bool glInstallDrawer = true;
|
bool glInstallDrawer = true;
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <keel/module.hpp>
|
#include <keel/module.hpp>
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
const keel::Module *keelModule() noexcept;
|
const keel::Module *keelModule() noexcept;
|
||||||
|
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "color.hpp"
|
#include "color.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
struct PaletteColorV1 {
|
struct PaletteColorV1 {
|
||||||
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.PaletteColor";
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.PaletteColor";
|
||||||
@ -33,7 +33,31 @@ OX_MODEL_BEGIN(PaletteColorV1)
|
|||||||
OX_MODEL_FIELD(a)
|
OX_MODEL_FIELD(a)
|
||||||
OX_MODEL_END()
|
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 {
|
struct PalettePageV1 {
|
||||||
@ -58,7 +82,31 @@ OX_MODEL_BEGIN(PalettePageV1)
|
|||||||
OX_MODEL_FIELD(colors)
|
OX_MODEL_FIELD(colors)
|
||||||
OX_MODEL_END()
|
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 {
|
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 {
|
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 TypeVersion = 1;
|
||||||
static constexpr auto Preloadable = true;
|
static constexpr auto Preloadable = true;
|
||||||
ox::Vector<ox::Vector<Color16>> pages{};
|
ox::Vector<ox::Vector<Color16>> pages{};
|
||||||
@ -207,7 +285,7 @@ using CompactPalette = CompactPaletteV1;
|
|||||||
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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]] {
|
if (page < pal.pages.size() && idx < pal.pages[page].colors.size()) [[likely]] {
|
||||||
return pal.pages[page].colors[idx];
|
return pal.pages[page].colors[idx];
|
||||||
}
|
}
|
||||||
@ -215,7 +293,7 @@ constexpr Color16 color(Palette const&pal, size_t page, size_t idx) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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]] {
|
if (page < pal.pages.size() && idx < pal.pages[page].size()) [[likely]] {
|
||||||
return pal.pages[page][idx];
|
return pal.pages[page][idx];
|
||||||
}
|
}
|
||||||
@ -223,37 +301,37 @@ constexpr Color16 color(CompactPalette const&pal, size_t page, size_t idx) noexc
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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);
|
return color(pal, 0, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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);
|
return color(pal, 0, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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;
|
return pal.pages[page].colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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];
|
return pal.pages[page];
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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];
|
return pal.pages[page];
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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];
|
return pal.pages[page];
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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]] {
|
if (page < pal.pages.size()) [[likely]] {
|
||||||
return pal.pages[page].colors.size();
|
return pal.pages[page].colors.size();
|
||||||
}
|
}
|
||||||
@ -261,7 +339,7 @@ constexpr size_t colorCnt(Palette const&pal, size_t page = 0) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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]] {
|
if (page < pal.pages.size()) [[likely]] {
|
||||||
return pal.pages[page].size();
|
return pal.pages[page].size();
|
||||||
}
|
}
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "consts.hpp"
|
#include "consts.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr std::size_t ptToIdx(int x, int y, int c, int scale = 1) noexcept {
|
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>
|
#include <studio/studio.hpp>
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
const studio::Module *studioModule() noexcept;
|
const studio::Module *studioModule() noexcept;
|
||||||
|
|
@ -5,18 +5,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ox/fs/fs.hpp>
|
#include <ox/fs/fs.hpp>
|
||||||
#include <ox/std/array.hpp>
|
|
||||||
#include <ox/std/point.hpp>
|
#include <ox/std/point.hpp>
|
||||||
#include <ox/std/size.hpp>
|
#include <ox/std/size.hpp>
|
||||||
#include <ox/std/span.hpp>
|
|
||||||
#include <ox/std/types.hpp>
|
#include <ox/std/types.hpp>
|
||||||
#include <ox/model/def.hpp>
|
#include <ox/model/def.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/ptidxconv.hpp>
|
#include <nostalgia/gfx/ptidxconv.hpp>
|
||||||
|
|
||||||
#include "palette.hpp"
|
#include "palette.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
// Predecessor to TileSheet, kept for backward compatibility
|
// Predecessor to TileSheet, kept for backward compatibility
|
||||||
struct TileSheetV1 {
|
struct TileSheetV1 {
|
||||||
@ -37,7 +35,7 @@ constexpr bool valid(TileSheetV1 const&ts) noexcept {
|
|||||||
return (ts.bpp == 4 || ts.bpp == 8) && ts.pixels.size() == bytes;
|
return (ts.bpp == 4 || ts.bpp == 8) && ts.pixels.size() == bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ox::Error repair(TileSheetV1 &ts, int bpp) noexcept {
|
constexpr ox::Error repair(TileSheetV1 &ts, int const bpp) noexcept {
|
||||||
auto const bytes = static_cast<size_t>(ts.columns * ts.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
auto const bytes = static_cast<size_t>(ts.columns * ts.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||||
ts.pixels.resize(bytes);
|
ts.pixels.resize(bytes);
|
||||||
return {};
|
return {};
|
||||||
@ -86,7 +84,7 @@ constexpr bool valid(TileSheetV2 const&ts) noexcept {
|
|||||||
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void repair(TileSheetV2::SubSheet &ss, int bpp) noexcept {
|
constexpr void repair(TileSheetV2::SubSheet &ss, int const bpp) noexcept {
|
||||||
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||||
ss.pixels.resize(bytes);
|
ss.pixels.resize(bytes);
|
||||||
for (auto &s : ss.subsheets) {
|
for (auto &s : ss.subsheets) {
|
||||||
@ -156,7 +154,7 @@ constexpr bool valid(TileSheetV3 const&ts) noexcept {
|
|||||||
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void repair(TileSheetV3::SubSheet &ss, int bpp) noexcept {
|
constexpr void repair(TileSheetV3::SubSheet &ss, int const bpp) noexcept {
|
||||||
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||||
ss.pixels.resize(bytes);
|
ss.pixels.resize(bytes);
|
||||||
for (auto &s : ss.subsheets) {
|
for (auto &s : ss.subsheets) {
|
||||||
@ -212,6 +210,10 @@ struct TileSheetV4 {
|
|||||||
pixels(std::move(pPixels)) {
|
pixels(std::move(pPixels)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the dimensional size of the SubSheet (e.g. width * height)
|
||||||
|
*/
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr std::size_t size() const noexcept {
|
constexpr std::size_t size() const noexcept {
|
||||||
return static_cast<std::size_t>(columns) * static_cast<std::size_t>(rows);
|
return static_cast<std::size_t>(columns) * static_cast<std::size_t>(rows);
|
||||||
@ -233,10 +235,12 @@ struct TileSheetV4 {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr bool valid(TileSheetV4::SubSheet const&ss, int bpp) noexcept {
|
constexpr bool valid(TileSheetV4::SubSheet const&ss, int bpp) noexcept {
|
||||||
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||||
return ox::all_of(ss.subsheets.begin(), ss.subsheets.end(),
|
return
|
||||||
[bpp, bytes](TileSheetV4::SubSheet const&s) {
|
(ss.pixels.empty() || ss.subsheets.empty()) &&
|
||||||
return bytes == s.pixels.size() && valid(s, bpp);
|
ox::all_of(ss.subsheets.begin(), ss.subsheets.end(),
|
||||||
});
|
[bpp, bytes](TileSheetV4::SubSheet const&s) {
|
||||||
|
return bytes == s.pixels.size() && valid(s, bpp);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
@ -244,9 +248,15 @@ constexpr bool valid(TileSheetV4 const&ts) noexcept {
|
|||||||
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void repair(TileSheetV4::SubSheet &ss, int bpp) noexcept {
|
constexpr void repair(TileSheetV4::SubSheet &ss, int const bpp) noexcept {
|
||||||
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
if (ss.subsheets.empty()) {
|
||||||
ss.pixels.resize(bytes);
|
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||||
|
ss.pixels.resize(bytes);
|
||||||
|
} else {
|
||||||
|
ss.pixels.clear();
|
||||||
|
ss.columns = -1;
|
||||||
|
ss.rows = -1;
|
||||||
|
}
|
||||||
for (auto &s : ss.subsheets) {
|
for (auto &s : ss.subsheets) {
|
||||||
repair(s, bpp);
|
repair(s, bpp);
|
||||||
}
|
}
|
||||||
@ -261,7 +271,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) 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
using TileSheet = TileSheetV5;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
std::size_t idx(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept;
|
std::size_t idx(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept;
|
||||||
@ -273,100 +385,69 @@ size_t getTileCnt(TileSheet const&ts) noexcept;
|
|||||||
TileSheet::SubSheet const*getSubsheet(TileSheet const&ts, SubSheetId id) noexcept;
|
TileSheet::SubSheet const*getSubsheet(TileSheet const&ts, SubSheetId id) noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
size_t getTileIdx(TileSheet const&ts, SubSheetId id) noexcept;
|
ox::Optional<size_t> getTileIdx(TileSheet const&ts, SubSheetId id) noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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]]
|
[[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]]
|
void setPixel(TileSheet::SubSheet &ss, ox::Point const&pt, uint8_t palIdx) noexcept;
|
||||||
uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, std::size_t idx) noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
ox::Error setPixelCount(TileSheet::SubSheet &ss, std::size_t cnt) noexcept;
|
||||||
uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
void flipX(TileSheet::SubSheet &ss, ox::Point const &a, ox::Point const &b) noexcept;
|
||||||
uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
void flipY(TileSheet::SubSheet &ss, ox::Point const &a, ox::Point const &b) noexcept;
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a count of the pixels in this sheet, and not that of its children.
|
* 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
|
* @return a count of the pixels in this sheet
|
||||||
*/
|
*/
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept;
|
unsigned pixelCnt(TileSheet::SubSheet const&ss) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param ss
|
* @param ss
|
||||||
* @param pBpp
|
|
||||||
* @param sz size of Subsheet in tiles (not pixels)
|
* @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
|
* validateSubSheetIdx takes a SubSheetIdx and moves the index to the
|
||||||
* preceding or parent sheet if the current corresponding sheet does
|
* preceding or parent sheet if the current corresponding sheet does
|
||||||
* not exist.
|
* not exist.
|
||||||
|
* @param ts
|
||||||
* @param idx SubSheetIdx to validate and correct
|
* @param idx SubSheetIdx to validate and correct
|
||||||
* @return a valid version of idx
|
* @return a valid version of idx
|
||||||
*/
|
*/
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx idx) noexcept;
|
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]]
|
[[nodiscard]]
|
||||||
TileSheet::SubSheet &getSubSheet(
|
TileSheet::SubSheet &getSubSheet(
|
||||||
TileSheet::SubSheetIdx const&idx,
|
ox::SpanView<uint32_t> const&idx,
|
||||||
std::size_t idxIt,
|
std::size_t idxIt,
|
||||||
TileSheet::SubSheet &pSubsheet) noexcept;
|
TileSheet::SubSheet &pSubsheet) noexcept;
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 13
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdangling-reference"
|
||||||
|
#endif
|
||||||
[[nodiscard]]
|
[[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]]
|
[[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 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(
|
ox::Error rmSubSheet(
|
||||||
TileSheet &ts,
|
TileSheet &ts,
|
||||||
@ -377,13 +458,7 @@ ox::Error rmSubSheet(
|
|||||||
ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept;
|
ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
uint8_t getPixel4Bpp(
|
uint8_t getPixel(
|
||||||
TileSheet const&ts,
|
|
||||||
ox::Point const&pt,
|
|
||||||
TileSheet::SubSheetIdx const&subsheetIdx) noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
uint8_t getPixel8Bpp(
|
|
||||||
TileSheet const&ts,
|
TileSheet const&ts,
|
||||||
ox::Point const&pt,
|
ox::Point const&pt,
|
||||||
TileSheet::SubSheetIdx const&subsheetIdx) noexcept;
|
TileSheet::SubSheetIdx const&subsheetIdx) noexcept;
|
||||||
@ -392,6 +467,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<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::SubSheet const&ss, SubSheetId pId) noexcept;
|
||||||
|
|
||||||
ox::Result<ox::StringView> getNameFor(TileSheet const&ts, SubSheetId pId) noexcept;
|
ox::Result<ox::StringView> getNameFor(TileSheet const&ts, SubSheetId pId) noexcept;
|
||||||
@ -401,7 +478,7 @@ ox::Vector<uint8_t> pixels(TileSheet &ts) noexcept;
|
|||||||
|
|
||||||
|
|
||||||
struct CompactTileSheetV1 {
|
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 TypeVersion = 1;
|
||||||
static constexpr auto Preloadable = true;
|
static constexpr auto Preloadable = true;
|
||||||
int8_t bpp = 0;
|
int8_t bpp = 0;
|
||||||
@ -491,6 +568,22 @@ OX_MODEL_BEGIN(TileSheetV4)
|
|||||||
OX_MODEL_FIELD(subsheet)
|
OX_MODEL_FIELD(subsheet)
|
||||||
OX_MODEL_END()
|
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_BEGIN(CompactTileSheetV1)
|
||||||
OX_MODEL_FIELD(bpp)
|
OX_MODEL_FIELD(bpp)
|
||||||
OX_MODEL_FIELD(defaultPalette)
|
OX_MODEL_FIELD(defaultPalette)
|
@ -1,5 +1,5 @@
|
|||||||
add_library(
|
add_library(
|
||||||
NostalgiaCore
|
NostalgiaGfx
|
||||||
gfx.cpp
|
gfx.cpp
|
||||||
tilesheet.cpp
|
tilesheet.cpp
|
||||||
)
|
)
|
||||||
@ -10,12 +10,12 @@ if(NOT BUILDCORE_TARGET STREQUAL "gba")
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
NostalgiaCore PUBLIC
|
NostalgiaGfx PUBLIC
|
||||||
../include
|
../include
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
NostalgiaCore PUBLIC
|
NostalgiaGfx PUBLIC
|
||||||
Turbine
|
Turbine
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ endif()
|
|||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS
|
TARGETS
|
||||||
NostalgiaCore
|
NostalgiaGfx
|
||||||
DESTINATION
|
DESTINATION
|
||||||
LIBRARY DESTINATION lib
|
LIBRARY DESTINATION lib
|
||||||
ARCHIVE DESTINATION lib
|
ARCHIVE DESTINATION lib
|
@ -1,15 +1,15 @@
|
|||||||
add_library(
|
add_library(
|
||||||
NostalgiaCore-GBA OBJECT
|
NostalgiaGfx-GBA OBJECT
|
||||||
context.cpp
|
context.cpp
|
||||||
gfx.cpp
|
gfx.cpp
|
||||||
panic.cpp
|
panic.cpp
|
||||||
)
|
)
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
NostalgiaCore-GBA PUBLIC
|
NostalgiaGfx-GBA PUBLIC
|
||||||
../../include
|
../../include
|
||||||
)
|
)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
NostalgiaCore-GBA PUBLIC
|
NostalgiaGfx-GBA PUBLIC
|
||||||
TeaGBA
|
TeaGBA
|
||||||
Keel
|
Keel
|
||||||
Turbine
|
Turbine
|
||||||
@ -17,5 +17,5 @@ target_link_libraries(
|
|||||||
|
|
||||||
if(BUILDCORE_TARGET STREQUAL "gba")
|
if(BUILDCORE_TARGET STREQUAL "gba")
|
||||||
set_source_files_properties(gfx.cpp PROPERTIES COMPILE_FLAGS -marm)
|
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()
|
endif()
|
@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
#include <turbine/turbine.hpp>
|
#include <turbine/turbine.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/gfx.hpp>
|
#include <nostalgia/gfx/gfx.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
void ContextDeleter::operator()(Context *p) noexcept {
|
void safeDelete(Context *ctx) noexcept {
|
||||||
ox::safeDelete(p);
|
delete ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context::Context(turbine::Context &tctx) noexcept: turbineCtx(tctx) {
|
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::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);
|
auto ctx = ox::make_unique<Context>(tctx);
|
||||||
OX_RETURN_ERROR(initGfx(*ctx, params));
|
OX_RETURN_ERROR(initGfx(*ctx, params));
|
||||||
return ContextUPtr(std::move(ctx));
|
return ox::UPtr<Context>(std::move(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
keel::Context &keelCtx(Context &ctx) noexcept {
|
keel::Context &keelCtx(Context &ctx) noexcept {
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <nostalgia/core/context.hpp>
|
#include <nostalgia/gfx/context.hpp>
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
struct BgCbbData {
|
struct BgCbbData {
|
||||||
unsigned bpp = 4;
|
unsigned bpp = 4;
|
@ -11,15 +11,15 @@
|
|||||||
|
|
||||||
#include <keel/keel.hpp>
|
#include <keel/keel.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/context.hpp>
|
#include <nostalgia/gfx/context.hpp>
|
||||||
#include <nostalgia/core/gfx.hpp>
|
#include <nostalgia/gfx/gfx.hpp>
|
||||||
#include <nostalgia/core/tilesheet.hpp>
|
#include <nostalgia/gfx/tilesheet.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
|
|
||||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
static constexpr auto SpriteCount = 128;
|
static constexpr auto SpriteCount = 128;
|
||||||
|
|
||||||
@ -63,6 +63,19 @@ ox::Error loadSpritePalette(
|
|||||||
return {};
|
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(
|
static ox::Error loadTileSheetSet(
|
||||||
Context &ctx,
|
Context &ctx,
|
||||||
ox::Span<uint16_t> tileMapTargetMem,
|
ox::Span<uint16_t> tileMapTargetMem,
|
||||||
@ -99,10 +112,10 @@ ox::Error loadBgTileSheet(
|
|||||||
size_t const tileCnt) noexcept {
|
size_t const tileCnt) noexcept {
|
||||||
size_t const bppMod = ts.bpp == 4;
|
size_t const bppMod = ts.bpp == 4;
|
||||||
size_t const bytesPerTile = PixelsPerTile >> bppMod;
|
size_t const bytesPerTile = PixelsPerTile >> bppMod;
|
||||||
auto const pixCnt = tileCnt * bytesPerTile;
|
auto const cnt = (tileCnt * bytesPerTile) / 2;
|
||||||
auto const srcPxIdx = srcTileIdx * bytesPerTile;
|
auto const srcPxIdx = srcTileIdx * bytesPerTile;
|
||||||
auto const dstPxIdx = (dstTileIdx * bytesPerTile) / 2;
|
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 srcIdx = srcPxIdx + i * 2;
|
||||||
auto const p1 = static_cast<uint16_t>(ts.pixels[srcIdx]);
|
auto const p1 = static_cast<uint16_t>(ts.pixels[srcIdx]);
|
||||||
auto const p2 = static_cast<uint16_t>(ts.pixels[srcIdx + 1]);
|
auto const p2 = static_cast<uint16_t>(ts.pixels[srcIdx + 1]);
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#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;
|
ox::Error initGfx(Context &ctx, InitParams const&) noexcept;
|
||||||
}
|
}
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <ox/std/def.hpp>
|
#include <ox/std/def.hpp>
|
||||||
|
#include <ox/std/realstd.hpp>
|
||||||
|
|
||||||
#include <keel/media.hpp>
|
#include <keel/media.hpp>
|
||||||
#include <turbine/turbine.hpp>
|
#include <turbine/turbine.hpp>
|
||||||
@ -11,7 +12,7 @@
|
|||||||
#include <teagba/addresses.hpp>
|
#include <teagba/addresses.hpp>
|
||||||
#include <teagba/bios.hpp>
|
#include <teagba/bios.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/core.hpp>
|
#include <nostalgia/gfx/core.hpp>
|
||||||
|
|
||||||
#include "gfx.hpp"
|
#include "gfx.hpp"
|
||||||
|
|
||||||
@ -21,7 +22,7 @@
|
|||||||
|
|
||||||
namespace ox {
|
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 {
|
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
|
// 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 Message:\t{}\n", err.msg);
|
||||||
}
|
}
|
||||||
oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
|
oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
|
||||||
if (err.file != nullptr) {
|
if (err.src.file_name() != nullptr) {
|
||||||
oxErrf("\tError Location:\t{}:{}\n", err.file, err.line);
|
oxErrf("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line());
|
||||||
}
|
}
|
||||||
// disable all interrupt handling and IntrWait on no interrupts
|
abort();
|
||||||
REG_IE = 0;
|
|
||||||
teagba::intrwait(0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -3,9 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <keel/media.hpp>
|
#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 GbaTileColumns = 32;
|
||||||
constexpr auto GbaTileRows = 32;
|
constexpr auto GbaTileRows = 32;
|
@ -1,18 +1,18 @@
|
|||||||
add_library(
|
add_library(
|
||||||
NostalgiaCore-Keel
|
NostalgiaGfx-Keel
|
||||||
keelmodule.cpp
|
keelmodule.cpp
|
||||||
typeconv.cpp
|
typeconv.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
NostalgiaCore-Keel PUBLIC
|
NostalgiaGfx-Keel PUBLIC
|
||||||
Keel
|
Keel
|
||||||
NostalgiaCore
|
NostalgiaGfx
|
||||||
)
|
)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS
|
TARGETS
|
||||||
NostalgiaCore-Keel
|
NostalgiaGfx-Keel
|
||||||
DESTINATION
|
DESTINATION
|
||||||
LIBRARY DESTINATION lib
|
LIBRARY DESTINATION lib
|
||||||
ARCHIVE DESTINATION lib
|
ARCHIVE DESTINATION lib
|
@ -4,15 +4,14 @@
|
|||||||
|
|
||||||
#include <ox/model/model.hpp>
|
#include <ox/model/model.hpp>
|
||||||
|
|
||||||
#include <keel/asset.hpp>
|
|
||||||
#include <keel/module.hpp>
|
#include <keel/module.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/palette.hpp>
|
#include <nostalgia/gfx/palette.hpp>
|
||||||
#include <nostalgia/core/tilesheet.hpp>
|
#include <nostalgia/gfx/tilesheet.hpp>
|
||||||
|
|
||||||
#include "typeconv.hpp"
|
#include "typeconv.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
static class: public keel::Module {
|
static class: public keel::Module {
|
||||||
private:
|
private:
|
||||||
@ -20,16 +19,18 @@ static class: public keel::Module {
|
|||||||
PaletteV1ToPaletteV2Converter m_paletteV1ToPaletteV2Converter;
|
PaletteV1ToPaletteV2Converter m_paletteV1ToPaletteV2Converter;
|
||||||
PaletteV2ToPaletteV3Converter m_paletteV2ToPaletteV3Converter;
|
PaletteV2ToPaletteV3Converter m_paletteV2ToPaletteV3Converter;
|
||||||
PaletteV3ToPaletteV4Converter m_paletteV3ToPaletteV4Converter;
|
PaletteV3ToPaletteV4Converter m_paletteV3ToPaletteV4Converter;
|
||||||
|
PaletteV4ToPaletteV5Converter m_paletteV4ToPaletteV5Converter;
|
||||||
PaletteToCompactPaletteConverter m_paletteToCompactPaletteConverter;
|
PaletteToCompactPaletteConverter m_paletteToCompactPaletteConverter;
|
||||||
TileSheetV1ToTileSheetV2Converter m_tileSheetV1ToTileSheetV2Converter;
|
TileSheetV1ToTileSheetV2Converter m_tileSheetV1ToTileSheetV2Converter;
|
||||||
TileSheetV2ToTileSheetV3Converter m_tileSheetV2ToTileSheetV3Converter;
|
TileSheetV2ToTileSheetV3Converter m_tileSheetV2ToTileSheetV3Converter;
|
||||||
TileSheetV3ToTileSheetV4Converter m_tileSheetV3ToTileSheetV4Converter;
|
TileSheetV3ToTileSheetV4Converter m_tileSheetV3ToTileSheetV4Converter;
|
||||||
|
TileSheetV4ToTileSheetV5Converter m_tileSheetV4ToTileSheetV5Converter;
|
||||||
TileSheetToCompactTileSheetConverter m_tileSheetToCompactTileSheetConverter;
|
TileSheetToCompactTileSheetConverter m_tileSheetToCompactTileSheetConverter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
ox::String id() const noexcept override {
|
ox::String id() const noexcept override {
|
||||||
return ox::String("net.drinkingtea.nostalgia.core");
|
return ox::String{"net.drinkingtea.nostalgia.gfx"};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
@ -39,11 +40,13 @@ static class: public keel::Module {
|
|||||||
keel::generateTypeDesc<TileSheetV2>,
|
keel::generateTypeDesc<TileSheetV2>,
|
||||||
keel::generateTypeDesc<TileSheetV3>,
|
keel::generateTypeDesc<TileSheetV3>,
|
||||||
keel::generateTypeDesc<TileSheetV4>,
|
keel::generateTypeDesc<TileSheetV4>,
|
||||||
|
keel::generateTypeDesc<TileSheetV5>,
|
||||||
keel::generateTypeDesc<CompactTileSheetV1>,
|
keel::generateTypeDesc<CompactTileSheetV1>,
|
||||||
keel::generateTypeDesc<PaletteV1>,
|
keel::generateTypeDesc<PaletteV1>,
|
||||||
keel::generateTypeDesc<PaletteV2>,
|
keel::generateTypeDesc<PaletteV2>,
|
||||||
keel::generateTypeDesc<PaletteV3>,
|
keel::generateTypeDesc<PaletteV3>,
|
||||||
keel::generateTypeDesc<PaletteV4>,
|
keel::generateTypeDesc<PaletteV4>,
|
||||||
|
keel::generateTypeDesc<PaletteV5>,
|
||||||
keel::generateTypeDesc<CompactPaletteV1>,
|
keel::generateTypeDesc<CompactPaletteV1>,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -55,10 +58,12 @@ static class: public keel::Module {
|
|||||||
&m_paletteV1ToPaletteV2Converter,
|
&m_paletteV1ToPaletteV2Converter,
|
||||||
&m_paletteV2ToPaletteV3Converter,
|
&m_paletteV2ToPaletteV3Converter,
|
||||||
&m_paletteV3ToPaletteV4Converter,
|
&m_paletteV3ToPaletteV4Converter,
|
||||||
|
&m_paletteV4ToPaletteV5Converter,
|
||||||
&m_paletteToCompactPaletteConverter,
|
&m_paletteToCompactPaletteConverter,
|
||||||
&m_tileSheetV1ToTileSheetV2Converter,
|
&m_tileSheetV1ToTileSheetV2Converter,
|
||||||
&m_tileSheetV2ToTileSheetV3Converter,
|
&m_tileSheetV2ToTileSheetV3Converter,
|
||||||
&m_tileSheetV3ToTileSheetV4Converter,
|
&m_tileSheetV3ToTileSheetV4Converter,
|
||||||
|
&m_tileSheetV4ToTileSheetV5Converter,
|
||||||
&m_tileSheetToCompactTileSheetConverter,
|
&m_tileSheetToCompactTileSheetConverter,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -67,23 +72,25 @@ static class: public keel::Module {
|
|||||||
ox::Vector<keel::PackTransform> packTransforms() const noexcept final {
|
ox::Vector<keel::PackTransform> packTransforms() const noexcept final {
|
||||||
return {
|
return {
|
||||||
// convert tilesheets to CompactTileSheets
|
// 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> ||
|
if (typeId == ox::ModelTypeId_v<TileSheetV1> ||
|
||||||
typeId == ox::ModelTypeId_v<TileSheetV2> ||
|
typeId == ox::ModelTypeId_v<TileSheetV2> ||
|
||||||
typeId == ox::ModelTypeId_v<TileSheetV3> ||
|
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>(
|
OX_RETURN_ERROR(keel::convertBuffToBuff<CompactTileSheet>(
|
||||||
ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
|
ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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> ||
|
if (typeId == ox::ModelTypeId_v<NostalgiaPalette> ||
|
||||||
typeId == ox::ModelTypeId_v<PaletteV1> ||
|
typeId == ox::ModelTypeId_v<PaletteV1> ||
|
||||||
typeId == ox::ModelTypeId_v<PaletteV2> ||
|
typeId == ox::ModelTypeId_v<PaletteV2> ||
|
||||||
typeId == ox::ModelTypeId_v<PaletteV3> ||
|
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>(
|
OX_RETURN_ERROR(keel::convertBuffToBuff<CompactPalette>(
|
||||||
ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
|
ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
|
||||||
return true;
|
return true;
|
||||||
@ -92,6 +99,7 @@ static class: public keel::Module {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
} const mod;
|
} const mod;
|
||||||
|
|
||||||
keel::Module const*keelModule() noexcept {
|
keel::Module const*keelModule() noexcept {
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "typeconv.hpp"
|
#include "typeconv.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
ox::Error NostalgiaPaletteToPaletteV1Converter::convert(
|
ox::Error NostalgiaPaletteToPaletteV1Converter::convert(
|
||||||
keel::Context&,
|
keel::Context&,
|
||||||
@ -52,6 +52,26 @@ ox::Error PaletteV3ToPaletteV4Converter::convert(
|
|||||||
return {};
|
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(
|
ox::Error PaletteToCompactPaletteConverter::convert(
|
||||||
keel::Context&,
|
keel::Context&,
|
||||||
Palette &src,
|
Palette &src,
|
||||||
@ -133,12 +153,50 @@ ox::Error TileSheetV3ToTileSheetV4Converter::convert(
|
|||||||
return {};
|
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(
|
ox::Error TileSheetToCompactTileSheetConverter::convert(
|
||||||
keel::Context&,
|
keel::Context&,
|
||||||
TileSheet &src,
|
TileSheet &src,
|
||||||
CompactTileSheet &dst) const noexcept {
|
CompactTileSheet &dst) const noexcept {
|
||||||
dst.bpp = src.bpp;
|
dst.bpp = src.bpp;
|
||||||
dst.defaultPalette = std::move(src.defaultPalette);
|
dst.defaultPalette = ox::FileAddress{src.defaultPalette};
|
||||||
dst.pixels = pixels(src);
|
dst.pixels = pixels(src);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
@ -8,11 +8,11 @@
|
|||||||
|
|
||||||
#include <keel/typeconv.hpp>
|
#include <keel/typeconv.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/context.hpp>
|
#include <nostalgia/gfx/context.hpp>
|
||||||
#include <nostalgia/core/palette.hpp>
|
#include <nostalgia/gfx/palette.hpp>
|
||||||
#include <nostalgia/core/tilesheet.hpp>
|
#include <nostalgia/gfx/tilesheet.hpp>
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
// Type converters
|
// Type converters
|
||||||
|
|
||||||
@ -21,15 +21,19 @@ class NostalgiaPaletteToPaletteV1Converter: public keel::Converter<NostalgiaPale
|
|||||||
};
|
};
|
||||||
|
|
||||||
class PaletteV1ToPaletteV2Converter: public keel::Converter<PaletteV1, PaletteV2> {
|
class PaletteV1ToPaletteV2Converter: public keel::Converter<PaletteV1, PaletteV2> {
|
||||||
ox::Error convert(keel::Context&, PaletteV1 &src, PaletteV2 &dst) const noexcept final;
|
ox::Error convert(keel::Context&, PaletteV1 &src, PaletteV2 &dst) const noexcept final;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PaletteV2ToPaletteV3Converter: public keel::Converter<PaletteV2, PaletteV3> {
|
class PaletteV2ToPaletteV3Converter: public keel::Converter<PaletteV2, PaletteV3> {
|
||||||
ox::Error convert(keel::Context&, PaletteV2 &src, PaletteV3 &dst) const noexcept final;
|
ox::Error convert(keel::Context&, PaletteV2 &src, PaletteV3 &dst) const noexcept final;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PaletteV3ToPaletteV4Converter: public keel::Converter<PaletteV3, PaletteV4> {
|
class PaletteV3ToPaletteV4Converter: public keel::Converter<PaletteV3, PaletteV4> {
|
||||||
ox::Error convert(keel::Context&, PaletteV3 &src, PaletteV4 &dst) const noexcept final;
|
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> {
|
class PaletteToCompactPaletteConverter: public keel::Converter<Palette, CompactPalette> {
|
||||||
@ -56,6 +60,14 @@ class TileSheetV3ToTileSheetV4Converter: public keel::Converter<TileSheetV3, Til
|
|||||||
ox::Error convert(keel::Context&, TileSheetV3 &src, TileSheetV4 &dst) const noexcept final;
|
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> {
|
class TileSheetToCompactTileSheetConverter: public keel::Converter<TileSheet, CompactTileSheet> {
|
||||||
ox::Error convert(keel::Context&, TileSheet &src, CompactTileSheet &dst) const noexcept final;
|
ox::Error convert(keel::Context&, TileSheet &src, CompactTileSheet &dst) const noexcept final;
|
||||||
};
|
};
|
@ -1,9 +1,9 @@
|
|||||||
target_sources(
|
target_sources(
|
||||||
NostalgiaCore PRIVATE
|
NostalgiaGfx PRIVATE
|
||||||
context.cpp
|
context.cpp
|
||||||
gfx.cpp
|
gfx.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
NostalgiaCore PUBLIC
|
NostalgiaGfx PUBLIC
|
||||||
GlUtils
|
GlUtils
|
||||||
)
|
)
|
@ -5,10 +5,10 @@
|
|||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
#include "gfx.hpp"
|
#include "gfx.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
void ContextDeleter::operator()(Context *p) noexcept {
|
void safeDelete(Context *ctx) noexcept {
|
||||||
ox::safeDelete(p);
|
delete ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context::Context(turbine::Context &tctx, InitParams const¶ms) noexcept:
|
Context::Context(turbine::Context &tctx, InitParams const¶ms) noexcept:
|
||||||
@ -23,10 +23,10 @@ Context::~Context() noexcept {
|
|||||||
shutdownGfx(*this);
|
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);
|
auto ctx = ox::make_unique<Context>(tctx, params);
|
||||||
OX_RETURN_ERROR(initGfx(*ctx, params));
|
OX_RETURN_ERROR(initGfx(*ctx, params));
|
||||||
return ContextUPtr(ctx.release());
|
return ox::UPtr<Context>(ctx.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
keel::Context &keelCtx(Context &ctx) noexcept {
|
keel::Context &keelCtx(Context &ctx) noexcept {
|
@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
#include <glutils/glutils.hpp>
|
#include <glutils/glutils.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/gfx.hpp>
|
#include <nostalgia/gfx/gfx.hpp>
|
||||||
#include <nostalgia/core/context.hpp>
|
#include <nostalgia/gfx/context.hpp>
|
||||||
|
|
||||||
#include "gfx.hpp"
|
#include "gfx.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
|
|
@ -10,15 +10,15 @@
|
|||||||
|
|
||||||
#include <glutils/glutils.hpp>
|
#include <glutils/glutils.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/context.hpp>
|
#include <nostalgia/gfx/context.hpp>
|
||||||
#include <nostalgia/core/gfx.hpp>
|
#include <nostalgia/gfx/gfx.hpp>
|
||||||
#include <nostalgia/core/palette.hpp>
|
#include <nostalgia/gfx/palette.hpp>
|
||||||
#include <nostalgia/core/tilesheet.hpp>
|
#include <nostalgia/gfx/tilesheet.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
#include "gfx.hpp"
|
#include "gfx.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
namespace renderer {
|
namespace renderer {
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ static constexpr auto PriorityScale = 0.01f;
|
|||||||
Drawer::Drawer(Context &ctx) noexcept: m_ctx(ctx) {}
|
Drawer::Drawer(Context &ctx) noexcept: m_ctx(ctx) {}
|
||||||
|
|
||||||
void Drawer::draw(turbine::Context &tctx) noexcept {
|
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(
|
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(
|
static void setSpriteBufferObject(
|
||||||
uint_t vi,
|
uint_t const vi,
|
||||||
float enabled,
|
float const enabled,
|
||||||
float x,
|
float x,
|
||||||
float y,
|
float y,
|
||||||
uint_t textureRow,
|
uint_t const textureRow,
|
||||||
uint_t flipX,
|
uint_t const flipX,
|
||||||
uint_t priority,
|
uint_t const priority,
|
||||||
float *vbo,
|
ox::Span<float> const vbo,
|
||||||
GLuint *ebo) noexcept {
|
ox::Span<GLuint> const ebo) noexcept {
|
||||||
// don't worry, this memcpy gets optimized to something much more ideal
|
// don't worry, this memcpy gets optimized to something much more ideal
|
||||||
constexpr float xmod = 0.1f;
|
constexpr float xmod = 0.1f;
|
||||||
constexpr float ymod = 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 + xmod, y + ymod, prif, R, textureRowf + 0, // top right
|
||||||
enabled, x, y + ymod, prif, L, textureRowf + 0, // top left
|
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 {
|
ox::Array<GLuint, SpriteVertexEboLength> const elms {
|
||||||
vi + 0, vi + 1, vi + 2,
|
vi + 0, vi + 1, vi + 2,
|
||||||
vi + 2, vi + 3, vi + 0,
|
vi + 2, vi + 3, vi + 0,
|
||||||
};
|
};
|
||||||
memcpy(ebo, elms.data(), sizeof(elms));
|
ox::spancpy<GLuint>(ebo, elms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setTileBufferObject(
|
static void setTileBufferObject(
|
||||||
uint_t vi,
|
uint_t const vi,
|
||||||
float x,
|
float x,
|
||||||
float y,
|
float y,
|
||||||
float textureTileIdx,
|
float const textureTileIdx,
|
||||||
float priority,
|
float const priority,
|
||||||
float palOffset,
|
float const palOffset,
|
||||||
bool flipX,
|
bool const flipX,
|
||||||
bool flipY,
|
bool const flipY,
|
||||||
float *vbo,
|
ox::Span<float> const vbo,
|
||||||
GLuint *ebo) noexcept {
|
ox::Span<GLuint> const ebo) noexcept {
|
||||||
// don't worry, this memcpy gets optimized to something much more ideal
|
// don't worry, this memcpy gets optimized to something much more ideal
|
||||||
constexpr float ymod = 0.1f;
|
constexpr float ymod = 0.1f;
|
||||||
constexpr float xmod = 0.1f;
|
constexpr float xmod = 0.1f;
|
||||||
@ -170,24 +170,35 @@ static void setTileBufferObject(
|
|||||||
float const T = flipY ? 1 : 0;
|
float const T = flipY ? 1 : 0;
|
||||||
float const B = flipY ? 0 : 1;
|
float const B = flipY ? 0 : 1;
|
||||||
ox::Array<float, BgVertexVboLength> const vertices {
|
ox::Array<float, BgVertexVboLength> const vertices {
|
||||||
x, y, prif, L, B, textureTileIdx, palOffset, // bottom left
|
x, y, prif, L, B, textureTileIdx, palOffset, // bottom left
|
||||||
x + xmod, y, prif, R, B, textureTileIdx, palOffset, // bottom right
|
x + xmod, y, prif, R, B, textureTileIdx, palOffset, // bottom right
|
||||||
x + xmod, y + ymod, prif, R, T, textureTileIdx, palOffset, // top right
|
x + xmod, y + ymod, prif, R, T, textureTileIdx, palOffset, // top right
|
||||||
x, y + ymod, prif, L, T, textureTileIdx, palOffset, // top left
|
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 {
|
ox::Array<GLuint, BgVertexEboLength> const elms {
|
||||||
vi + 0, vi + 1, vi + 2,
|
vi + 0, vi + 1, vi + 2,
|
||||||
vi + 2, vi + 3, vi + 0,
|
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 {
|
static void initSpriteBufferObjects(Context &ctx, glutils::BufferSet &bs) noexcept {
|
||||||
for (auto i = 0u; i < ctx.spriteCount; ++i) {
|
for (auto i = 0u; i < ctx.spriteCount; ++i) {
|
||||||
auto vbo = &bs.vertices[i * static_cast<std::size_t>(SpriteVertexVboLength)];
|
auto const vbo = ox::Span{bs.vertices}
|
||||||
auto ebo = &bs.elements[i * static_cast<std::size_t>(SpriteVertexEboLength)];
|
+ i * static_cast<std::size_t>(SpriteVertexVboLength);
|
||||||
setSpriteBufferObject(i * static_cast<uint_t>(SpriteVertexVboRows) * ctx.blocksPerSprite, 0, 0, 0, 0, false, 0, vbo, ebo);
|
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 x = 0u; x < TileColumns; ++x) {
|
||||||
for (auto y = 0u; y < TileRows; ++y) {
|
for (auto y = 0u; y < TileRows; ++y) {
|
||||||
const auto i = bgVertexRow(x, y);
|
const auto i = bgVertexRow(x, y);
|
||||||
auto vbo = &bs.vertices[i * static_cast<std::size_t>(BgVertexVboLength)];
|
auto const vbo = ox::Span{bs.vertices}
|
||||||
auto ebo = &bs.elements[i * static_cast<std::size_t>(BgVertexEboLength)];
|
+ i * static_cast<std::size_t>(BgVertexVboLength);
|
||||||
|
auto const ebo = ox::Span{bs.elements}
|
||||||
|
+ i * static_cast<std::size_t>(BgVertexEboLength);
|
||||||
setTileBufferObject(
|
setTileBufferObject(
|
||||||
static_cast<uint_t>(i * BgVertexVboRows),
|
static_cast<uint_t>(i * BgVertexVboRows),
|
||||||
static_cast<float>(x),
|
static_cast<float>(x),
|
||||||
@ -421,8 +434,8 @@ static void setSprite(
|
|||||||
auto const eboIdx = eboBase + renderer::SpriteVertexEboLength * i;
|
auto const eboIdx = eboBase + renderer::SpriteVertexEboLength * i;
|
||||||
oxAssert(vboIdx < ctx.spriteBlocks.vertices.size(), "vbo overflow");
|
oxAssert(vboIdx < ctx.spriteBlocks.vertices.size(), "vbo overflow");
|
||||||
oxAssert(eboIdx < ctx.spriteBlocks.elements.size(), "ebo overflow");
|
oxAssert(eboIdx < ctx.spriteBlocks.elements.size(), "ebo overflow");
|
||||||
auto const vbo = &ctx.spriteBlocks.vertices[vboIdx];
|
auto const vbo = ox::Span{ctx.spriteBlocks.vertices} + vboIdx;
|
||||||
auto const ebo = &ctx.spriteBlocks.elements[eboIdx];
|
auto const ebo = ox::Span{ctx.spriteBlocks.elements} + eboIdx;
|
||||||
renderer::setSpriteBufferObject(
|
renderer::setSpriteBufferObject(
|
||||||
static_cast<uint_t>(vboIdx),
|
static_cast<uint_t>(vboIdx),
|
||||||
enabled,
|
enabled,
|
||||||
@ -436,7 +449,7 @@ static void setSprite(
|
|||||||
++i;
|
++i;
|
||||||
};
|
};
|
||||||
if (!s.flipX) {
|
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) {
|
for (auto xIt = 0u; xIt < dim.x; ++xIt) {
|
||||||
set(static_cast<int>(xIt), static_cast<int>(yIt), s.enabled);
|
set(static_cast<int>(xIt), static_cast<int>(yIt), s.enabled);
|
||||||
}
|
}
|
||||||
@ -556,7 +569,7 @@ static void copyPixels(
|
|||||||
CompactTileSheet const&ts,
|
CompactTileSheet const&ts,
|
||||||
ox::Span<uint32_t> dst,
|
ox::Span<uint32_t> dst,
|
||||||
size_t const srcPxIdx,
|
size_t const srcPxIdx,
|
||||||
size_t pxlCnt) noexcept {
|
size_t const pxlCnt) noexcept {
|
||||||
size_t idx{};
|
size_t idx{};
|
||||||
if (ts.bpp == 4) {
|
if (ts.bpp == 4) {
|
||||||
for (size_t i = 0; i < pxlCnt; i += 2) {
|
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(
|
ox::Error loadBgTileSheet(
|
||||||
Context &ctx,
|
Context &ctx,
|
||||||
unsigned const cbb,
|
unsigned const cbb,
|
||||||
@ -625,7 +650,7 @@ ox::Error loadSpriteTileSheet(
|
|||||||
CompactTileSheet const&ts,
|
CompactTileSheet const&ts,
|
||||||
bool loadDefaultPalette) noexcept {
|
bool loadDefaultPalette) noexcept {
|
||||||
OX_REQUIRE(tsd, normalizeTileSheet(ts));
|
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());
|
ctx.spriteBlocks.tex = renderer::createTexture(tsd.width, tsd.height, tsd.pixels.data());
|
||||||
if (loadDefaultPalette) {
|
if (loadDefaultPalette) {
|
||||||
OX_RETURN_ERROR(loadSpritePalette(ctx, ts.defaultPalette));
|
OX_RETURN_ERROR(loadSpritePalette(ctx, ts.defaultPalette));
|
||||||
@ -648,7 +673,7 @@ void setBgTile(
|
|||||||
int row,
|
int row,
|
||||||
BgTile const&tile) noexcept {
|
BgTile const&tile) noexcept {
|
||||||
oxTracef(
|
oxTracef(
|
||||||
"nostalgia.core.gfx.setBgTile",
|
"nostalgia.gfx.setBgTile",
|
||||||
"bgIdx: {}, column: {}, row: {}, tile: {}, palBank: {}",
|
"bgIdx: {}, column: {}, row: {}, tile: {}, palBank: {}",
|
||||||
bgIdx, column, row, tile.tileIdx, tile.palBank);
|
bgIdx, column, row, tile.tileIdx, tile.palBank);
|
||||||
const auto z = static_cast<uint_t>(bgIdx);
|
const auto z = static_cast<uint_t>(bgIdx);
|
||||||
@ -656,8 +681,8 @@ void setBgTile(
|
|||||||
const auto x = static_cast<uint_t>(column);
|
const auto x = static_cast<uint_t>(column);
|
||||||
const auto i = renderer::bgVertexRow(x, y);
|
const auto i = renderer::bgVertexRow(x, y);
|
||||||
auto &cbb = ctx.cbbs[z];
|
auto &cbb = ctx.cbbs[z];
|
||||||
const auto vbo = &cbb.vertices[i * renderer::BgVertexVboLength];
|
const auto vbo = ox::Span{cbb.vertices} + i * renderer::BgVertexVboLength;
|
||||||
const auto ebo = &cbb.elements[i * renderer::BgVertexEboLength];
|
const auto ebo = ox::Span{cbb.elements} + i * renderer::BgVertexEboLength;
|
||||||
auto &bg = ctx.backgrounds[bgIdx];
|
auto &bg = ctx.backgrounds[bgIdx];
|
||||||
renderer::setTileBufferObject(
|
renderer::setTileBufferObject(
|
||||||
static_cast<uint_t>(i * renderer::BgVertexVboRows),
|
static_cast<uint_t>(i * renderer::BgVertexVboRows),
|
||||||
@ -743,7 +768,7 @@ ox::Size drawSize(int scale) noexcept {
|
|||||||
return {240 * scale, 160 * scale};
|
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);
|
glViewport(0, 0, renderSz.width, renderSz.height);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
@ -758,7 +783,7 @@ void draw(core::Context &ctx, ox::Size const&renderSz) noexcept {
|
|||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(core::Context &ctx, int scale) noexcept {
|
void draw(gfx::Context &ctx, int scale) noexcept {
|
||||||
draw(ctx, drawSize(scale));
|
draw(ctx, drawSize(scale));
|
||||||
}
|
}
|
||||||
|
|
@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
#include <glutils/glutils.hpp>
|
#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 TileRows = 128;
|
||||||
constexpr uint64_t TileColumns = 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;
|
ox::Error initGfx(Context &ctx, InitParams const&) noexcept;
|
||||||
void shutdownGfx(Context &ctx) noexcept;
|
void shutdownGfx(Context &ctx) noexcept;
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user