Compare commits

..

27 Commits

Author SHA1 Message Date
791b7746f3 [nostalgia] Update liccor file
All checks were successful
Build / build (push) Successful in 3m18s
2025-01-08 23:13:14 -06:00
842e3587fd [nostalgia] Update .gitignore for new location of scripts dir 2025-01-08 23:13:02 -06:00
318e79004b [ox] Update liccor file 2025-01-08 23:12:28 -06:00
9f338a7429 [ox] Run liccor
All checks were successful
Build / build (push) Successful in 3m18s
2025-01-08 23:03:05 -06:00
645e48af7b [nostalgia,olympic] Run liccor 2025-01-08 23:02:08 -06:00
ef92c8df13 [nostalgia] Make pkg-gba.py force lower case for pack tool
All checks were successful
Build / build (push) Successful in 3m9s
2025-01-08 22:01:27 -06:00
849d50be8e [nostalgia/core] Make getTileIdx return an Optional 2025-01-08 21:34:01 -06:00
845092f114 [turbine] Make common turbine.cpp file private to its target 2025-01-08 21:33:23 -06:00
75819a1797 [ox/std] Add SmallMap::values() 2025-01-08 21:31:46 -06:00
d66da85753 [ox/std] SmallMap fixes, add findIdx function 2025-01-07 20:59:04 -06:00
98ddb08abd [nostalgia] Cleanup
All checks were successful
Build / build (push) Successful in 3m18s
2025-01-05 20:55:49 -06:00
8d1701b0bb [turbine/glfw] Ensure window opens with a standard mandatory refresh period
All checks were successful
Build / build (push) Successful in 3m19s
2025-01-04 23:49:04 -06:00
1048e522fd [imgui] Make ImGui not an object lib 2025-01-04 23:42:43 -06:00
ee59da4aa3 [glad] Make glad not an object lib 2025-01-04 23:42:43 -06:00
1ba64cb5d8 Merge commit '07610a5af2aaaac9cfcdcf8359b33f7df40d46cd'
All checks were successful
Build / build (push) Successful in 3m15s
2025-01-04 01:29:09 -06:00
462bebf6dd [nostalgia/core] Cleanup unused function declaration 2025-01-04 01:26:02 -06:00
e3f84c4e75 [studio] Make first tab not draw before selected tab when window opens 2025-01-04 01:12:48 -06:00
6837a0556d [keel] Make AssetManager take StringViewCR for assetId
All checks were successful
Build / build (push) Successful in 3m16s
2025-01-04 01:11:05 -06:00
ede2c8ca37 [keel] Make AssetTypeManager(Loader) move loader
All checks were successful
Build / build (push) Successful in 3m23s
2025-01-04 01:05:04 -06:00
f50367f7d5 [ox/std] Add hash.hpp to install
All checks were successful
Build / build (push) Successful in 3m31s
2025-01-03 00:26:10 -06:00
e758e03d2b [nostalgia,olympic] Update for ox::Error changes
All checks were successful
Build / build (push) Successful in 3m20s
2025-01-01 23:43:32 -06:00
835e3270ce [ox] Make Error use std::source_location 2025-01-01 23:42:46 -06:00
480dd5ece4 [ox/std] Cleanup
All checks were successful
Build / build (push) Successful in 3m25s
2025-01-01 22:57:20 -06:00
dba6bb5800 [ox/std] Make Vector(initializer_list) use list size as capacity
All checks were successful
Build / build (push) Successful in 3m55s
2025-01-01 22:37:28 -06:00
40a456e54a [ox/std] Add Vector::shrink_to_fit 2025-01-01 22:32:57 -06:00
bf5be00c12 Merge commit 'dc96270ca5e882e41f6b657be14a20e8bd2ad501'
All checks were successful
Build / build (push) Successful in 3m14s
2024-12-21 20:13:20 -06:00
dc7c2559d6 [studio] Make selection tracker not go below 0 2024-12-21 20:06:48 -06:00
37 changed files with 232 additions and 136 deletions

2
.gitignore vendored
View File

@ -6,7 +6,7 @@
.mypy_cache
.stfolder
.stignore
scripts/__pycache__
util/scripts/__pycache__
pyenv
CMakeLists.txt.user
ROM.oxfs

View File

@ -1,5 +1,6 @@
BC_VAR_PROJECT_NAME=nostalgia
BC_VAR_PROJECT_NAME_CAP=Nostalgia
BC_VAR_DEVENV_ROOT=util
BUILDCORE_PATH=deps/buildcore
include ${BUILDCORE_PATH}/base.mk
@ -13,7 +14,7 @@ endif
.PHONY: pkg-gba
pkg-gba: build
${BC_CMD_ENVRUN} ${BC_PY3} ./scripts/pkg-gba.py sample_project ${BC_VAR_PROJECT_NAME}
${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/pkg-gba.py sample_project ${BC_VAR_PROJECT_NAME}
.PHONY: run
run: build

View File

@ -1,2 +1,11 @@
add_library(glad OBJECT src/glad.c)
target_include_directories(glad PUBLIC include)
add_library(glad src/glad.c)
target_include_directories(glad PUBLIC include)
install(
TARGETS
glad
DESTINATION
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)

View File

@ -6,7 +6,7 @@ endif()
# DrinkingTea: end
add_library(
imgui OBJECT
imgui
imgui.cpp
imgui_demo.cpp
imgui_draw.cpp
@ -19,4 +19,12 @@ add_library(
target_include_directories(
imgui SYSTEM PUBLIC
.
)
)
install(
TARGETS
imgui
DESTINATION
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)

View File

@ -215,7 +215,7 @@ Error Signal<Args...>::emitCheckError(Args... args) const noexcept {
}
return ox::Error(0);
} catch (const ox::Exception &ex) {
return ox::Error(ex.file, ex.line, ex.errCode, ex.msg);
return ox::Error(ex.errCode, ex.msg, ex.src);
}
}

View File

@ -14,7 +14,7 @@
{ \
const auto loggerErr = (loggerName).initConn(appName); \
if (loggerErr) { \
oxErrf("Could not connect to logger: {} ({}:{})\n", toStr(loggerErr), loggerErr.file, loggerErr.line); \
oxErrf("Could not connect to logger: {} ({}:{})\n", toStr(loggerErr), loggerErr.src.file_name(), loggerErr.src.line()); \
} else { \
ox::trace::setLogger(&(loggerName)); \
} \

View File

@ -9,13 +9,25 @@
#pragma once
#include "def.hpp"
#include "error.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename It, typename T>
constexpr It find(It begin, It end, const T &value) {
constexpr ox::Result<size_t> findIdx(It begin, It end, T const&value) {
auto it = begin;
for (; it != end; ++it) {
if (*it == value) {
return it.offset();
}
}
return ox::Error{1, "item not found"};
}
template<typename It, typename T>
constexpr It find(It begin, It end, T const&value) {
for (; begin != end; ++begin) {
if (*begin == value) {
return begin;

View File

@ -20,8 +20,8 @@ void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err)
oxErrf("\tError Message:\t{}\n", err.msg);
}
oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
if (err.file != nullptr) {
oxErrf("\tError Location:\t{}:{}\n", err.file, err.line);
if (err.src.file_name() != nullptr) {
oxErrf("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line());
}
#ifdef OX_USE_STDLIB
printStackTrace(2);
@ -56,8 +56,8 @@ void assertFailFuncRuntime(StringViewCR file, int line, [[maybe_unused]] const E
msg += sfmt("\tError Message:\t{}\n", err.msg);
}
msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
if (err.file != nullptr) {
msg += sfmt("\tError Location:\t{}:{}\n", err.file, err.line);
if (err.src.file_name() != nullptr) {
msg += sfmt("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line());
}
msg += genStackTrace(2);
oxErr(msg);

View File

@ -36,28 +36,16 @@ using ErrorCode = uint16_t;
struct [[nodiscard]] Error {
std::source_location src;
ox::CString msg = nullptr;
ox::CString file = nullptr;
uint16_t line = 0;
ErrorCode errCode = 0;
constexpr Error() noexcept = default;
explicit constexpr Error(
ox::CString file,
uint32_t const line,
ErrorCode const errCode,
ox::CString msg = nullptr) noexcept:
msg{msg},
file{file},
line{static_cast<uint16_t>(line)},
errCode{errCode} {}
explicit constexpr Error(
ErrorCode const errCode,
std::source_location const&src = std::source_location::current()) noexcept:
file{src.file_name()},
line{static_cast<uint16_t>(src.line())},
src{src},
errCode{errCode}
{}
@ -65,9 +53,8 @@ struct [[nodiscard]] Error {
ErrorCode const errCode,
ox::CString msg,
std::source_location const&src = std::source_location::current()) noexcept:
src{src},
msg{msg},
file{src.file_name()},
line{static_cast<uint16_t>(src.line())},
errCode{errCode}
{}
@ -89,42 +76,31 @@ constexpr auto toStr(Error const&err) noexcept {
}
struct Exception: public std::exception {
std::source_location src;
ox::CString msg = nullptr;
ox::CString file = nullptr;
uint16_t line = 0;
ErrorCode errCode = 0;
explicit inline Exception(ox::CString file, uint32_t line, ErrorCode errCode, char const*msg = "") noexcept {
this->file = file;
this->line = static_cast<uint16_t>(line);
this->msg = msg;
this->errCode = errCode;
}
explicit inline Exception(
ErrorCode const errCode,
std::source_location const&src = std::source_location::current()) noexcept:
file{src.file_name()},
line{static_cast<uint16_t>(src.line())},
src{src},
errCode{errCode} {}
explicit inline Exception(
ErrorCode const errCode,
ox::CString msg,
std::source_location const&src = std::source_location::current()) noexcept:
src{src},
msg{msg},
file{src.file_name()},
line{static_cast<uint16_t>(src.line())},
errCode{errCode} {}
explicit inline Exception(Error const&err) noexcept:
src{err.src},
msg{err.msg ? err.msg : ""},
file{err.file},
line{err.line},
errCode{err.errCode} {}
constexpr Error toError() const noexcept {
return Error(file, line, errCode, msg);
return Error(errCode, msg, src);
}
[[nodiscard]]

View File

@ -31,7 +31,6 @@ concept Reader_c = requires(T v) {
class Reader_v {
public:
virtual constexpr ~Reader_v() noexcept = default;
[[nodiscard]]
virtual constexpr ox::Result<char> peek() const noexcept = 0;
virtual constexpr ox::Result<std::size_t> read(char*, std::size_t) noexcept = 0;
virtual constexpr ox::Result<std::size_t> tellg() noexcept = 0;

View File

@ -62,6 +62,9 @@ class SmallMap {
[[nodiscard]]
constexpr Vector<K> keys() const noexcept;
[[nodiscard]]
constexpr Vector<T> values() const noexcept;
[[nodiscard]]
constexpr K const&key(size_t i) const noexcept;
@ -86,10 +89,13 @@ class SmallMap {
private:
template<typename KK>
constexpr Pair const&access(PairVector const&pairs, KK const&key, bool &isNew) const;
constexpr Pair const*access(PairVector const&pairs, KK const&key, bool &isNew) const;
template<typename KK>
constexpr Pair &access(PairVector &pairs, KK const&key, bool &isNew);
constexpr Pair *access(PairVector &pairs, KK const&key, bool &isNew);
template<typename KK>
constexpr Pair *accessNoCreate(PairVector &pairs, KK const&key);
};
@ -129,7 +135,7 @@ constexpr SmallMap<K, T, SmallSz> &SmallMap<K, T, SmallSz>::operator=(SmallMap<K
template<typename K, typename T, size_t SmallSz>
constexpr T &SmallMap<K, T, SmallSz>::operator[](MaybeView_t<K> const&k) {
bool isNew{};
auto p = &access(m_pairs, k, isNew);
auto p = access(m_pairs, k, isNew);
if (isNew) {
p->key = k;
}
@ -138,7 +144,7 @@ constexpr T &SmallMap<K, T, SmallSz>::operator[](MaybeView_t<K> const&k) {
template<typename K, typename T, size_t SmallSz>
constexpr Result<T*> SmallMap<K, T, SmallSz>::at(MaybeView_t<K> const&k) noexcept {
auto p = access(m_pairs, k);
auto const p = accessNoCreate(m_pairs, k);
if (!p) {
return {nullptr, ox::Error(1, "value not found for given key")};
}
@ -147,7 +153,8 @@ constexpr Result<T*> SmallMap<K, T, SmallSz>::at(MaybeView_t<K> const&k) noexcep
template<typename K, typename T, size_t SmallSz>
constexpr Result<const T*> SmallMap<K, T, SmallSz>::at(MaybeView_t<K> const&k) const noexcept {
auto p = access(m_pairs, k);
bool isNew{};
auto p = access(m_pairs, k, isNew);
if (!p) {
return {nullptr, ox::Error(1, "value not found for given key")};
}
@ -168,7 +175,8 @@ constexpr void SmallMap<K, T, SmallSz>::erase(MaybeView_t<K> const&k) {
template<typename K, typename T, size_t SmallSz>
constexpr bool SmallMap<K, T, SmallSz>::contains(MaybeView_t<K> const&k) const noexcept {
return access(m_pairs, k) != nullptr;
bool isNew{};
return access(m_pairs, k, isNew) != nullptr;
}
template<typename K, typename T, size_t SmallSz>
@ -186,6 +194,16 @@ constexpr Vector<K> SmallMap<K, T, SmallSz>::keys() const noexcept {
return keys;
}
template<typename K, typename T, size_t SmallSz>
constexpr Vector<T> SmallMap<K, T, SmallSz>::values() const noexcept {
ox::Vector<T> keys;
keys.reserve(m_pairs.size());
for (auto const&p : m_pairs) {
keys.emplace_back(p.key);
}
return keys;
}
template<typename K, typename T, size_t SmallSz>
constexpr K const&SmallMap<K, T, SmallSz>::key(size_t i) const noexcept {
return m_pairs[i].key;
@ -218,30 +236,42 @@ constexpr void SmallMap<K, T, SmallSz>::clear() {
template<typename K, typename T, size_t SmallSz>
template<typename KK>
constexpr typename SmallMap<K, T, SmallSz>::Pair const&SmallMap<K, T, SmallSz>::access(
constexpr typename SmallMap<K, T, SmallSz>::Pair const*SmallMap<K, T, SmallSz>::access(
PairVector const&pairs, KK const&k, bool &isNew) const {
for (auto const&p : pairs) {
if (p.key == k) {
isNew = false;
return p;
return &p;
}
}
isNew = true;
return pairs.emplace_back();
return nullptr;
}
template<typename K, typename T, size_t SmallSz>
template<typename KK>
constexpr typename SmallMap<K, T, SmallSz>::Pair &SmallMap<K, T, SmallSz>::access(
constexpr typename SmallMap<K, T, SmallSz>::Pair *SmallMap<K, T, SmallSz>::access(
PairVector &pairs, KK const&k, bool &isNew) {
for (auto &p : pairs) {
if (p.key == k) {
isNew = false;
return p;
return &p;
}
}
isNew = true;
return pairs.emplace_back();
return &pairs.emplace_back();
}
template<typename K, typename T, size_t SmallSz>
template<typename KK>
constexpr typename SmallMap<K, T, SmallSz>::Pair *SmallMap<K, T, SmallSz>::accessNoCreate(
PairVector &pairs, KK const&k) {
for (auto &p : pairs) {
if (p.key == k) {
return &p;
}
}
return nullptr;
}
template<typename T, typename K, typename V, size_t SmallSz>

View File

@ -17,6 +17,8 @@ add_test("[ox/std] String" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "String")
add_test("[ox/std] SmallMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "SmallMap")
add_test("[ox/std] SmallMap2" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "SmallMap2")
add_test("[ox/std] Vector" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Vector")
add_test("[ox/std] Vector::shrink_to_fit" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Vector::shrink_to_fit")
add_test("[ox/std] findIdx" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "findIdx")
add_test("[ox/std] HashMap" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "HashMap")
add_test("[ox/std] HeapMgr" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest malloc)
add_test("[ox/std] Serialize-Int" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/StdTest "Serialize-Int")

View File

@ -237,6 +237,50 @@ OX_CLANG_NOWARN_END
return ox::Error(0);
}
},
{
"Vector::shrink_to_fit",
[] {
{
ox::Vector<ox::IString<8>> v;
v.reserve(50);
v.emplace_back("asdf");
v.emplace_back("aoeu");
auto const origData = v.data();
v.shrink_to_fit();
oxExpect(v[0], "asdf");
oxExpect(v[1], "aoeu");
oxExpect(v.capacity(), 2u);
oxAssert(origData != v.data(), "shrink_to_fit did not create a new allocation");
}
{
ox::Vector<ox::IString<8>> v;
v.reserve(2);
v.emplace_back("asdf");
v.emplace_back("aoeu");
auto const origData = v.data();
v.shrink_to_fit();
oxExpect(v[0], "asdf");
oxExpect(v[1], "aoeu");
oxExpect(v.capacity(), 2u);
oxAssert(origData == v.data(), "shrink_to_fit inappropriately created a new allocation");
}
return ox::Error{};
}
},
{
"findIdx",
[] {
ox::Vector<ox::IString<8>> const v {"zero", "one", "two", "three", "four"};
oxExpect(ox::findIdx(v.begin(), v.end(), "zero").or_value(5), 0u);
oxExpect(ox::findIdx(v.begin(), v.end(), "one").or_value(5), 1u);
oxExpect(ox::findIdx(v.begin(), v.end(), "two").or_value(5), 2u);
oxExpect(ox::findIdx(v.begin(), v.end(), "three").or_value(5), 3u);
oxExpect(ox::findIdx(v.begin(), v.end(), "four").or_value(5), 4u);
oxExpect(ox::findIdx(v.begin(), v.end(), "five").or_value(5), 5u);
oxExpect(ox::findIdx(v.begin(), v.end(), "six").or_value(6), 6u);
return ox::Error{};
}
},
{
"SmallMap",
[] {
@ -246,7 +290,18 @@ OX_CLANG_NOWARN_END
oxExpect(map.size(), 1u);
oxExpect(map["aoeu"], "");
oxExpect(map.size(), 2u);
return ox::Error(0);
ox::SmallMap<ox::String, ox::String> cmap;
cmap["asdf"] = "aoeu";
auto constexpr constTest = [](ox::SmallMap<ox::String, ox::String> const&map) {
OX_REQUIRE(asdf, map.at("asdf"));
oxExpect(*asdf, "aoeu");
oxExpect(map.size(), 1u);
auto const aoeu = map.at("aoeu");
oxExpect(aoeu.ok(), false);
oxExpect(map.size(), 1u);
return ox::Error{};
};
return constTest(cmap);
}
},
{

View File

@ -269,8 +269,8 @@ using TraceStream = NullStream;
inline void logError(const char *file, int line, const char *fmt, const Error &err) noexcept {
if (err) {
TraceStream trc(file, line, "ox::error");
if (err.file != nullptr) {
trc << "Error: (" << err.file << ":" << err.line << "):";
if (err.src.file_name() != nullptr) {
trc << "Error: (" << err.src.file_name() << ":" << err.src.line() << "):";
} else {
trc << "Error:";
}
@ -282,8 +282,8 @@ inline void logError(const char *file, int line, const Error &err) noexcept {
if (err) {
TraceStream trc(file, line, "ox::error");
trc << "Error:" << err;
if (err.file != nullptr) {
trc << "(" << err.file << ":" << err.line << ")";
if (err.src.file_name() != nullptr) {
trc << "(" << err.src.file_name() << ":" << err.src.line() << ")";
}
}
}

View File

@ -313,6 +313,8 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
constexpr void reserve(std::size_t cap) noexcept(useNoexcept);
constexpr void shrink_to_fit() noexcept(useNoexcept);
private:
constexpr void reserveInsert(
std::size_t cap, std::size_t pos, std::size_t offset = 1) noexcept(useNoexcept);
@ -341,6 +343,7 @@ constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::size_t size) noexce
template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::initializer_list<T> list) noexcept {
reserve(list.size());
for (auto &item : list) {
emplace_back(std::move(item));
}
@ -675,6 +678,24 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::reserve(std::size_t cap) n
}
}
template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr void Vector<T, SmallVectorSize, Allocator>::shrink_to_fit() noexcept(useNoexcept) {
if (m_size == m_cap) {
return;
}
const auto oldItems = m_items;
const auto oldCap = m_cap;
m_cap = m_size;
this->allocate(&m_items, m_size);
if (oldItems) { // move over old items
for (std::size_t i = 0; i < m_size; ++i) {
std::construct_at(&m_items[i], std::move(oldItems[i]));
oldItems[i].~T();
}
this->deallocate(oldItems, oldCap);
}
}
template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr void Vector<T, SmallVectorSize, Allocator>::reserveInsert(
std::size_t cap,

View File

@ -102,8 +102,6 @@ OX_MODEL_BEGIN(TileSheetSet)
OX_MODEL_FIELD(entries)
OX_MODEL_END()
void addEntry(TileSheetSet &set, ox::FileAddress path, int32_t begin = 0, int32_t size = -1) noexcept;
[[nodiscard]]
int tileColumns(Context&) noexcept;

View File

@ -212,6 +212,10 @@ struct TileSheetV4 {
pixels(std::move(pPixels)) {
}
/**
*
* @return the dimensional size of the SubSheet (e.g. width * height)
*/
[[nodiscard]]
constexpr std::size_t size() const noexcept {
return static_cast<std::size_t>(columns) * static_cast<std::size_t>(rows);
@ -233,12 +237,10 @@ struct TileSheetV4 {
[[nodiscard]]
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);
return
(ss.pixels.empty() || ss.subsheets.empty()) &&
ox::all_of(ss.subsheets.begin(), ss.subsheets.end(),
[bpp, bytes](TileSheetV4::SubSheet const&s) {
return bytes == s.pixels.size() && valid(s, bpp);
});
return ox::all_of(ss.subsheets.begin(), ss.subsheets.end(),
[bpp, bytes](TileSheetV4::SubSheet const&s) {
return bytes == s.pixels.size() && valid(s, bpp);
});
}
[[nodiscard]]
@ -247,14 +249,8 @@ constexpr bool valid(TileSheetV4 const&ts) noexcept {
}
constexpr void repair(TileSheetV4::SubSheet &ss, int bpp) noexcept {
if (ss.subsheets.empty()) {
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;
}
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
ss.pixels.resize(bytes);
for (auto &s : ss.subsheets) {
repair(s, bpp);
}
@ -281,7 +277,7 @@ size_t getTileCnt(TileSheet const&ts) noexcept;
TileSheet::SubSheet const*getSubsheet(TileSheet const&ts, SubSheetId id) noexcept;
[[nodiscard]]
size_t getTileIdx(TileSheet const&ts, SubSheetId id) noexcept;
ox::Optional<size_t> getTileIdx(TileSheet const&ts, SubSheetId id) noexcept;
[[nodiscard]]
uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept;
@ -400,6 +396,8 @@ ox::Result<SubSheetId> getIdFor(TileSheet const&ts, ox::StringViewCR path) noexc
ox::Result<unsigned> getTileOffset(TileSheet const&ts, ox::StringViewCR pNamePath) noexcept;
ox::Result<uint32_t> getTileOffset(TileSheet const&ts, SubSheetId pId) noexcept;
ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept;
ox::Result<ox::StringView> getNameFor(TileSheet const&ts, SubSheetId pId) noexcept;

View File

@ -48,8 +48,8 @@ OX_ALLOW_UNSAFE_BUFFERS_END
oxErrf("\tError Message:\t{}\n", err.msg);
}
oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
if (err.file != nullptr) {
oxErrf("\tError Location:\t{}:{}\n", err.file, err.line);
if (err.src.file_name() != nullptr) {
oxErrf("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line());
}
// disable all interrupt handling and IntrWait on no interrupts
REG_IE = 0;

View File

@ -6,7 +6,7 @@
namespace nostalgia::core {
InsertTilesCommand::InsertTilesCommand(
core::InsertTilesCommand::InsertTilesCommand(
TileSheet &img,
TileSheet::SubSheetIdx idx,
std::size_t tileIdx,
@ -31,11 +31,9 @@ ox::Error InsertTilesCommand::redo() noexcept {
auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels;
auto dstPos = m_insertPos + m_insertCnt;
auto const dst = &p[dstPos];
auto const src = &p[m_insertPos];
if (dstPos < p.size()) {
auto const dst = &p[dstPos];
ox::memmove(dst, src, p.size() - dstPos);
}
ox::memmove(dst, src, p.size() - dstPos);
ox::memset(src, 0, m_insertCnt * sizeof(decltype(p[0])));
return {};
}
@ -43,14 +41,12 @@ ox::Error InsertTilesCommand::redo() noexcept {
ox::Error InsertTilesCommand::undo() noexcept {
auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels;
auto const srcIdx = m_insertPos + m_insertCnt;
auto const src = &p[srcIdx];
auto const dst1 = &p[m_insertPos];
auto const dst2 = &p[p.size() - m_insertCnt];
auto const srcIdx = m_insertPos + m_insertCnt;
if (srcIdx < p.size()) {
auto const sz = p.size() - srcIdx;
auto const src = &p[srcIdx];
ox::memmove(dst1, src, sz);
}
auto const sz = p.size() - srcIdx;
ox::memmove(dst1, src, sz);
ox::memcpy(dst2, m_deletedPixels.data(), m_deletedPixels.size());
return {};
}

View File

@ -188,7 +188,7 @@ void TileSheetEditorImGui::draw(studio::StudioContext&) noexcept {
if (ImGui::IsKeyDown(ImGuiKey_ModCtrl)) {
if (ImGui::IsKeyPressed(ImGuiKey_A)) {
auto const&img = m_model.activeSubSheet();
m_model.setSelection({{}, {img.columns * TileWidth - 1, img.rows * TileHeight - 1}});
m_model.setSelection({{}, {img.columns * TileWidth, img.rows * TileHeight}});
} else if (ImGui::IsKeyPressed(ImGuiKey_G)) {
m_model.clearSelection();
}
@ -544,7 +544,7 @@ void TileSheetEditorImGui::SubSheetEditor::draw(turbine::Context &tctx) noexcept
auto const popupHeight = modSize ? 130.f : 85.f;
auto const popupSz = ImVec2{popupWidth, popupHeight};
if (ig::BeginPopup(tctx, popupName, m_show, popupSz)) {
ig::InputText("Name", m_name);
ImGui::InputText("Name", m_name.data(), m_name.cap());
if (modSize) {
ImGui::InputInt("Columns", &m_cols);
ImGui::InputInt("Rows", &m_rows);

View File

@ -56,10 +56,8 @@ void TileSheetEditorView::scrollH(ox::Vec2 const&paneSz, float wheelh) noexcept
}
void TileSheetEditorView::insertTile(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept {
auto pt = clickPoint(paneSize, clickPos);
auto const pt = clickPoint(paneSize, clickPos);
auto const&s = m_model.activeSubSheet();
pt.x = ox::min(pt.x, s.columns * TileWidth - 1);
pt.y = ox::min(pt.y, s.rows * TileHeight - 1);
auto const tileIdx = ptToIdx(pt, s.columns) / PixelsPerTile;
m_model.insertTiles(m_model.activeSubSheetIdx(), tileIdx, 1);
}

View File

@ -80,11 +80,6 @@ void TileSheetGrid::setBufferObject(
}
void TileSheetGrid::setBufferObjects(ox::Vec2 const&paneSize, TileSheet::SubSheet const&subsheet) noexcept {
if (subsheet.columns < 1 || subsheet.rows < 1) {
m_bufferSet.elements.clear();
m_bufferSet.vertices.clear();
return;
}
auto const pixSize = pixelSize(paneSize);
auto const set = [&](std::size_t i, ox::Point pt1, ox::Point pt2, Color32 c) {
auto const vbo = &m_bufferSet.vertices[i * VertexVboLength];

View File

@ -51,7 +51,7 @@ ox::Error TileSheetPixels::buildShader() noexcept {
return glutils::buildShaderProgram(s_programSrc).moveTo(m_shader);
}
void TileSheetPixels::draw(bool const update, ox::Vec2 const&scroll) noexcept {
void TileSheetPixels::draw(bool update, ox::Vec2 const&scroll) noexcept {
glUseProgram(m_shader);
glBindVertexArray(m_bufferSet.vao);
if (update) {
@ -117,11 +117,6 @@ void TileSheetPixels::setPixelBufferObject(
void TileSheetPixels::setBufferObjects(ox::Vec2 const&paneSize) noexcept {
// set buffer lengths
auto const&subSheet = m_model.activeSubSheet();
if (subSheet.columns < 1 || subSheet.rows < 1) {
m_bufferSet.vertices.clear();
m_bufferSet.elements.clear();
return;
}
auto const&pal = m_model.pal();
auto const width = subSheet.columns * TileWidth;
auto const height = subSheet.rows * TileHeight;

View File

@ -66,10 +66,10 @@ static ox::Optional<size_t> getPixelIdx(
return ox::Optional<size_t>{};
}
size_t getTileIdx(TileSheet const&ts, SubSheetId const id) noexcept {
ox::Optional<size_t> getTileIdx(TileSheet const&ts, SubSheetId const id) noexcept {
size_t idx{};
auto const out = getPixelIdx(ts.subsheet, id, idx, ts.bpp);
return out.or_value(0) / PixelsPerTile;
return out ? ox::Optional<size_t>{ox::in_place, *out / PixelsPerTile} : out;
}
uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept {
@ -355,12 +355,12 @@ ox::Result<SubSheetId> getIdFor(TileSheet const&ts, ox::StringViewCR path) noexc
/**
* Gets the offset in tiles of the desired subsheet.
*/
static ox::Result<unsigned> getTileOffset(
static ox::Result<uint32_t> getTileOffset(
TileSheet::SubSheet const&ss,
ox::SpanView<ox::StringView> const&pNamePath,
int8_t pBpp,
std::size_t pIt = 0,
unsigned pCurrentTotal = 0) noexcept {
uint32_t pCurrentTotal = 0) noexcept {
// pIt == pNamePath.size() - 1 &&
if (ss.name != pNamePath[pIt]) {
return ox::Error(2, "Wrong branch");
@ -374,12 +374,14 @@ static ox::Result<unsigned> getTileOffset(
if (!err) {
return offset;
}
// Possible bug? Shoud this be usinga a recursive version of
// pixelCnt will count pixels in subsheets of sub as well.
pCurrentTotal += pixelCnt(sub, pBpp) / PixelsPerTile;
}
return ox::Error(1, "SubSheet not found");
}
ox::Result<unsigned> getTileOffset(TileSheet const&ts, ox::StringViewCR pNamePath) noexcept {
ox::Result<uint32_t> getTileOffset(TileSheet const&ts, ox::StringViewCR pNamePath) noexcept {
return core::getTileOffset(ts.subsheet, ox::split<8>(pNamePath, '.'), ts.bpp);
}

View File

@ -11,7 +11,7 @@ target_link_libraries(
target_compile_definitions(
NostalgiaStudio PUBLIC
OLYMPIC_APP_VERSION="d2024.12.2"
OLYMPIC_APP_VERSION="dev build"
)
install(

View File

@ -196,15 +196,15 @@ class AssetManager {
template<typename T>
class AssetTypeManager: public AssetTypeManagerBase {
public:
using Loader = std::function<ox::Result<T>(ox::StringView assetId)>;
using Loader = std::function<ox::Result<T>(ox::StringViewCR assetId)>;
private:
Loader m_loader{};
ox::HashMap<ox::String, ox::UPtr<AssetContainer<T>>> m_cache;
public:
AssetTypeManager(Loader loader) noexcept: m_loader(loader) {}
AssetTypeManager(Loader &&loader) noexcept: m_loader(std::move(loader)) {}
ox::Result<AssetRef<T>> getAsset(ox::StringView const assetId) const noexcept {
ox::Result<AssetRef<T>> getAsset(ox::StringViewCR assetId) const noexcept {
OX_REQUIRE(out, m_cache.at(assetId));
if (!out || !*out) {
return ox::Error(1, "asset is null");
@ -212,7 +212,7 @@ class AssetManager {
return AssetRef<T>(out->get());
}
ox::Result<AssetRef<T>> loadAsset(ox::StringView const assetId) noexcept {
ox::Result<AssetRef<T>> loadAsset(ox::StringViewCR assetId) noexcept {
auto &p = m_cache[assetId];
OX_REQUIRE_M(obj, m_loader(assetId));
if (!p) {
@ -224,7 +224,7 @@ class AssetManager {
return AssetRef<T>(p.get());
}
ox::Error reloadAsset(ox::StringView const assetId) noexcept {
ox::Error reloadAsset(ox::StringViewCR assetId) noexcept {
auto &p = m_cache[assetId];
OX_REQUIRE_M(obj, m_loader(assetId));
if (!p) {
@ -247,7 +247,7 @@ class AssetManager {
};
ox::HashMap<ox::String, ox::UPtr<AssetTypeManagerBase>> m_assetTypeManagers;
ox::HashMap<ox::String, ox::Signal<ox::Error(ox::StringView assetId)>> m_fileUpdated;
ox::HashMap<ox::String, ox::Signal<ox::Error(ox::StringViewCR assetId)>> m_fileUpdated;
template<typename T>
ox::Result<AssetTypeManager<T>*> getTypeManager() noexcept {
@ -273,18 +273,18 @@ class AssetManager {
}
template<typename T>
ox::Result<AssetRef<T>> getAsset(ox::StringView assetId) noexcept {
ox::Result<AssetRef<T>> getAsset(ox::StringViewCR assetId) noexcept {
OX_REQUIRE(m, getTypeManager<T>());
return m->getAsset(assetId);
}
ox::Error reloadAsset(ox::StringView assetId) noexcept {
ox::Error reloadAsset(ox::StringViewCR assetId) noexcept {
m_fileUpdated[assetId].emit(assetId);
return {};
}
template<typename T>
ox::Result<AssetRef<T>> loadAsset(ox::StringView assetId) noexcept {
ox::Result<AssetRef<T>> loadAsset(ox::StringViewCR assetId) noexcept {
OX_REQUIRE(m, getTypeManager<T>());
OX_REQUIRE(out, m->loadAsset(assetId));
m_fileUpdated[assetId].connect(m, &AssetTypeManager<T>::reloadAsset);

View File

@ -154,12 +154,13 @@ ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::UUID const&uuid) noexce
}
ox::Error reloadAsset(keel::Context &ctx, ox::StringViewCR assetId) noexcept {
ox::UUIDStr uuidStr;
if (beginsWith(assetId, "uuid://")) {
return ctx.assetManager.reloadAsset(substr(assetId, 7));
} else {
auto const [uuid, uuidErr] = getUuid(ctx, assetId);
auto const [uuid, uuidErr] = getUuid(ctx, assetId);
if (!uuidErr) {
return ctx.assetManager.reloadAsset(uuid.toString());
return ctx.assetManager.reloadAsset(uuidStr);
} else {
return ctx.assetManager.reloadAsset(assetId);
}

View File

@ -50,7 +50,7 @@ void NewProject::draw(studio::StudioContext &ctx) noexcept {
void NewProject::drawNewProjectName(studio::StudioContext &sctx) noexcept {
drawWindow(sctx.tctx, &m_open, [this, &sctx] {
ig::InputText("Name", m_projectName);
ImGui::InputText("Name", m_projectName.data(), m_projectName.cap());
ImGui::Text("Path: %s", m_projectPath.c_str());
if (ImGui::Button("Browse")) {
oxLogError(studio::chooseDirectory().moveTo(m_projectPath));

View File

@ -77,7 +77,7 @@ StudioUI::StudioUI(turbine::Context &ctx, ox::StringParam projectDataDir) noexce
} else {
oxErrf(
"Could not open studio config file: {}: {} ({}:{})\n",
err.errCode, toStr(err), err.file, err.line);
err.errCode, toStr(err), err.src.file_name(), err.src.line());
}
}
}
@ -227,7 +227,7 @@ void StudioUI::drawTabs() noexcept {
try {
OX_THROW_ERROR(m_editors.erase(it).moveTo(it));
} catch (ox::Exception const&ex) {
oxErrf("Editor tab deletion failed: {} ({}:{})\n", ex.what(), ex.file, ex.line);
oxErrf("Editor tab deletion failed: {} ({}:{})\n", ex.what(), ex.src.file_name(), ex.src.line());
} catch (std::exception const&ex) {
oxErrf("Editor tab deletion failed: {}\n", ex.what());
}
@ -379,7 +379,7 @@ ox::Error StudioUI::openFileActiveTab(ox::StringViewCR path, bool makeActiveTab)
if constexpr(!ox::defines::Debug) {
oxErrf("Could not open Editor: {}\n", toStr(err));
} else {
oxErrf("Could not open Editor: {} ({}:{})\n", err.errCode, err.file, err.line);
oxErrf("Could not open Editor: {} ({}:{})\n", err.errCode, err.src.file_name(), err.src.line());
}
return err;
}

View File

@ -13,7 +13,7 @@ namespace studio {
class NoChangesException: public ox::Exception {
public:
inline NoChangesException(std::source_location sloc = std::source_location::current()):
ox::Exception(sloc.file_name(), sloc.line(), 1, "Command makes no changes.") {}
ox::Exception(1, "Command makes no changes.", sloc) {}
};
class UndoCommand {

View File

@ -46,7 +46,7 @@ void BaseEditor::save() noexcept {
setUnsavedChanges(false);
} else {
if constexpr(ox::defines::Debug) {
oxErrorf("Could not save file {}: {} ({}:{})", itemPath(), toStr(err), err.file, err.line);
oxErrorf("Could not save file {}: {} ({}:{})", itemPath(), toStr(err), err.src.file_name(), err.src.line());
} else {
oxErrorf("Could not save file {}: {}", itemPath(), toStr(err));
}

View File

@ -19,7 +19,7 @@ target_include_directories(
)
target_sources(
Turbine PUBLIC
Turbine PRIVATE
turbine.cpp
)

View File

@ -1,4 +1,4 @@
FROM fedora:36
FROM fedora:41
RUN dnf update -y

View File

@ -28,11 +28,11 @@ project_name = sys.argv[2]
bin = f'./build/{host_env}-{current_build}/bin/'
project_bin = f'build/gba-release/bin/{project_name}.bin'
project_gba = f'{project_name}.gba'
project_manifest = f'{project_name}-manifest.json'
project_manifest = f'{project_name.lower()}-manifest.json'
shutil.copyfile(project_bin, project_gba)
subprocess.run([
f'{bin}/{project_name}-pack',
f'{bin}/{project_name.lower()}-pack',
'-src', project_dir,
'-rom-bin', project_gba,
'-manifest', project_manifest])