Compare commits

..

24 Commits

Author SHA1 Message Date
671b8edaad [ox/std] Make StringLiteral constructors consteval
All checks were successful
Build / build (push) Successful in 1m29s
2025-06-27 23:05:42 -05:00
952637a1ea Merge commit 'cbf4414fcaf00c00a2abf73b5c04a055180ad980'
All checks were successful
Build / build (push) Successful in 1m37s
2025-06-25 21:33:16 -05:00
7569698e95 [nostalgia,studio] Add FileExts_TileSheet const, and corresponding FilePickerPopup constructor 2025-06-25 21:30:49 -05:00
21713ba945 [ox/std] Fix StringLiteral::operator= to work with DevkitARM 2025-06-25 21:29:41 -05:00
73273b6fa7 [nostalgia/gfx] Add isTileSheet function for checking paths against both file extensions 2025-06-25 21:03:45 -05:00
9f040392c7 [olympic,nostalgia] Cleanup style
All checks were successful
Build / build (push) Successful in 1m18s
2025-06-24 01:59:22 -05:00
f4f7e5d053 Merge commit '9b5f7886cadc5c3dc826d00fa5b2e71696151dfd' 2025-06-23 20:49:01 -05:00
f847289bd4 [glutils] Cleanup
All checks were successful
Build / build (push) Successful in 1m20s
2025-06-23 01:39:47 -05:00
94b0020d15 [nostalgia,olympic] Cleanup
All checks were successful
Build / build (push) Successful in 1m16s
2025-06-23 01:30:33 -05:00
c54c0bad38 [teagba] Cleanup
All checks were successful
Build / build (push) Successful in 1m20s
2025-06-23 01:03:33 -05:00
b9ffae0269 [nostalgia/gfx] Cleanup
All checks were successful
Build / build (push) Successful in 1m18s
2025-06-23 00:47:46 -05:00
003f3e01c6 [nostalgia] Update release notes 2025-06-22 01:01:09 -05:00
9028e74af0 [nostalgia/gfx/studio/tilesheet] Disable paste when nothing is selected 2025-06-22 01:00:56 -05:00
f5ccab5f2c [studio] Cleanup 2025-06-21 19:19:39 -05:00
c27726a4a9 Merge commit '6bbcae10cc7b21b73171ec0ff196f4baf6304404' 2025-06-21 14:29:47 -05:00
37cfa927d1 [nostalgia/gfx] Address a couple of implicit conversions
All checks were successful
Build / build (push) Successful in 1m19s
2025-06-21 14:16:17 -05:00
0efed70b57 [studio] Fix Studio to clear editor pointers when opening a new project
All checks were successful
Build / build (push) Successful in 1m20s
2025-06-21 14:12:45 -05:00
bd24a775b2 Merge commit '7371df429534f264c179684412f6197f7968ebfa' 2025-06-21 08:48:13 -05:00
4419dff299 Merge commit '7688c05bac8c20bc267cae62ec78d55e5d0c493b' 2025-05-31 02:14:15 -05:00
536999c070 Merge commit '47eee1d56d591e3631d16e95a78ea3629ee312ee' 2025-05-30 23:38:53 -05:00
a5535ef59a Merge commit '08236fc790e711afe886b6ef545511d35e4e5c6c' 2025-05-24 01:44:07 -05:00
a90380f377 Merge commit 'e90dd887477452922f783535edb3d4c55e9a0d2c' 2025-05-23 03:23:17 -05:00
2000b2deee [nostalgia/gfx/studio] Cleanup 2025-05-17 23:35:10 -05:00
7d92400f6d [nostalgia/gfx/studio] Add type specific navigateTo functions 2025-05-17 23:26:23 -05:00
93 changed files with 530 additions and 459 deletions

View File

@@ -89,7 +89,7 @@ struct GLObject: public Base {
return id; return id;
} }
constexpr operator const GLuint&() const noexcept { constexpr operator GLuint const&() const noexcept {
return id; return id;
} }
@@ -135,7 +135,7 @@ struct FrameBuffer {
return fbo.id; return fbo.id;
} }
constexpr operator const GLuint&() const noexcept { constexpr operator GLuint const&() const noexcept {
return fbo.id; return fbo.id;
} }
@@ -158,14 +158,14 @@ struct FrameBuffer {
class FrameBufferBind { class FrameBufferBind {
private: private:
static const FrameBuffer *s_activeFb; static FrameBuffer const *s_activeFb;
const FrameBuffer *m_restoreFb = nullptr; FrameBuffer const *m_restoreFb = nullptr;
public: public:
explicit FrameBufferBind(const FrameBuffer &fb) noexcept; explicit FrameBufferBind(FrameBuffer const &fb) noexcept;
~FrameBufferBind() noexcept; ~FrameBufferBind() noexcept;
}; };
void bind(const FrameBuffer &fb) noexcept; void bind(FrameBuffer const &fb) noexcept;
struct ShaderVarSet { struct ShaderVarSet {
GLsizei len{}; GLsizei len{};
@@ -176,7 +176,7 @@ struct ProgramSource {
ox::Vector<glutils::ShaderVarSet> const shaderParams; ox::Vector<glutils::ShaderVarSet> const shaderParams;
GLsizei const rowLen = [this] { GLsizei const rowLen = [this] {
GLsizei len{}; GLsizei len{};
for (auto const&v : shaderParams) { for (auto const &v : shaderParams) {
len += v.len; len += v.len;
} }
return len; return len;
@@ -187,23 +187,23 @@ struct ProgramSource {
ox::String const geomShader{}; ox::String const geomShader{};
}; };
ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept; ox::Result<GLProgram> buildShaderProgram(ProgramSource const &src) noexcept;
ox::Result<GLProgram> buildShaderProgram( ox::Result<GLProgram> buildShaderProgram(
ox::CStringView const&vert, ox::CStringView const &vert,
ox::CStringView const&frag, ox::CStringView const &frag,
ox::CStringView const&geo = "") noexcept; ox::CStringView const &geo = "") noexcept;
void setupShaderParams( void setupShaderParams(
GLProgram const&shader, GLProgram const &shader,
ox::Vector<ShaderVarSet> const&vars, ox::Vector<ShaderVarSet> const &vars,
GLsizei vertexRowLen) noexcept; GLsizei vertexRowLen) noexcept;
void setupShaderParams(GLProgram const&shader, ox::Vector<ShaderVarSet> const&vars) noexcept; void setupShaderParams(GLProgram const &shader, ox::Vector<ShaderVarSet> const &vars) noexcept;
glutils::GLVertexArray generateVertexArrayObject() noexcept; GLVertexArray generateVertexArrayObject() noexcept;
glutils::GLBuffer generateBuffer() noexcept; GLBuffer generateBuffer() noexcept;
[[nodiscard]] [[nodiscard]]
FrameBuffer generateFrameBuffer(int width, int height) noexcept; FrameBuffer generateFrameBuffer(int width, int height) noexcept;
@@ -215,20 +215,20 @@ void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept;
*/ */
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept; void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept;
void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept; void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const &sz) noexcept;
struct BufferSet { struct BufferSet {
glutils::GLVertexArray vao; GLVertexArray vao;
glutils::GLBuffer vbo; GLBuffer vbo;
glutils::GLBuffer ebo; GLBuffer ebo;
glutils::GLTexture tex; GLTexture tex;
ox::Vector<float> vertices; ox::Vector<float> vertices;
ox::Vector<GLuint> elements; ox::Vector<GLuint> elements;
}; };
void sendVbo(BufferSet const&bs) noexcept; void sendVbo(BufferSet const &bs) noexcept;
void sendEbo(BufferSet const&bs) noexcept; void sendEbo(BufferSet const &bs) noexcept;
void clearScreen() noexcept; void clearScreen() noexcept;

View File

@@ -46,9 +46,9 @@ template struct GLObject<deleteVertexArray>;
template struct GLObject<deleteProgram>; template struct GLObject<deleteProgram>;
template struct GLObject<deleteShader>; template struct GLObject<deleteShader>;
const FrameBuffer *FrameBufferBind::s_activeFb = nullptr; FrameBuffer const *FrameBufferBind::s_activeFb = nullptr;
FrameBufferBind::FrameBufferBind(const FrameBuffer &fb) noexcept: m_restoreFb(s_activeFb) { FrameBufferBind::FrameBufferBind(FrameBuffer const &fb) noexcept: m_restoreFb(s_activeFb) {
s_activeFb = &fb; s_activeFb = &fb;
glBindFramebuffer(GL_FRAMEBUFFER, fb); glBindFramebuffer(GL_FRAMEBUFFER, fb);
glViewport(0, 0, fb.width, fb.height); glViewport(0, 0, fb.width, fb.height);
@@ -64,15 +64,15 @@ FrameBufferBind::~FrameBufferBind() noexcept {
} }
} }
void bind(const FrameBuffer &fb) noexcept { void bind(FrameBuffer const &fb) noexcept {
glBindFramebuffer(GL_FRAMEBUFFER, fb); glBindFramebuffer(GL_FRAMEBUFFER, fb);
glViewport(0, 0, fb.width, fb.height); glViewport(0, 0, fb.width, fb.height);
} }
static ox::Result<GLShader> buildShader( static ox::Result<GLShader> buildShader(
GLuint shaderType, GLuint const shaderType,
const GLchar *src, GLchar const *src,
ox::StringViewCR shaderName) noexcept { ox::StringViewCR shaderName) noexcept {
GLShader shader(glCreateShader(shaderType)); GLShader shader(glCreateShader(shaderType));
glShaderSource(shader, 1, &src, nullptr); glShaderSource(shader, 1, &src, nullptr);
@@ -88,7 +88,7 @@ static ox::Result<GLShader> buildShader(
return shader; return shader;
} }
ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept { ox::Result<GLProgram> buildShaderProgram(ProgramSource const &src) noexcept {
OX_REQUIRE_M(program, buildShaderProgram( OX_REQUIRE_M(program, buildShaderProgram(
src.vertShader, src.vertShader,
src.fragShader, src.fragShader,
@@ -98,11 +98,11 @@ ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept {
} }
void setupShaderParams( void setupShaderParams(
GLProgram const&shader, GLProgram const &shader,
ox::Vector<ShaderVarSet> const&vars, ox::Vector<ShaderVarSet> const &vars,
GLsizei vertexRowLen) noexcept { GLsizei vertexRowLen) noexcept {
// setup vars // setup vars
for (size_t lenWritten = 0; auto const&v : vars) { for (size_t lenWritten = 0; auto const &v : vars) {
auto const attr = static_cast<GLuint>(glGetAttribLocation(shader, v.name.c_str())); auto const attr = static_cast<GLuint>(glGetAttribLocation(shader, v.name.c_str()));
glEnableVertexAttribArray(attr); glEnableVertexAttribArray(attr);
glVertexAttribPointer( glVertexAttribPointer(
@@ -113,19 +113,19 @@ void setupShaderParams(
} }
} }
void setupShaderParams(GLProgram const&shader, ox::Vector<ShaderVarSet> const&vars) noexcept { void setupShaderParams(GLProgram const &shader, ox::Vector<ShaderVarSet> const &vars) noexcept {
// get row len // get row len
GLsizei vertexRowLen{}; GLsizei vertexRowLen{};
for (auto const&v : vars) { for (auto const &v : vars) {
vertexRowLen += v.len; vertexRowLen += v.len;
} }
setupShaderParams(shader, vars, vertexRowLen); setupShaderParams(shader, vars, vertexRowLen);
} }
ox::Result<GLProgram> buildShaderProgram( ox::Result<GLProgram> buildShaderProgram(
ox::CStringView const&vert, ox::CStringView const &vert,
ox::CStringView const&frag, ox::CStringView const &frag,
ox::CStringView const&geo) noexcept { ox::CStringView const &geo) noexcept {
GLProgram prgm(glCreateProgram()); GLProgram prgm(glCreateProgram());
OX_REQUIRE(vs, buildShader(GL_VERTEX_SHADER, vert.c_str(), "vshad")); OX_REQUIRE(vs, buildShader(GL_VERTEX_SHADER, vert.c_str(), "vshad"));
glAttachShader(prgm, vs); glAttachShader(prgm, vs);
@@ -162,16 +162,30 @@ FrameBuffer generateFrameBuffer(int width, int height) noexcept {
// color texture // color texture
glGenTextures(1, &fb.color.id); glGenTextures(1, &fb.color.id);
glBindTexture(GL_TEXTURE_2D, fb.color); glBindTexture(GL_TEXTURE_2D, fb.color);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB,
width,
height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
nullptr);
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.color, 0); glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.color, 0);
// depth texture // depth texture
glGenRenderbuffers(1, &fb.depth.id); glGenRenderbuffers(1, &fb.depth.id);
glBindRenderbuffer(GL_RENDERBUFFER, fb.depth); glBindRenderbuffer(GL_RENDERBUFFER, fb.depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb.depth); glFramebufferRenderbuffer(
GL_FRAMEBUFFER,
GL_DEPTH_STENCIL_ATTACHMENT,
GL_RENDERBUFFER,
fb.depth);
// verify FBO // verify FBO
oxAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame Buffer is incomplete"); oxAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame Buffer is incomplete");
// restore primary FB // restore primary FB
@@ -189,7 +203,16 @@ void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
glBindFramebuffer(GL_FRAMEBUFFER, fb); glBindFramebuffer(GL_FRAMEBUFFER, fb);
// color texture // color texture
glBindTexture(GL_TEXTURE_2D, fb.color); glBindTexture(GL_TEXTURE_2D, fb.color);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB,
width,
height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// depth texture // depth texture
@@ -201,7 +224,7 @@ void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0);
} }
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept { void resizeInitFrameBuffer(FrameBuffer &fb, int const width, int const height) noexcept {
if (!fb) { if (!fb) {
fb = generateFrameBuffer(width, height); fb = generateFrameBuffer(width, height);
return; return;
@@ -209,18 +232,18 @@ void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
resizeFrameBuffer(fb, width, height); resizeFrameBuffer(fb, width, height);
} }
void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept { void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const &sz) noexcept {
resizeInitFrameBuffer(fb, sz.width, sz.height); resizeInitFrameBuffer(fb, sz.width, sz.height);
} }
void sendVbo(BufferSet const&bs) noexcept { void sendVbo(BufferSet const &bs) noexcept {
const auto bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.vertices)::value_type) * bs.vertices.size()); auto const bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.vertices)::value_type) * bs.vertices.size());
glBindBuffer(GL_ARRAY_BUFFER, bs.vbo); glBindBuffer(GL_ARRAY_BUFFER, bs.vbo);
glBufferData(GL_ARRAY_BUFFER, bufferSize, bs.vertices.data(), GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, bufferSize, bs.vertices.data(), GL_DYNAMIC_DRAW);
} }
void sendEbo(BufferSet const&bs) noexcept { void sendEbo(BufferSet const &bs) noexcept {
const auto bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.elements)::value_type) * bs.elements.size()); auto const bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.elements)::value_type) * bs.elements.size());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bs.ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bs.ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferSize, bs.elements.data(), GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferSize, bs.elements.data(), GL_STATIC_DRAW);
} }

View File

@@ -16,35 +16,28 @@ namespace ox {
* StringLiteral is used for functions that want to ensure that they are taking * StringLiteral is used for functions that want to ensure that they are taking
* string literals, and not strings outside of the data section of the program * string literals, and not strings outside of the data section of the program
* that might get deleted. * that might get deleted.
* This type cannot force you to use it correctly, so don't give it something
* that is not a literal.
* If you do this:
* StringLiteral(str.c_str())
* the resulting segfault is on you.
*/ */
class StringLiteral: public detail::BaseStringView { class StringLiteral: public detail::BaseStringView {
public: public:
constexpr StringLiteral() noexcept = default; consteval StringLiteral() noexcept = default;
constexpr StringLiteral(StringLiteral const&sv) noexcept = default; constexpr StringLiteral(StringLiteral const &sv) noexcept = default;
constexpr explicit StringLiteral(std::nullptr_t) noexcept {} consteval explicit StringLiteral(std::nullptr_t) noexcept {}
constexpr explicit StringLiteral(const char *str, std::size_t len) noexcept: BaseStringView(str, len) {} consteval explicit StringLiteral(char const *str, std::size_t const len) noexcept: BaseStringView{str, len} {}
OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_ALLOW_UNSAFE_BUFFERS_BEGIN
constexpr explicit StringLiteral(char const *str) noexcept: StringLiteral(str, ox::strlen(str)) {} consteval explicit StringLiteral(char const *str) noexcept: StringLiteral{str, ox::strlen(str)} {}
OX_ALLOW_UNSAFE_BUFFERS_END OX_ALLOW_UNSAFE_BUFFERS_END
constexpr StringLiteral &operator=(StringLiteral const&other) noexcept { constexpr StringLiteral &operator=(StringLiteral const &other) noexcept {
if (&other != this) { set(other.data(), other.len());
set(other.data(), other.len());
}
return *this; return *this;
} }
[[nodiscard]] [[nodiscard]]
constexpr const char *c_str() const noexcept { constexpr char const *c_str() const noexcept {
return data(); return data();
} }

View File

@@ -37,7 +37,7 @@ struct OX_ALIGN8 GbaSpriteAttrUpdate {
GbaSpriteAttrUpdate &spriteAttr(size_t i) noexcept; GbaSpriteAttrUpdate &spriteAttr(size_t i) noexcept;
void addSpriteUpdate(const GbaSpriteAttrUpdate &upd) noexcept; void addSpriteUpdate(GbaSpriteAttrUpdate const &upd) noexcept;
void applySpriteUpdates() noexcept; void applySpriteUpdates() noexcept;

View File

@@ -26,7 +26,7 @@ extern void (*__preinit_array_end[]) (void);
extern void (*__init_array_start[]) (void); extern void (*__init_array_start[]) (void);
extern void (*__init_array_end[]) (void); extern void (*__init_array_end[]) (void);
int main(int argc, const char **argv); int main(int argc, char const **argv);
extern "C" { extern "C" {
@@ -50,7 +50,7 @@ void __libc_init_array() {
} }
int c_start() { int c_start() {
const char *args[2] = {"", "rom.oxfs"}; char const *args[2] = {"", "rom.oxfs"};
ox::heapmgr::initHeap(HEAP_BEGIN, HEAP_END); ox::heapmgr::initHeap(HEAP_BEGIN, HEAP_END);
mgba::initConsole(); mgba::initConsole();
#pragma GCC diagnostic push #pragma GCC diagnostic push

View File

@@ -16,7 +16,7 @@ GbaSpriteAttrUpdate &spriteAttr(size_t i) noexcept {
return g_spriteBuffer[i]; return g_spriteBuffer[i];
} }
void addSpriteUpdate(const GbaSpriteAttrUpdate &upd) noexcept { void addSpriteUpdate(GbaSpriteAttrUpdate const &upd) noexcept {
const auto ie = REG_IE; // disable vblank interrupt handler const auto ie = REG_IE; // disable vblank interrupt handler
REG_IE = REG_IE & static_cast<uint16_t>(~teagba::Int_vblank); // disable vblank interrupt handler REG_IE = REG_IE & static_cast<uint16_t>(~teagba::Int_vblank); // disable vblank interrupt handler
g_spriteBuffer[upd.idx] = upd; g_spriteBuffer[upd.idx] = upd;

View File

@@ -19,10 +19,10 @@ using Color32 = uint32_t;
[[nodiscard]] [[nodiscard]]
constexpr Color32 toColor32(Color16 nc) noexcept { constexpr Color32 toColor32(Color16 nc) noexcept {
const auto r = static_cast<Color32>(((nc & 0b0000000000011111) >> 0) * 8); auto const r = static_cast<Color32>(((nc & 0b0000000000011111) >> 0) * 8);
const auto g = static_cast<Color32>(((nc & 0b0000001111100000) >> 5) * 8); auto const g = static_cast<Color32>(((nc & 0b0000001111100000) >> 5) * 8);
const auto b = static_cast<Color32>(((nc & 0b0111110000000000) >> 10) * 8); auto const b = static_cast<Color32>(((nc & 0b0111110000000000) >> 10) * 8);
const auto a = static_cast<Color32>(255); auto const a = static_cast<Color32>(255);
return r | (g << 8) | (b << 16) | (a << 24); return r | (g << 8) | (b << 16) | (a << 24);
} }

View File

@@ -12,8 +12,18 @@ 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_nts{"nts"};
constexpr ox::StringLiteral FileExt_npal("npal"); constexpr ox::StringLiteral FileExt_npal{"npal"};
constexpr ox::Array<ox::StringLiteral, 2> FileExts_TileSheet{
FileExt_nts,
FileExt_ng,
};
[[nodiscard]]
constexpr bool isTileSheet(ox::StringViewCR path) noexcept {
return endsWith(path, FileExt_nts) || endsWith(path, FileExt_ng);
}
} }

View File

@@ -111,23 +111,23 @@ struct InitParams {
uint_t glBlocksPerSprite = 64; uint_t glBlocksPerSprite = 64;
}; };
ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const&params = {}) noexcept; ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const &params = {}) noexcept;
[[nodiscard]] [[nodiscard]]
int tileColumns(Context&) noexcept; int tileColumns(Context const&) noexcept;
[[nodiscard]] [[nodiscard]]
int tileRows(Context&) noexcept; int tileRows(Context const&) noexcept;
ox::Error loadBgPalette( ox::Error loadBgPalette(
Context &ctx, Context &ctx,
size_t palBank, size_t palBank,
CompactPalette const&palette, CompactPalette const &palette,
size_t page = 0) noexcept; size_t page = 0) noexcept;
ox::Error loadSpritePalette( ox::Error loadSpritePalette(
Context &ctx, Context &ctx,
CompactPalette const&palette, CompactPalette const &palette,
size_t page = 0) noexcept; size_t page = 0) noexcept;
ox::Error loadBgPalette( ox::Error loadBgPalette(
@@ -138,7 +138,7 @@ ox::Error loadBgPalette(
ox::Error loadBgPalette( ox::Error loadBgPalette(
Context &ctx, Context &ctx,
size_t palBank, size_t palBank,
ox::FileAddress const&paletteAddr) noexcept; ox::FileAddress const &paletteAddr) noexcept;
ox::Error loadSpritePalette( ox::Error loadSpritePalette(
Context &ctx, Context &ctx,
@@ -146,12 +146,12 @@ ox::Error loadSpritePalette(
ox::Error loadSpritePalette( ox::Error loadSpritePalette(
Context &ctx, Context &ctx,
ox::FileAddress const&paletteAddr) noexcept; ox::FileAddress const &paletteAddr) noexcept;
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned cbb, unsigned cbb,
TileSheetSet const&set) noexcept; TileSheetSet const &set) noexcept;
void clearCbb(Context &ctx, unsigned cbb) noexcept; void clearCbb(Context &ctx, unsigned cbb) noexcept;
@@ -160,7 +160,7 @@ void clearCbbs(Context &ctx) noexcept;
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned cbb, unsigned cbb,
CompactTileSheet const&ts, CompactTileSheet const &ts,
size_t dstTileIdx, size_t dstTileIdx,
size_t srcTileIdx, size_t srcTileIdx,
size_t tileCnt) noexcept; size_t tileCnt) noexcept;
@@ -176,7 +176,7 @@ ox::Error loadBgTileSheet(
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned cbb, unsigned cbb,
ox::FileAddress const&tsAddr, ox::FileAddress const &tsAddr,
size_t dstTileIdx, size_t dstTileIdx,
size_t srcTileIdx, size_t srcTileIdx,
size_t tileCnt) noexcept; size_t tileCnt) noexcept;
@@ -184,24 +184,24 @@ ox::Error loadBgTileSheet(
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned cbb, unsigned cbb,
CompactTileSheet const&ts, CompactTileSheet const &ts,
ox::Optional<unsigned> const&paletteBank = {}) noexcept; ox::Optional<unsigned> const &paletteBank = {}) noexcept;
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned cbb, unsigned cbb,
ox::StringViewCR tilesheetPath, ox::StringViewCR tilesheetPath,
ox::Optional<unsigned> const&paletteBank) noexcept; ox::Optional<unsigned> const &paletteBank) noexcept;
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned cbb, unsigned cbb,
ox::FileAddress const&tilesheetAddr, ox::FileAddress const &tilesheetAddr,
ox::Optional<unsigned> const&paletteBank = {}) noexcept; ox::Optional<unsigned> const &paletteBank = {}) noexcept;
ox::Error loadSpriteTileSheet( ox::Error loadSpriteTileSheet(
Context &ctx, Context &ctx,
CompactTileSheet const&ts, CompactTileSheet const &ts,
bool loadDefaultPalette) noexcept; bool loadDefaultPalette) noexcept;
ox::Error loadSpriteTileSheet( ox::Error loadSpriteTileSheet(
@@ -211,16 +211,16 @@ ox::Error loadSpriteTileSheet(
ox::Error loadSpriteTileSheet( ox::Error loadSpriteTileSheet(
Context &ctx, Context &ctx,
ox::FileAddress const&tilesheetAddr, ox::FileAddress const &tilesheetAddr,
bool loadDefaultPalette = false) noexcept; bool loadDefaultPalette = false) noexcept;
ox::Error loadSpriteTileSheet( ox::Error loadSpriteTileSheet(
Context &ctx, Context &ctx,
TileSheetSet const&set) noexcept; TileSheetSet const &set) noexcept;
void setBgTile(Context &ctx, uint_t bgIdx, int column, int row, unsigned tile, unsigned palBank = 0) noexcept; void setBgTile(Context &ctx, uint_t bgIdx, int column, int row, unsigned tile, unsigned palBank = 0) noexcept;
void setBgTile(Context &ctx, uint_t bgIdx, int column, int row, BgTile const&tile) noexcept; void setBgTile(Context &ctx, uint_t bgIdx, int column, int row, BgTile const &tile) noexcept;
void clearBg(Context &ctx, uint_t bgIdx) noexcept; void clearBg(Context &ctx, uint_t bgIdx) noexcept;
@@ -242,7 +242,7 @@ void hideSprite(Context &ctx, unsigned) noexcept;
void showSprite(Context &ctx, unsigned) noexcept; void showSprite(Context &ctx, unsigned) noexcept;
void setSprite(Context &ctx, uint_t idx, Sprite const&sprite) noexcept; void setSprite(Context &ctx, uint_t idx, Sprite const &sprite) noexcept;
[[nodiscard]] [[nodiscard]]
uint_t spriteCount(Context const &ctx) noexcept; uint_t spriteCount(Context const &ctx) noexcept;
@@ -260,7 +260,7 @@ constexpr ox::CStringView GlslVersion = "#version 330";
[[nodiscard]] [[nodiscard]]
ox::Size drawSize(int scale = 5) noexcept; ox::Size drawSize(int scale = 5) noexcept;
void draw(gfx::Context &ctx, ox::Size const&renderSz) noexcept; void draw(gfx::Context &ctx, ox::Size const &renderSz) noexcept;
void draw(gfx::Context&, int scale = 5) noexcept; void draw(gfx::Context&, int scale = 5) noexcept;

View File

@@ -12,15 +12,15 @@ 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 {
const auto tileWidth = TileWidth * scale; auto const tileWidth = TileWidth * scale;
const auto tileHeight = TileHeight * scale; auto const tileHeight = TileHeight * scale;
const auto pixelsPerTile = tileWidth * tileHeight; auto const pixelsPerTile = tileWidth * tileHeight;
const auto colLength = static_cast<std::size_t>(pixelsPerTile); auto const colLength = static_cast<std::size_t>(pixelsPerTile);
const auto rowLength = static_cast<std::size_t>(static_cast<std::size_t>(c / tileWidth) * colLength); auto const rowLength = static_cast<std::size_t>(static_cast<std::size_t>(c / tileWidth) * colLength);
const auto colStart = static_cast<std::size_t>(colLength * static_cast<std::size_t>(x / tileWidth)); auto const colStart = static_cast<std::size_t>(colLength * static_cast<std::size_t>(x / tileWidth));
const auto rowStart = static_cast<std::size_t>(rowLength * static_cast<std::size_t>(y / tileHeight)); auto const rowStart = static_cast<std::size_t>(rowLength * static_cast<std::size_t>(y / tileHeight));
const auto colOffset = static_cast<std::size_t>(x % tileWidth); auto const colOffset = static_cast<std::size_t>(x % tileWidth);
const auto rowOffset = static_cast<std::size_t>((y % tileHeight) * tileHeight); auto const rowOffset = static_cast<std::size_t>((y % tileHeight) * tileHeight);
return static_cast<std::size_t>(colStart + colOffset + rowStart + rowOffset); return static_cast<std::size_t>(colStart + colOffset + rowStart + rowOffset);
} }
@@ -31,19 +31,19 @@ constexpr std::size_t ptToIdx(const ox::Point &pt, int c, int scale = 1) noexcep
[[nodiscard]] [[nodiscard]]
constexpr ox::Point idxToPt(int i, int c, int scale = 1) noexcept { constexpr ox::Point idxToPt(int i, int c, int scale = 1) noexcept {
const auto tileWidth = TileWidth * scale; auto const tileWidth = TileWidth * scale;
const auto tileHeight = TileHeight * scale; auto const tileHeight = TileHeight * scale;
const auto pixelsPerTile = tileWidth * tileHeight; auto const pixelsPerTile = tileWidth * tileHeight;
// prevent divide by zeros // prevent divide by zeros
if (!c) { if (!c) {
++c; ++c;
} }
const auto t = i / pixelsPerTile; // tile number auto const t = i / pixelsPerTile; // tile number
const auto iti = i % pixelsPerTile; // in tile index auto const iti = i % pixelsPerTile; // in tile index
const auto tc = t % c; // tile column auto const tc = t % c; // tile column
const auto tr = t / c; // tile row auto const tr = t / c; // tile row
const auto itx = iti % tileWidth; // in tile x auto const itx = iti % tileWidth; // in tile x
const auto ity = iti / tileHeight; // in tile y auto const ity = iti / tileHeight; // in tile y
return { return {
itx + tc * tileWidth, itx + tc * tileWidth,
ity + tr * tileHeight, ity + tr * tileHeight,

View File

@@ -6,6 +6,28 @@
#include <studio/studio.hpp> #include <studio/studio.hpp>
namespace nostalgia::core { #include "tilesheet.hpp"
namespace nostalgia::gfx {
inline void navigateToTileSheet(
studio::Context &ctx, ox::StringParam path, SubSheetId const subsheetId) noexcept {
studio::navigateTo(ctx, std::move(path), ox::intToStr(subsheetId));
}
inline void navigateToPalette(studio::Context &ctx, ox::StringParam path) noexcept {
studio::navigateTo(ctx, std::move(path));
}
inline void navigateToPalette(
studio::Context &ctx,
ox::StringParam path,
size_t const colorIdx,
size_t const palPage) noexcept {
studio::navigateTo(
ctx,
std::move(path),
ox::sfmt("{};{}", colorIdx, palPage));
}
} }

View File

@@ -31,12 +31,12 @@ class Context {
explicit Context(turbine::Context &tctx) noexcept: turbineCtx{tctx} {} explicit Context(turbine::Context &tctx) noexcept: turbineCtx{tctx} {}
Context(Context &other) noexcept = delete; Context(Context &other) noexcept = delete;
Context(Context const&other) noexcept = delete; Context(Context const &other) noexcept = delete;
Context(Context const&&other) noexcept = delete; Context(Context const &&other) noexcept = delete;
virtual ~Context() noexcept = default; virtual ~Context() noexcept = default;
[[nodiscard]] [[nodiscard]]
ox::MemFS const&rom() const noexcept { ox::MemFS const &rom() const noexcept {
return static_cast<ox::MemFS const&>(*turbine::rom(turbineCtx)); return static_cast<ox::MemFS const&>(*turbine::rom(turbineCtx));
} }
@@ -76,7 +76,7 @@ ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const&) no
ox::Error loadBgPalette( ox::Error loadBgPalette(
Context&, Context&,
size_t const palBank, size_t const palBank,
CompactPalette const&palette, CompactPalette const &palette,
size_t const page) noexcept { size_t const page) noexcept {
if (palette.pages.empty()) { if (palette.pages.empty()) {
return {}; return {};
@@ -90,7 +90,7 @@ ox::Error loadBgPalette(
ox::Error loadSpritePalette( ox::Error loadSpritePalette(
Context&, Context&,
CompactPalette const&palette, CompactPalette const &palette,
size_t const page) noexcept { size_t const page) noexcept {
if (palette.pages.empty()) { if (palette.pages.empty()) {
return {}; return {};
@@ -118,15 +118,15 @@ void clearCbbs(Context &ctx) noexcept {
static ox::Error loadTileSheetSet( static ox::Error loadTileSheetSet(
Context &ctx, Context &ctx,
ox::Span<uint16_t> tileMapTargetMem, ox::Span<uint16_t> tileMapTargetMem,
TileSheetSet const&set) noexcept { TileSheetSet const &set) noexcept {
size_t tileWriteIdx = 0; size_t tileWriteIdx = 0;
size_t const bppMod = set.bpp == 4; size_t const bppMod = set.bpp == 4;
for (auto const&entry : set.entries) { for (auto const &entry : set.entries) {
OX_REQUIRE(ts, keel::readObj<CompactTileSheet>(keelCtx(ctx), entry.tilesheet)); OX_REQUIRE(ts, keel::readObj<CompactTileSheet>(keelCtx(ctx), entry.tilesheet));
if (set.bpp != ts->bpp && ts->bpp == 8) { if (set.bpp != ts->bpp && ts->bpp == 8) {
return ox::Error(1, "cannot load an 8 BPP tilesheet into a 4 BPP CBB"); return ox::Error(1, "cannot load an 8 BPP tilesheet into a 4 BPP CBB");
} }
for (auto const&s : entry.sections) { for (auto const &s : entry.sections) {
auto const cnt = (static_cast<size_t>(s.tiles) * PixelsPerTile) >> bppMod; auto const cnt = (static_cast<size_t>(s.tiles) * PixelsPerTile) >> bppMod;
for (size_t i = 0; i < cnt; ++i) { for (size_t i = 0; i < cnt; ++i) {
auto const begin = static_cast<size_t>(s.begin) * (PixelsPerTile >> bppMod); auto const begin = static_cast<size_t>(s.begin) * (PixelsPerTile >> bppMod);
@@ -145,7 +145,7 @@ static ox::Error loadTileSheetSet(
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned const cbb, unsigned const cbb,
CompactTileSheet const&ts, CompactTileSheet const &ts,
size_t const dstTileIdx, size_t const dstTileIdx,
size_t const srcTileIdx, size_t const srcTileIdx,
size_t const tileCnt) noexcept { size_t const tileCnt) noexcept {
@@ -173,8 +173,8 @@ ox::Error loadBgTileSheet(
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned const cbb, unsigned const cbb,
CompactTileSheet const&ts, CompactTileSheet const &ts,
ox::Optional<unsigned> const&paletteBank) noexcept { ox::Optional<unsigned> const &paletteBank) noexcept {
auto const cnt = (ts.pixels.size() * PixelsPerTile) / (1 + (ts.bpp == 4)); auto const cnt = (ts.pixels.size() * PixelsPerTile) / (1 + (ts.bpp == 4));
for (size_t i = 0; i < cnt; ++i) { for (size_t i = 0; i < cnt; ++i) {
auto const srcIdx = i * 2; auto const srcIdx = i * 2;
@@ -198,7 +198,7 @@ ox::Error loadBgTileSheet(
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned const cbb, unsigned const cbb,
TileSheetSet const&set) noexcept { TileSheetSet const &set) noexcept {
auto const bpp = static_cast<unsigned>(set.bpp); auto const bpp = static_cast<unsigned>(set.bpp);
OX_RETURN_ERROR(loadTileSheetSet(ctx, MEM_BG_TILES[cbb], set)); OX_RETURN_ERROR(loadTileSheetSet(ctx, MEM_BG_TILES[cbb], set));
// update bpp of all bgs with the updated cbb // update bpp of all bgs with the updated cbb
@@ -222,7 +222,7 @@ static void setSpritesBpp(unsigned const bpp) noexcept {
ox::Error loadSpriteTileSheet( ox::Error loadSpriteTileSheet(
Context &ctx, Context &ctx,
CompactTileSheet const&ts, CompactTileSheet const &ts,
bool const loadDefaultPalette) noexcept { bool const loadDefaultPalette) noexcept {
for (size_t i = 0; i < ts.pixels.size(); i += 2) { for (size_t i = 0; i < ts.pixels.size(); i += 2) {
uint16_t v = ts.pixels[i]; uint16_t v = ts.pixels[i];
@@ -238,7 +238,7 @@ ox::Error loadSpriteTileSheet(
ox::Error loadSpriteTileSheet( ox::Error loadSpriteTileSheet(
Context &ctx, Context &ctx,
TileSheetSet const&set) noexcept { TileSheetSet const &set) noexcept {
auto const bpp = static_cast<unsigned>(set.bpp); auto const bpp = static_cast<unsigned>(set.bpp);
OX_RETURN_ERROR(loadTileSheetSet(ctx, {MEM_SPRITE_TILES, 32 * ox::units::KB}, set)); OX_RETURN_ERROR(loadTileSheetSet(ctx, {MEM_SPRITE_TILES, 32 * ox::units::KB}, set));
setSpritesBpp(bpp); setSpritesBpp(bpp);
@@ -246,7 +246,11 @@ ox::Error loadSpriteTileSheet(
} }
void setBgTile( void setBgTile(
Context &ctx, uint_t const bgIdx, int const column, int const row, BgTile const&tile) noexcept { Context &ctx,
uint_t const bgIdx,
int const column,
int const row,
BgTile const &tile) noexcept {
auto const tileIdx = static_cast<std::size_t>(row * tileColumns(ctx) + column); auto const tileIdx = static_cast<std::size_t>(row * tileColumns(ctx) + column);
// see Tonc 9.3 // see Tonc 9.3
MEM_BG_MAP[bgIdx][tileIdx] = MEM_BG_MAP[bgIdx][tileIdx] =
@@ -275,7 +279,7 @@ bool bgStatus(Context&, unsigned const bg) noexcept {
void setBgStatus(Context&, unsigned const bg, bool const status) noexcept { void setBgStatus(Context&, unsigned const bg, bool const status) noexcept {
constexpr auto Bg0Status = 8; constexpr auto Bg0Status = 8;
const auto mask = static_cast<uint32_t>(status) << (Bg0Status + bg); auto const mask = static_cast<uint32_t>(status) << (Bg0Status + bg);
REG_DISPCTL = REG_DISPCTL | ((REG_DISPCTL & ~mask) | mask); REG_DISPCTL = REG_DISPCTL | ((REG_DISPCTL & ~mask) | mask);
} }
@@ -286,7 +290,7 @@ void setBgBpp(Context&, unsigned const bgIdx, unsigned const bpp) noexcept {
void setBgCbb(Context &ctx, unsigned const bgIdx, unsigned const cbbIdx) noexcept { void setBgCbb(Context &ctx, unsigned const bgIdx, unsigned const cbbIdx) noexcept {
auto &bgCtl = regBgCtl(bgIdx); auto &bgCtl = regBgCtl(bgIdx);
const auto &cbbData = ctx.cbbData[cbbIdx]; auto const &cbbData = ctx.cbbData[cbbIdx];
teagba::bgSetBpp(bgCtl, cbbData.bpp); teagba::bgSetBpp(bgCtl, cbbData.bpp);
teagba::bgSetCbb(bgCtl, cbbIdx); teagba::bgSetCbb(bgCtl, cbbIdx);
} }
@@ -312,7 +316,7 @@ void showSprite(Context&, unsigned const idx) noexcept {
}); });
} }
void setSprite(Context&, uint_t const idx, Sprite const&s) noexcept { void setSprite(Context&, uint_t const idx, Sprite const &s) noexcept {
//oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow"); //oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow");
uint16_t const eightBpp = s.bpp == 8; uint16_t const eightBpp = s.bpp == 8;
teagba::addSpriteUpdate({ teagba::addSpriteUpdate({
@@ -333,7 +337,7 @@ void setSprite(Context&, uint_t const idx, Sprite const&s) noexcept {
}); });
} }
uint_t spriteCount(Context const&) noexcept { uint_t spriteCount(Context const &) noexcept {
return SpriteCount; return SpriteCount;
} }
@@ -341,13 +345,13 @@ uint_t spriteCount(Context const&) noexcept {
namespace ox { namespace ox {
void panic(const char *file, int line, const char *panicMsg, ox::Error const&err) noexcept { void panic(char const *file, int line, char const *panicMsg, ox::Error const &err) noexcept {
using namespace nostalgia::gfx; using namespace nostalgia::gfx;
// 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
OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_ALLOW_UNSAFE_BUFFERS_BEGIN
const auto heapBegin = reinterpret_cast<char*>(MEM_EWRAM_BEGIN); auto const heapBegin = reinterpret_cast<char*>(MEM_EWRAM_BEGIN);
const auto heapSz = (MEM_EWRAM_END - MEM_EWRAM_BEGIN) / 2; auto const heapSz = (MEM_EWRAM_END - MEM_EWRAM_BEGIN) / 2;
const auto heapEnd = reinterpret_cast<char*>(MEM_EWRAM_BEGIN + heapSz); auto const heapEnd = reinterpret_cast<char*>(MEM_EWRAM_BEGIN + heapSz);
ox::heapmgr::initHeap(heapBegin, heapEnd); ox::heapmgr::initHeap(heapBegin, heapEnd);
OX_ALLOW_UNSAFE_BUFFERS_END OX_ALLOW_UNSAFE_BUFFERS_END
auto tctx = turbine::init(keel::loadRomFs("").unwrap(), "Nostalgia").unwrap(); auto tctx = turbine::init(keel::loadRomFs("").unwrap(), "Nostalgia").unwrap();

View File

@@ -287,7 +287,7 @@ static void initSpriteBufferObjects(Context const &ctx, glutils::BufferSet &bs)
static void initBackgroundBufferObjects(glutils::BufferSet &bs) noexcept { 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); auto const i = bgVertexRow(x, y);
auto const vbo = ox::Span{bs.vertices} auto const vbo = ox::Span{bs.vertices}
+ i * static_cast<std::size_t>(BgVertexVboLength); + i * static_cast<std::size_t>(BgVertexVboLength);
auto const ebo = ox::Span{bs.elements} auto const ebo = ox::Span{bs.elements}
@@ -387,7 +387,7 @@ static void initBackgroundBufferset(
static glutils::GLTexture createTexture( static glutils::GLTexture createTexture(
GLsizei const w, GLsizei const w,
GLsizei const h, GLsizei const h,
void const*pixels) noexcept { void const *pixels) noexcept {
GLuint texId = 0; GLuint texId = 0;
glGenTextures(1, &texId); glGenTextures(1, &texId);
glutils::GLTexture tex(texId); glutils::GLTexture tex(texId);
@@ -425,22 +425,22 @@ static void drawBackground(CBB &cbb) noexcept {
static void drawBackgrounds( static void drawBackgrounds(
Context &ctx, Context &ctx,
ox::Size const&renderSz) noexcept { ox::Size const &renderSz) noexcept {
// load background shader and its uniforms // load background shader and its uniforms
glUseProgram(ctx.bgShader); glUseProgram(ctx.bgShader);
const auto uniformSrcImgSz = glGetUniformLocation(ctx.bgShader, "fSrcImgSz"); auto const uniformSrcImgSz = glGetUniformLocation(ctx.bgShader, "fSrcImgSz");
const auto uniformXScale = static_cast<GLint>(glGetUniformLocation(ctx.bgShader, "vXScale")); auto const uniformXScale = static_cast<GLint>(glGetUniformLocation(ctx.bgShader, "vXScale"));
const auto uniformTileHeight = static_cast<GLint>(glGetUniformLocation(ctx.bgShader, "vTileHeight")); auto const uniformTileHeight = static_cast<GLint>(glGetUniformLocation(ctx.bgShader, "vTileHeight"));
const auto uniformBgIdx = static_cast<GLint>(glGetUniformLocation(ctx.bgShader, "vBgIdx")); auto const uniformBgIdx = static_cast<GLint>(glGetUniformLocation(ctx.bgShader, "vBgIdx"));
const auto [wi, hi] = renderSz; auto const [wi, hi] = renderSz;
const auto wf = static_cast<float>(wi); auto const wf = static_cast<float>(wi);
const auto hf = static_cast<float>(hi); auto const hf = static_cast<float>(hi);
glUniform1f(uniformXScale, hf / wf); glUniform1f(uniformXScale, hf / wf);
auto bgIdx = 0.f; auto bgIdx = 0.f;
for (const auto &bg : ctx.backgrounds) { for (auto const &bg : ctx.backgrounds) {
if (bg.enabled) { if (bg.enabled) {
auto &cbb = ctx.cbbs[bg.cbbIdx]; auto &cbb = ctx.cbbs[bg.cbbIdx];
const auto tileRows = cbb.tex.height / (TileHeight * Scale); auto const tileRows = cbb.tex.height / (TileHeight * Scale);
glUniform1f(uniformTileHeight, 1.0f / static_cast<float>(tileRows)); glUniform1f(uniformTileHeight, 1.0f / static_cast<float>(tileRows));
glUniform2f( glUniform2f(
uniformSrcImgSz, uniformSrcImgSz,
@@ -456,11 +456,11 @@ static void drawBackgrounds(
static void drawSprites(Context &ctx, ox::Size const&renderSz) noexcept { static void drawSprites(Context &ctx, ox::Size const&renderSz) noexcept {
glUseProgram(ctx.spriteShader); glUseProgram(ctx.spriteShader);
auto &sb = ctx.spriteBlocks; auto &sb = ctx.spriteBlocks;
const auto uniformXScale = glGetUniformLocation(ctx.bgShader, "vXScale"); auto const uniformXScale = glGetUniformLocation(ctx.bgShader, "vXScale");
const auto uniformTileHeight = glGetUniformLocation(ctx.spriteShader, "vTileHeight"); auto const uniformTileHeight = glGetUniformLocation(ctx.spriteShader, "vTileHeight");
const auto [wi, hi] = renderSz; auto const [wi, hi] = renderSz;
const auto wf = static_cast<float>(wi); auto const wf = static_cast<float>(wi);
const auto hf = static_cast<float>(hi); auto const hf = static_cast<float>(hi);
glUniform1f(uniformXScale, hf / wf); glUniform1f(uniformXScale, hf / wf);
// update vbo // update vbo
glBindVertexArray(sb.vao); glBindVertexArray(sb.vao);
@@ -469,7 +469,7 @@ static void drawSprites(Context &ctx, ox::Size const&renderSz) noexcept {
glutils::sendVbo(sb); glutils::sendVbo(sb);
} }
// set vTileHeight uniform // set vTileHeight uniform
const auto tileRows = sb.tex.height / (TileHeight * Scale); auto const tileRows = sb.tex.height / (TileHeight * Scale);
glUniform1f(uniformTileHeight, 1.0f / static_cast<float>(tileRows)); glUniform1f(uniformTileHeight, 1.0f / static_cast<float>(tileRows));
// draw // draw
glBindTexture(GL_TEXTURE_2D, sb.tex); glBindTexture(GL_TEXTURE_2D, sb.tex);
@@ -493,7 +493,7 @@ static void loadPalette(
// make first color transparent // make first color transparent
palette[palOffset + 3] = 0; palette[palOffset + 3] = 0;
glUseProgram(shaderPgrm); glUseProgram(shaderPgrm);
const auto uniformPalette = static_cast<GLint>(glGetUniformLocation(shaderPgrm, "fPalette")); auto const uniformPalette = static_cast<GLint>(glGetUniformLocation(shaderPgrm, "fPalette"));
glUniform4fv(uniformPalette, ColorCnt, palette.data()); glUniform4fv(uniformPalette, ColorCnt, palette.data());
} }
@@ -526,12 +526,12 @@ static void setSprite(
auto const uY = static_cast<int>(s.y + 8) % 255 - 8; auto const uY = static_cast<int>(s.y + 8) % 255 - 8;
oxAssert(1 < ctx.spriteBlocks.vertices.size(), "vbo overflow"); oxAssert(1 < ctx.spriteBlocks.vertices.size(), "vbo overflow");
oxAssert(1 < ctx.spriteBlocks.elements.size(), "ebo overflow"); oxAssert(1 < ctx.spriteBlocks.elements.size(), "ebo overflow");
const auto spriteVboSz = ctx.blocksPerSprite * renderer::SpriteVertexVboLength; auto const spriteVboSz = ctx.blocksPerSprite * renderer::SpriteVertexVboLength;
const auto spriteEboSz = ctx.blocksPerSprite * renderer::SpriteVertexEboLength; auto const spriteEboSz = ctx.blocksPerSprite * renderer::SpriteVertexEboLength;
auto const vboBase = spriteVboSz * idx; auto const vboBase = spriteVboSz * idx;
auto const eboBase = spriteEboSz * idx; auto const eboBase = spriteEboSz * idx;
auto i = 0u; auto i = 0u;
const auto set = [&](int xIt, int yIt, bool enabled) { auto const set = [&](int xIt, int yIt, bool enabled) {
auto const fX = static_cast<float>(uX + xIt * 8) / 8; auto const fX = static_cast<float>(uX + xIt * 8) / 8;
auto const fY = static_cast<float>(uY + yIt * 8) / 8; auto const fY = static_cast<float>(uY + yIt * 8) / 8;
auto const vboIdx = vboBase + renderer::SpriteVertexVboLength * i; auto const vboIdx = vboBase + renderer::SpriteVertexVboLength * i;
@@ -576,10 +576,10 @@ static void setSprite(
ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const&params) noexcept { ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const&params) noexcept {
auto ctx = ox::make_unique<Context>(tctx, params); auto ctx = ox::make_unique<Context>(tctx, params);
const auto bgVshad = ox::sfmt(renderer::bgvshadTmpl, gl::GlslVersion); auto const bgVshad = ox::sfmt(renderer::bgvshadTmpl, gl::GlslVersion);
const auto bgFshad = ox::sfmt(renderer::bgfshadTmpl, gl::GlslVersion); auto const bgFshad = ox::sfmt(renderer::bgfshadTmpl, gl::GlslVersion);
const auto spriteVshad = ox::sfmt(renderer::spritevshadTmpl, gl::GlslVersion); auto const spriteVshad = ox::sfmt(renderer::spritevshadTmpl, gl::GlslVersion);
const auto spriteFshad = ox::sfmt(renderer::spritefshadTmpl, gl::GlslVersion); auto const spriteFshad = ox::sfmt(renderer::spritefshadTmpl, gl::GlslVersion);
OX_RETURN_ERROR(glutils::buildShaderProgram(bgVshad, bgFshad).moveTo(ctx->bgShader)); OX_RETURN_ERROR(glutils::buildShaderProgram(bgVshad, bgFshad).moveTo(ctx->bgShader));
OX_RETURN_ERROR( OX_RETURN_ERROR(
glutils::buildShaderProgram(spriteVshad, spriteFshad).moveTo(ctx->spriteShader)); glutils::buildShaderProgram(spriteVshad, spriteFshad).moveTo(ctx->spriteShader));
@@ -603,12 +603,12 @@ struct TileSheetData {
} }
}; };
static ox::Result<TileSheetData> normalizeTileSheet( static ox::Result<TileSheetData> normalizeTileSheet
CompactTileSheet const&ts) noexcept { (CompactTileSheet const&ts) noexcept {
const uint_t bytesPerTile = ts.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2; const uint_t bytesPerTile = ts.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2;
const auto tiles = ts.pixels.size() / bytesPerTile; auto const tiles = ts.pixels.size() / bytesPerTile;
constexpr int width = 8; constexpr int width = 8;
const int height = 8 * static_cast<int>(tiles); int const height = 8 * static_cast<int>(tiles);
ox::Vector<uint32_t> pixels; ox::Vector<uint32_t> pixels;
if (bytesPerTile == 64) { // 8 BPP if (bytesPerTile == 64) { // 8 BPP
pixels.resize(ts.pixels.size()); pixels.resize(ts.pixels.size());
@@ -779,13 +779,13 @@ void setBgTile(
"nostalgia.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); auto const z = static_cast<uint_t>(bgIdx);
const auto y = static_cast<uint_t>(row); auto const y = static_cast<uint_t>(row);
const auto x = static_cast<uint_t>(column); auto const x = static_cast<uint_t>(column);
const auto i = renderer::bgVertexRow(x, y); auto const i = renderer::bgVertexRow(x, y);
auto &cbb = ctx.cbbs[z]; auto &cbb = ctx.cbbs[z];
const auto vbo = ox::Span{cbb.vertices} + i * renderer::BgVertexVboLength; auto const vbo = ox::Span{cbb.vertices} + i * renderer::BgVertexVboLength;
const auto ebo = ox::Span{cbb.elements} + i * renderer::BgVertexEboLength; auto const 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),

View File

@@ -10,11 +10,11 @@ namespace nostalgia::gfx {
constexpr auto GbaTileColumns = 32; constexpr auto GbaTileColumns = 32;
constexpr auto GbaTileRows = 32; constexpr auto GbaTileRows = 32;
int tileColumns(Context&) noexcept { int tileColumns(Context const&) noexcept {
return GbaTileColumns; return GbaTileColumns;
} }
int tileRows(Context&) noexcept { int tileRows(Context const&) noexcept {
return GbaTileRows; return GbaTileRows;
} }
@@ -51,7 +51,7 @@ ox::Error loadSpritePalette(
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned const cbb, unsigned const cbb,
ox::FileAddress const&tsAddr, ox::FileAddress const &tsAddr,
size_t const dstTileIdx, size_t const dstTileIdx,
size_t const srcTileIdx, size_t const srcTileIdx,
size_t const tileCnt) noexcept { size_t const tileCnt) noexcept {
@@ -74,7 +74,7 @@ ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned const cbb, unsigned const cbb,
ox::StringViewCR tilesheetPath, ox::StringViewCR tilesheetPath,
ox::Optional<unsigned> const&paletteBank) noexcept { ox::Optional<unsigned> const &paletteBank) noexcept {
OX_REQUIRE(ts, keel::readObj<CompactTileSheet>(keelCtx(ctx), tilesheetPath)); OX_REQUIRE(ts, keel::readObj<CompactTileSheet>(keelCtx(ctx), tilesheetPath));
return loadBgTileSheet(ctx, cbb, *ts, paletteBank); return loadBgTileSheet(ctx, cbb, *ts, paletteBank);
} }
@@ -82,8 +82,8 @@ ox::Error loadBgTileSheet(
ox::Error loadBgTileSheet( ox::Error loadBgTileSheet(
Context &ctx, Context &ctx,
unsigned const cbb, unsigned const cbb,
ox::FileAddress const&tilesheetAddr, ox::FileAddress const &tilesheetAddr,
ox::Optional<unsigned> const&paletteBank) noexcept { ox::Optional<unsigned> const &paletteBank) noexcept {
OX_REQUIRE(ts, keel::readObj<CompactTileSheet>(keelCtx(ctx), tilesheetAddr)); OX_REQUIRE(ts, keel::readObj<CompactTileSheet>(keelCtx(ctx), tilesheetAddr));
return loadBgTileSheet(ctx, cbb, *ts, paletteBank); return loadBgTileSheet(ctx, cbb, *ts, paletteBank);
} }
@@ -98,7 +98,7 @@ ox::Error loadSpriteTileSheet(
ox::Error loadSpriteTileSheet( ox::Error loadSpriteTileSheet(
Context &ctx, Context &ctx,
ox::FileAddress const&tilesheetAddr, ox::FileAddress const &tilesheetAddr,
bool const loadDefaultPalette) noexcept { bool const loadDefaultPalette) noexcept {
OX_REQUIRE(ts, readObj<CompactTileSheet>(keelCtx(ctx), tilesheetAddr)); OX_REQUIRE(ts, readObj<CompactTileSheet>(keelCtx(ctx), tilesheetAddr));
return loadSpriteTileSheet(ctx, *ts, loadDefaultPalette); return loadSpriteTileSheet(ctx, *ts, loadDefaultPalette);

View File

@@ -89,7 +89,7 @@ static class: public keel::Module {
} const mod; } const mod;
keel::Module const*keelModule() noexcept { keel::Module const *keelModule() noexcept {
return &mod; return &mod;
} }

View File

@@ -61,7 +61,7 @@ ox::Error convertPaletteV4ToPaletteV5(
for (auto &s : src.pages) { for (auto &s : src.pages) {
ox::Vector<PaletteColorV2> colors; ox::Vector<PaletteColorV2> colors;
colors.reserve(s.colors.size()); colors.reserve(s.colors.size());
for (auto const&c : s.colors) { for (auto const &c : s.colors) {
colors.emplace_back(c.r, c.g, c.b, c.a); colors.emplace_back(c.r, c.g, c.b, c.a);
} }
dst.pages.emplace_back(PalettePageV2{ dst.pages.emplace_back(PalettePageV2{

View File

@@ -8,7 +8,6 @@
#include <keel/typeconv.hpp> #include <keel/typeconv.hpp>
#include <nostalgia/gfx/context.hpp>
#include <nostalgia/gfx/palette.hpp> #include <nostalgia/gfx/palette.hpp>
#include <nostalgia/gfx/tilesheet.hpp> #include <nostalgia/gfx/tilesheet.hpp>

View File

@@ -20,7 +20,7 @@ class PaletteEditorImGui: public studio::Editor {
bool m_show = false; bool m_show = false;
public: public:
ox::Signal<ox::Error(ox::StringView name)> inputSubmitted; ox::Signal<ox::Error(ox::StringView name)> inputSubmitted;
constexpr void show(ox::StringView const&name) noexcept { constexpr void show(ox::StringView const &name) noexcept {
m_show = true; m_show = true;
m_name = name; m_name = name;
} }

View File

@@ -30,7 +30,7 @@ static class: public studio::Module {
} }
} const mod; } const mod;
const studio::Module *studioModule() noexcept { studio::Module const *studioModule() noexcept {
return &mod; return &mod;
} }

View File

@@ -60,7 +60,7 @@ int AddSubSheetCommand::commandId() const noexcept {
return static_cast<int>(CommandId::AddSubSheet); return static_cast<int>(CommandId::AddSubSheet);
} }
TileSheet::SubSheetIdx const&AddSubSheetCommand::subsheetIdx() const noexcept { TileSheet::SubSheetIdx const &AddSubSheetCommand::subsheetIdx() const noexcept {
return m_parentIdx; return m_parentIdx;
} }

View File

@@ -25,7 +25,7 @@ class AddSubSheetCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };

View File

@@ -37,7 +37,7 @@ constexpr bool operator==(int i, CommandId c) noexcept {
class TileSheetCommand: public studio::UndoCommand { class TileSheetCommand: public studio::UndoCommand {
public: public:
[[nodiscard]] [[nodiscard]]
virtual TileSheet::SubSheetIdx const&subsheetIdx() const noexcept = 0; virtual TileSheet::SubSheetIdx const &subsheetIdx() const noexcept = 0;
}; };
} }

View File

@@ -48,7 +48,7 @@ CutPasteCommand::CutPasteCommand(
ox::Error CutPasteCommand::redo() noexcept { ox::Error CutPasteCommand::redo() noexcept {
auto &subsheet = getSubSheet(m_img, m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto &c : m_changes) { for (auto const &c : m_changes) {
subsheet.pixels[c.idx] = static_cast<uint8_t>(c.newPalIdx); subsheet.pixels[c.idx] = static_cast<uint8_t>(c.newPalIdx);
} }
return {}; return {};
@@ -56,7 +56,7 @@ ox::Error CutPasteCommand::redo() noexcept {
ox::Error CutPasteCommand::undo() noexcept { ox::Error CutPasteCommand::undo() noexcept {
auto &subsheet = getSubSheet(m_img, m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto &c : m_changes) { for (auto const &c : m_changes) {
subsheet.pixels[c.idx] = static_cast<uint8_t>(c.oldPalIdx); subsheet.pixels[c.idx] = static_cast<uint8_t>(c.oldPalIdx);
} }
return {}; return {};

View File

@@ -30,10 +30,10 @@ class TileSheetClipboard: public turbine::ClipboardObject<TileSheetClipboard> {
ox::Vector<Pixel> m_pixels; ox::Vector<Pixel> m_pixels;
public: public:
void addPixel(ox::Point const&pt, uint16_t colorIdx) noexcept; void addPixel(ox::Point const &pt, uint16_t colorIdx) noexcept;
[[nodiscard]] [[nodiscard]]
ox::Vector<Pixel> const&pixels() const noexcept; ox::Vector<Pixel> const &pixels() const noexcept;
}; };
OX_MODEL_BEGIN(TileSheetClipboard::Pixel) OX_MODEL_BEGIN(TileSheetClipboard::Pixel)
@@ -67,9 +67,9 @@ class CutPasteCommand: public TileSheetCommand {
CommandId commandId, CommandId commandId,
TileSheet &img, TileSheet &img,
TileSheet::SubSheetIdx subSheetIdx, TileSheet::SubSheetIdx subSheetIdx,
ox::Point const&dstStart, ox::Point const &dstStart,
ox::Point dstEnd, ox::Point dstEnd,
TileSheetClipboard const&cb); TileSheetClipboard const &cb);
ox::Error redo() noexcept final; ox::Error redo() noexcept final;
@@ -79,7 +79,7 @@ class CutPasteCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };

View File

@@ -66,7 +66,7 @@ int DeleteTilesCommand::commandId() const noexcept {
return static_cast<int>(CommandId::DeleteTile); return static_cast<int>(CommandId::DeleteTile);
} }
TileSheet::SubSheetIdx const&DeleteTilesCommand::subsheetIdx() const noexcept { TileSheet::SubSheetIdx const &DeleteTilesCommand::subsheetIdx() const noexcept {
return m_idx; return m_idx;
} }

View File

@@ -31,7 +31,7 @@ class DeleteTilesCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };

View File

@@ -74,7 +74,7 @@ DrawCommand::DrawCommand(
DrawCommand::DrawCommand( DrawCommand::DrawCommand(
TileSheet &img, TileSheet &img,
TileSheet::SubSheetIdx subSheetIdx, TileSheet::SubSheetIdx subSheetIdx,
ox::SpanView<std::size_t> const&idxList, ox::SpanView<std::size_t> const &idxList,
int const palIdx) noexcept: int const palIdx) noexcept:
m_img(img), m_img(img),
m_subSheetIdx(std::move(subSheetIdx)), m_subSheetIdx(std::move(subSheetIdx)),
@@ -90,7 +90,7 @@ bool DrawCommand::append(std::size_t const idx) noexcept {
if (m_changes.back().value->idx != idx && getPixel(subsheet, idx) != m_palIdx) { if (m_changes.back().value->idx != idx && getPixel(subsheet, idx) != m_palIdx) {
// duplicate entries are bad // duplicate entries are bad
auto existing = find_if( auto existing = find_if(
m_changes.cbegin(), m_changes.cend(), [idx](auto const&c) { m_changes.cbegin(), m_changes.cend(), [idx](auto const &c) {
return c.idx == idx; return c.idx == idx;
}); });
if (existing == m_changes.cend()) { if (existing == m_changes.cend()) {
@@ -102,7 +102,7 @@ bool DrawCommand::append(std::size_t const idx) noexcept {
return false; return false;
} }
bool DrawCommand::append(ox::SpanView<std::size_t> const&idxList) noexcept { bool DrawCommand::append(ox::SpanView<std::size_t> const &idxList) noexcept {
auto out = false; auto out = false;
for (auto idx : idxList) { for (auto idx : idxList) {
out = append(idx) || out; out = append(idx) || out;
@@ -134,7 +134,7 @@ void DrawCommand::lineUpdate(ox::Point a, ox::Point b) noexcept {
ox::Error DrawCommand::redo() noexcept { ox::Error DrawCommand::redo() noexcept {
auto &subsheet = getSubSheet(m_img, m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (auto const&c : m_changes) { for (auto const &c : m_changes) {
subsheet.pixels[c.idx] = static_cast<uint8_t>(m_palIdx); subsheet.pixels[c.idx] = static_cast<uint8_t>(m_palIdx);
} }
return {}; return {};
@@ -142,7 +142,7 @@ ox::Error DrawCommand::redo() noexcept {
ox::Error DrawCommand::undo() noexcept { ox::Error DrawCommand::undo() noexcept {
auto &subsheet = getSubSheet(m_img, m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (auto const&c : m_changes) { for (auto const &c : m_changes) {
subsheet.pixels[c.idx] = static_cast<uint8_t>(c.oldPalIdx); subsheet.pixels[c.idx] = static_cast<uint8_t>(c.oldPalIdx);
} }
return {}; return {};
@@ -152,7 +152,7 @@ int DrawCommand::commandId() const noexcept {
return static_cast<int>(CommandId::Draw); return static_cast<int>(CommandId::Draw);
} }
TileSheet::SubSheetIdx const&DrawCommand::subsheetIdx() const noexcept { TileSheet::SubSheetIdx const &DrawCommand::subsheetIdx() const noexcept {
return m_subSheetIdx; return m_subSheetIdx;
} }

View File

@@ -33,12 +33,12 @@ class DrawCommand: public TileSheetCommand {
DrawCommand( DrawCommand(
TileSheet &img, TileSheet &img,
TileSheet::SubSheetIdx subSheetIdx, TileSheet::SubSheetIdx subSheetIdx,
ox::SpanView<std::size_t> const&idxList, ox::SpanView<std::size_t> const &idxList,
int palIdx) noexcept; int palIdx) noexcept;
bool append(std::size_t idx) noexcept; bool append(std::size_t idx) noexcept;
bool append(ox::SpanView<std::size_t> const&idxList) noexcept; bool append(ox::SpanView<std::size_t> const &idxList) noexcept;
void lineUpdate(ox::Point a, ox::Point b) noexcept; void lineUpdate(ox::Point a, ox::Point b) noexcept;
@@ -50,7 +50,7 @@ class DrawCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
void finish() noexcept; void finish() noexcept;

View File

@@ -30,7 +30,7 @@ class FlipXCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };
@@ -56,7 +56,7 @@ class FlipYCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };

View File

@@ -62,7 +62,7 @@ int InsertTilesCommand::commandId() const noexcept {
return static_cast<int>(CommandId::InsertTile); return static_cast<int>(CommandId::InsertTile);
} }
TileSheet::SubSheetIdx const&InsertTilesCommand::subsheetIdx() const noexcept { TileSheet::SubSheetIdx const &InsertTilesCommand::subsheetIdx() const noexcept {
return m_idx; return m_idx;
} }

View File

@@ -31,7 +31,7 @@ class InsertTilesCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };

View File

@@ -33,7 +33,7 @@ int MoveSubSheetCommand::commandId() const noexcept {
return static_cast<int>(CommandId::MoveSubSheet); return static_cast<int>(CommandId::MoveSubSheet);
} }
TileSheet::SubSheetIdx const&MoveSubSheetCommand::subsheetIdx() const noexcept { TileSheet::SubSheetIdx const &MoveSubSheetCommand::subsheetIdx() const noexcept {
return *m_active; return *m_active;
} }

View File

@@ -26,7 +26,7 @@ class MoveSubSheetCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };

View File

@@ -30,7 +30,7 @@ int PaletteChangeCommand::commandId() const noexcept {
return static_cast<int>(CommandId::PaletteChange); return static_cast<int>(CommandId::PaletteChange);
} }
TileSheet::SubSheetIdx const&PaletteChangeCommand::subsheetIdx() const noexcept { TileSheet::SubSheetIdx const &PaletteChangeCommand::subsheetIdx() const noexcept {
return m_idx; return m_idx;
} }

View File

@@ -29,7 +29,7 @@ class PaletteChangeCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };

View File

@@ -31,7 +31,7 @@ int RmSubSheetCommand::commandId() const noexcept {
return static_cast<int>(CommandId::RmSubSheet); return static_cast<int>(CommandId::RmSubSheet);
} }
TileSheet::SubSheetIdx const&RmSubSheetCommand::subsheetIdx() const noexcept { TileSheet::SubSheetIdx const &RmSubSheetCommand::subsheetIdx() const noexcept {
return m_idx; return m_idx;
} }

View File

@@ -26,7 +26,7 @@ class RmSubSheetCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };

View File

@@ -119,7 +119,7 @@ int RotateCommand::commandId() const noexcept {
return static_cast<int>(CommandId::Rotate); return static_cast<int>(CommandId::Rotate);
} }
TileSheet::SubSheetIdx const&RotateCommand::subsheetIdx() const noexcept { TileSheet::SubSheetIdx const &RotateCommand::subsheetIdx() const noexcept {
return m_idx; return m_idx;
} }

View File

@@ -40,7 +40,7 @@ class RotateCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };

View File

@@ -33,7 +33,7 @@ int UpdateSubSheetCommand::commandId() const noexcept {
return static_cast<int>(CommandId::UpdateSubSheet); return static_cast<int>(CommandId::UpdateSubSheet);
} }
TileSheet::SubSheetIdx const&UpdateSubSheetCommand::subsheetIdx() const noexcept { TileSheet::SubSheetIdx const &UpdateSubSheetCommand::subsheetIdx() const noexcept {
return m_idx; return m_idx;
} }

View File

@@ -30,7 +30,7 @@ class UpdateSubSheetCommand: public TileSheetCommand {
int commandId() const noexcept final; int commandId() const noexcept final;
[[nodiscard]] [[nodiscard]]
TileSheet::SubSheetIdx const&subsheetIdx() const noexcept override; TileSheet::SubSheetIdx const &subsheetIdx() const noexcept override;
}; };

View File

@@ -9,6 +9,8 @@
#include <keel/media.hpp> #include <keel/media.hpp>
#include <studio/studio.hpp> #include <studio/studio.hpp>
#include <nostalgia/gfx/studio.hpp>
#include "tilesheeteditor-imgui.hpp" #include "tilesheeteditor-imgui.hpp"
namespace nostalgia::gfx { namespace nostalgia::gfx {
@@ -576,10 +578,10 @@ void TileSheetEditorImGui::drawPaletteMenu() noexcept {
m_view.setPalIdx(i); m_view.setPalIdx(i);
} }
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) { if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
studio::navigateTo( navigateToPalette(
m_sctx, m_sctx,
m_model.palPath(), m_model.palPath(),
ox::sfmt("{};{}", i, m_model.palettePage())); i, m_model.palettePage());
} }
// Column: color RGB // Column: color RGB
ImGui::TableNextColumn(); ImGui::TableNextColumn();

View File

@@ -66,7 +66,7 @@ void TileSheetEditorModel::cut() {
} }
TileSheetClipboard blankCb; TileSheetClipboard blankCb;
auto cb = ox::make_unique<TileSheetClipboard>(); auto cb = ox::make_unique<TileSheetClipboard>();
auto const&s = activeSubSheet(); auto const &s = activeSubSheet();
if (iterateSelectionRows(*m_selection, [&](int const x, int const y) { if (iterateSelectionRows(*m_selection, [&](int const x, int const y) {
auto pt = ox::Point{x, y}; auto pt = ox::Point{x, y};
auto const idx = gfx::idx(s, pt); auto const idx = gfx::idx(s, pt);
@@ -97,7 +97,7 @@ void TileSheetEditorModel::copy() {
auto cb = ox::make_unique<TileSheetClipboard>(); auto cb = ox::make_unique<TileSheetClipboard>();
if (iterateSelectionRows(*m_selection, [&](int const x, int const y) { if (iterateSelectionRows(*m_selection, [&](int const x, int const y) {
auto pt = ox::Point{x, y}; auto pt = ox::Point{x, y};
auto const&s = activeSubSheet(); auto const &s = activeSubSheet();
auto const idx = gfx::idx(s, pt); auto const idx = gfx::idx(s, pt);
if (idx >= s.pixels.size()) { if (idx >= s.pixels.size()) {
return ox::Error{1, "invalid idx"}; return ox::Error{1, "invalid idx"};
@@ -122,7 +122,7 @@ void TileSheetEditorModel::paste() {
oxErrf("Could not read clipboard: {}", toStr(err)); oxErrf("Could not read clipboard: {}", toStr(err));
return; return;
} }
auto const&s = activeSubSheet(); auto const &s = activeSubSheet();
auto const pt1 = m_selection->a; auto const pt1 = m_selection->a;
auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight}; auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight};
if (auto cmd = ox::make_unique_catch<CutPasteCommand>( if (auto cmd = ox::make_unique_catch<CutPasteCommand>(
@@ -235,7 +235,7 @@ void TileSheetEditorModel::setActiveSubsheet(TileSheet::SubSheetIdx const &idx)
} }
void TileSheetEditorModel::fill(ox::Point const &pt, uint8_t const palIdx) noexcept { void TileSheetEditorModel::fill(ox::Point const &pt, uint8_t const palIdx) noexcept {
auto const&activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx); auto const &activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx);
// build idx list // build idx list
if (pt.x >= activeSubSheet.columns * TileWidth || pt.y >= activeSubSheet.rows * TileHeight) { if (pt.x >= activeSubSheet.columns * TileWidth || pt.y >= activeSubSheet.rows * TileHeight) {
return; return;
@@ -303,7 +303,7 @@ void TileSheetEditorModel::completeSelection() noexcept {
m_selTracker.finishSelection(); m_selTracker.finishSelection();
m_selection.emplace(m_selTracker.selection()); m_selection.emplace(m_selTracker.selection());
auto&pt = m_selection->b; auto&pt = m_selection->b;
auto const&s = activeSubSheet(); auto const &s = activeSubSheet();
pt.x = ox::min(s.columns * TileWidth - 1, pt.x); pt.x = ox::min(s.columns * TileWidth - 1, pt.x);
pt.y = ox::min(s.rows * TileHeight - 1, pt.y); pt.y = ox::min(s.rows * TileHeight - 1, pt.y);
} }
@@ -356,7 +356,7 @@ ox::Error TileSheetEditorModel::saveFile() noexcept {
} }
bool TileSheetEditorModel::pixelSelected(std::size_t const idx) const noexcept { bool TileSheetEditorModel::pixelSelected(std::size_t const idx) const noexcept {
auto const&s = activeSubSheet(); auto const &s = activeSubSheet();
auto const pt = idxToPt(static_cast<int>(idx), s.columns); auto const pt = idxToPt(static_cast<int>(idx), s.columns);
return m_selection && m_selection->contains(pt); return m_selection && m_selection->contains(pt);
} }
@@ -398,7 +398,7 @@ ox::Error TileSheetEditorModel::moveSubSheet(TileSheet::SubSheetIdx src, TileShe
} }
void TileSheetEditorModel::getFillPixels( void TileSheetEditorModel::getFillPixels(
TileSheet::SubSheet const&activeSubSheet, TileSheet::SubSheet const &activeSubSheet,
ox::Span<bool> const pixels, ox::Span<bool> const pixels,
ox::Point const &pt, ox::Point const &pt,
uint8_t const oldColor) noexcept { uint8_t const oldColor) noexcept {
@@ -448,7 +448,7 @@ ox::Error TileSheetEditorModel::pushCommand(ox::UPtr<studio::UndoCommand> &&cmd)
return {}; return {};
} }
ox::Error TileSheetEditorModel::handleFileRename(ox::StringViewCR, ox::StringViewCR newPath, ox::UUID const&id) noexcept { ox::Error TileSheetEditorModel::handleFileRename(ox::StringViewCR, ox::StringViewCR newPath, ox::UUID const &id) noexcept {
if ((beginsWith(m_img.defaultPalette, "uuid://") && if ((beginsWith(m_img.defaultPalette, "uuid://") &&
substr(m_img.defaultPalette, 7) == id.toString()) || substr(m_img.defaultPalette, 7) == id.toString()) ||
m_img.defaultPalette == newPath) { m_img.defaultPalette == newPath) {

View File

@@ -29,8 +29,8 @@ void TileSheetEditorView::draw() noexcept {
m_pixelGridDrawer.draw(updated(), m_scrollOffset); m_pixelGridDrawer.draw(updated(), m_scrollOffset);
} }
void TileSheetEditorView::scrollV(ox::Vec2 const&paneSz, float wheel, bool zoomMod) noexcept { void TileSheetEditorView::scrollV(ox::Vec2 const &paneSz, float wheel, bool zoomMod) noexcept {
auto const&s = m_model.activeSubSheet(); auto const &s = m_model.activeSubSheet();
auto const pixelSize = m_pixelsDrawer.pixelSize(paneSz); auto const pixelSize = m_pixelsDrawer.pixelSize(paneSz);
ImVec2 const sheetSize(pixelSize.x * static_cast<float>(s.columns) * TileWidth, ImVec2 const sheetSize(pixelSize.x * static_cast<float>(s.columns) * TileWidth,
pixelSize.y * static_cast<float>(s.rows) * TileHeight); pixelSize.y * static_cast<float>(s.rows) * TileHeight);
@@ -47,8 +47,8 @@ void TileSheetEditorView::scrollV(ox::Vec2 const&paneSz, float wheel, bool zoomM
m_scrollOffset.y = ox::clamp(m_scrollOffset.y, 0.f, sheetSize.y / 2); m_scrollOffset.y = ox::clamp(m_scrollOffset.y, 0.f, sheetSize.y / 2);
} }
void TileSheetEditorView::scrollH(ox::Vec2 const&paneSz, float wheelh) noexcept { void TileSheetEditorView::scrollH(ox::Vec2 const &paneSz, float wheelh) noexcept {
auto const&s = m_model.activeSubSheet(); auto const &s = m_model.activeSubSheet();
auto const pixelSize = m_pixelsDrawer.pixelSize(paneSz); auto const pixelSize = m_pixelsDrawer.pixelSize(paneSz);
ImVec2 const sheetSize(pixelSize.x * static_cast<float>(s.columns) * TileWidth, ImVec2 const sheetSize(pixelSize.x * static_cast<float>(s.columns) * TileWidth,
pixelSize.y * static_cast<float>(s.rows) * TileHeight); pixelSize.y * static_cast<float>(s.rows) * TileHeight);
@@ -56,43 +56,43 @@ void TileSheetEditorView::scrollH(ox::Vec2 const&paneSz, float wheelh) noexcept
m_scrollOffset.x = ox::clamp(m_scrollOffset.x, -(sheetSize.x / 2), 0.f); m_scrollOffset.x = ox::clamp(m_scrollOffset.x, -(sheetSize.x / 2), 0.f);
} }
void TileSheetEditorView::insertTile(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept { void TileSheetEditorView::insertTile(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept {
auto pt = clickPoint(paneSize, clickPos); auto pt = clickPoint(paneSize, clickPos);
auto const&s = m_model.activeSubSheet(); auto const &s = m_model.activeSubSheet();
pt.x = ox::min(pt.x, s.columns * TileWidth - 1); pt.x = ox::min(pt.x, s.columns * TileWidth - 1);
pt.y = ox::min(pt.y, s.rows * TileHeight - 1); pt.y = ox::min(pt.y, s.rows * TileHeight - 1);
auto const tileIdx = ptToIdx(pt, s.columns) / PixelsPerTile; auto const tileIdx = ptToIdx(pt, s.columns) / PixelsPerTile;
m_model.insertTiles(m_model.activeSubSheetIdx(), tileIdx, 1); m_model.insertTiles(m_model.activeSubSheetIdx(), tileIdx, 1);
} }
void TileSheetEditorView::deleteTile(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept { void TileSheetEditorView::deleteTile(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept {
auto const pt = clickPoint(paneSize, clickPos); auto const pt = clickPoint(paneSize, clickPos);
auto const&s = m_model.activeSubSheet(); auto const &s = m_model.activeSubSheet();
auto const tileIdx = ptToIdx(pt, s.columns) / PixelsPerTile; auto const tileIdx = ptToIdx(pt, s.columns) / PixelsPerTile;
m_model.deleteTiles(m_model.activeSubSheetIdx(), tileIdx, 1); m_model.deleteTiles(m_model.activeSubSheetIdx(), tileIdx, 1);
} }
void TileSheetEditorView::clickDraw(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept { void TileSheetEditorView::clickDraw(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept {
auto const pt = clickPoint(paneSize, clickPos); auto const pt = clickPoint(paneSize, clickPos);
m_model.drawCommand(pt, m_palIdx); m_model.drawCommand(pt, m_palIdx);
} }
void TileSheetEditorView::clickLine(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept { void TileSheetEditorView::clickLine(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept {
auto const pt = clickPoint(paneSize, clickPos); auto const pt = clickPoint(paneSize, clickPos);
m_model.drawLineCommand(pt, m_palIdx); m_model.drawLineCommand(pt, m_palIdx);
} }
void TileSheetEditorView::clickSelect(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept { void TileSheetEditorView::clickSelect(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept {
auto const pt = clickPoint(paneSize, clickPos); auto const pt = clickPoint(paneSize, clickPos);
m_model.select(pt); m_model.select(pt);
} }
void TileSheetEditorView::clickFill(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept { void TileSheetEditorView::clickFill(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept {
auto const pt = clickPoint(paneSize, clickPos); auto const pt = clickPoint(paneSize, clickPos);
m_model.fill(pt, static_cast<uint8_t>(m_palIdx)); m_model.fill(pt, static_cast<uint8_t>(m_palIdx));
} }
void TileSheetEditorView::releaseMouseButton(TileSheetTool tool) noexcept { void TileSheetEditorView::releaseMouseButton(TileSheetTool const tool) noexcept {
switch (tool) { switch (tool) {
case TileSheetTool::Draw: case TileSheetTool::Draw:
case TileSheetTool::Fill: case TileSheetTool::Fill:
@@ -107,7 +107,7 @@ void TileSheetEditorView::releaseMouseButton(TileSheetTool tool) noexcept {
} }
} }
void TileSheetEditorView::resizeView(ox::Vec2 const&sz) noexcept { void TileSheetEditorView::resizeView(ox::Vec2 const &sz) noexcept {
m_viewSize = sz; m_viewSize = sz;
initView(); initView();
} }
@@ -133,9 +133,9 @@ void TileSheetEditorView::initView() noexcept {
m_pixelGridDrawer.initBufferSet(m_viewSize, m_model.activeSubSheet()); m_pixelGridDrawer.initBufferSet(m_viewSize, m_model.activeSubSheet());
} }
ox::Point TileSheetEditorView::clickPoint(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) const noexcept { ox::Point TileSheetEditorView::clickPoint(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) const noexcept {
auto [x, y] = clickPos; auto [x, y] = clickPos;
const auto pixDrawSz = m_pixelsDrawer.pixelSize(paneSize); auto const pixDrawSz = m_pixelsDrawer.pixelSize(paneSize);
x /= paneSize.x; x /= paneSize.x;
y /= paneSize.y; y /= paneSize.y;
x += -m_scrollOffset.x / 2; x += -m_scrollOffset.x / 2;

View File

@@ -62,28 +62,28 @@ class TileSheetEditorView: public ox::SignalHandler {
void draw() noexcept; void draw() noexcept;
void insertTile(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept; void insertTile(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept;
void deleteTile(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept; void deleteTile(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept;
void clickDraw(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept; void clickDraw(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept;
void clickLine(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept; void clickLine(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept;
void clickSelect(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept; void clickSelect(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept;
void clickFill(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept; void clickFill(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) noexcept;
void releaseMouseButton(TileSheetTool tool) noexcept; void releaseMouseButton(TileSheetTool tool) noexcept;
void scrollV(ox::Vec2 const&paneSz, float wheel, bool zoomMod) noexcept; void scrollV(ox::Vec2 const &paneSz, float wheel, bool zoomMod) noexcept;
void scrollH(ox::Vec2 const&paneSz, float wheel) noexcept; void scrollH(ox::Vec2 const &paneSz, float wheel) noexcept;
void resizeView(ox::Vec2 const&sz) noexcept; void resizeView(ox::Vec2 const &sz) noexcept;
[[nodiscard]] [[nodiscard]]
constexpr TileSheet const&img() const noexcept; constexpr TileSheet const &img() const noexcept;
[[nodiscard]] [[nodiscard]]
constexpr TileSheet &img() noexcept; constexpr TileSheet &img() noexcept;
@@ -117,13 +117,13 @@ class TileSheetEditorView: public ox::SignalHandler {
private: private:
void initView() noexcept; void initView() noexcept;
ox::Point clickPoint(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) const noexcept; ox::Point clickPoint(ox::Vec2 const &paneSize, ox::Vec2 const &clickPos) const noexcept;
ox::Error setActiveSubsheet(TileSheet::SubSheetIdx const&idx) noexcept; ox::Error setActiveSubsheet(TileSheet::SubSheetIdx const &idx) noexcept;
}; };
constexpr TileSheet const&TileSheetEditorView::img() const noexcept { constexpr TileSheet const &TileSheetEditorView::img() const noexcept {
return m_model.img(); return m_model.img();
} }

View File

@@ -23,7 +23,7 @@ ox::Error TileSheetGrid::buildShader() noexcept {
pixelLineVshad, pixelLineFshad, pixelLineGshad).moveTo(m_shader); pixelLineVshad, pixelLineFshad, pixelLineGshad).moveTo(m_shader);
} }
void TileSheetGrid::draw(bool const update, ox::Vec2 const&scroll) noexcept { void TileSheetGrid::draw(bool const update, ox::Vec2 const &scroll) noexcept {
// the lines just show up bigger on Windows for some reason // the lines just show up bigger on Windows for some reason
if constexpr(ox::defines::OS == ox::OS::Windows) { if constexpr(ox::defines::OS == ox::OS::Windows) {
glLineWidth(3 * m_pixelSizeMod * 0.25f); glLineWidth(3 * m_pixelSizeMod * 0.25f);
@@ -42,7 +42,7 @@ void TileSheetGrid::draw(bool const update, ox::Vec2 const&scroll) noexcept {
glUseProgram(0); glUseProgram(0);
} }
void TileSheetGrid::initBufferSet(ox::Vec2 const&paneSize, TileSheet::SubSheet const&subsheet) noexcept { void TileSheetGrid::initBufferSet(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept {
// vao // vao
m_bufferSet.vao = glutils::generateVertexArrayObject(); m_bufferSet.vao = glutils::generateVertexArrayObject();
glBindVertexArray(m_bufferSet.vao); glBindVertexArray(m_bufferSet.vao);
@@ -65,7 +65,7 @@ void TileSheetGrid::initBufferSet(ox::Vec2 const&paneSize, TileSheet::SubSheet c
std::bit_cast<void*>(uintptr_t{4 * sizeof(float)})); std::bit_cast<void*>(uintptr_t{4 * sizeof(float)}));
} }
void TileSheetGrid::update(ox::Vec2 const&paneSize, TileSheet::SubSheet const&subsheet) noexcept { void TileSheetGrid::update(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept {
glBindVertexArray(m_bufferSet.vao); glBindVertexArray(m_bufferSet.vao);
setBufferObjects(paneSize, subsheet); setBufferObjects(paneSize, subsheet);
glutils::sendVbo(m_bufferSet); glutils::sendVbo(m_bufferSet);
@@ -77,7 +77,7 @@ void TileSheetGrid::setBufferObject(
ox::Point const pt2, ox::Point const pt2,
Color32 const c, Color32 const c,
ox::Span<float> const vbo, ox::Span<float> const vbo,
ox::Vec2 const&pixSize) noexcept { ox::Vec2 const &pixSize) noexcept {
auto const x1 = static_cast<float>(pt1.x) * pixSize.x - 1.f; auto const x1 = static_cast<float>(pt1.x) * pixSize.x - 1.f;
auto const y1 = 1.f - static_cast<float>(pt1.y) * pixSize.y; auto const y1 = 1.f - static_cast<float>(pt1.y) * pixSize.y;
auto const x2 = static_cast<float>(pt2.x) * pixSize.x - 1.f; auto const x2 = static_cast<float>(pt2.x) * pixSize.x - 1.f;
@@ -87,7 +87,7 @@ void TileSheetGrid::setBufferObject(
ox::spancpy(vbo, ox::SpanView<float>{vertices}); ox::spancpy(vbo, ox::SpanView<float>{vertices});
} }
void TileSheetGrid::setBufferObjects(ox::Vec2 const&paneSize, TileSheet::SubSheet const&subsheet) noexcept { void TileSheetGrid::setBufferObjects(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept {
if (subsheet.columns < 1 || subsheet.rows < 1) { if (subsheet.columns < 1 || subsheet.rows < 1) {
m_bufferSet.elements.clear(); m_bufferSet.elements.clear();
m_bufferSet.vertices.clear(); m_bufferSet.vertices.clear();
@@ -129,7 +129,7 @@ void TileSheetGrid::setBufferObjects(ox::Vec2 const&paneSize, TileSheet::SubShee
} }
} }
ox::Vec2 TileSheetGrid::pixelSize(ox::Vec2 const&paneSize) const noexcept { ox::Vec2 TileSheetGrid::pixelSize(ox::Vec2 const &paneSize) const noexcept {
auto const [sw, sh] = paneSize; auto const [sw, sh] = paneSize;
constexpr float ymod = 0.35f / 10.0f; constexpr float ymod = 0.35f / 10.0f;
auto const xmod = ymod * sh / sw; auto const xmod = ymod * sh / sw;

View File

@@ -66,19 +66,20 @@ class TileSheetGrid {
ox::Error buildShader() noexcept; ox::Error buildShader() noexcept;
void draw(bool update, ox::Vec2 const&scroll) noexcept; void draw(bool update, ox::Vec2 const &scroll) noexcept;
void initBufferSet(ox::Vec2 const&paneSize, TileSheet::SubSheet const&subsheet) noexcept; void initBufferSet(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept;
void update(ox::Vec2 const&paneSize, TileSheet::SubSheet const&subsheet) noexcept; void update(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept;
private: private:
static void setBufferObject(ox::Point pt1, ox::Point pt2, Color32 c, ox::Span<float> vbo, ox::Vec2 const&pixSize) noexcept; static void setBufferObject(
ox::Point pt1, ox::Point pt2, Color32 c, ox::Span<float> vbo, ox::Vec2 const &pixSize) noexcept;
void setBufferObjects(ox::Vec2 const&paneSize, TileSheet::SubSheet const&subsheet) noexcept; void setBufferObjects(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept;
[[nodiscard]] [[nodiscard]]
ox::Vec2 pixelSize(ox::Vec2 const&paneSize) const noexcept; ox::Vec2 pixelSize(ox::Vec2 const &paneSize) const noexcept;
}; };

View File

@@ -49,7 +49,7 @@ ox::Error TileSheetPixels::buildShader() noexcept {
return glutils::buildShaderProgram(s_programSrc).moveTo(m_shader); return glutils::buildShaderProgram(s_programSrc).moveTo(m_shader);
} }
void TileSheetPixels::draw(bool const update, ox::Vec2 const&scroll) noexcept { void TileSheetPixels::draw(bool const update, ox::Vec2 const &scroll) noexcept {
glUseProgram(m_shader); glUseProgram(m_shader);
glBindVertexArray(m_bufferSet.vao); glBindVertexArray(m_bufferSet.vao);
if (update) { if (update) {
@@ -62,7 +62,7 @@ void TileSheetPixels::draw(bool const update, ox::Vec2 const&scroll) noexcept {
glUseProgram(0); glUseProgram(0);
} }
void TileSheetPixels::initBufferSet(ox::Vec2 const&paneSize) noexcept { void TileSheetPixels::initBufferSet(ox::Vec2 const &paneSize) noexcept {
m_bufferSet.vao = glutils::generateVertexArrayObject(); m_bufferSet.vao = glutils::generateVertexArrayObject();
m_bufferSet.vbo = glutils::generateBuffer(); m_bufferSet.vbo = glutils::generateBuffer();
m_bufferSet.ebo = glutils::generateBuffer(); m_bufferSet.ebo = glutils::generateBuffer();
@@ -70,14 +70,14 @@ void TileSheetPixels::initBufferSet(ox::Vec2 const&paneSize) noexcept {
glutils::setupShaderParams(m_shader, s_programSrc.shaderParams); glutils::setupShaderParams(m_shader, s_programSrc.shaderParams);
} }
void TileSheetPixels::update(ox::Vec2 const&paneSize) noexcept { void TileSheetPixels::update(ox::Vec2 const &paneSize) noexcept {
glBindVertexArray(m_bufferSet.vao); glBindVertexArray(m_bufferSet.vao);
setBufferObjects(paneSize); setBufferObjects(paneSize);
glutils::sendVbo(m_bufferSet); glutils::sendVbo(m_bufferSet);
glutils::sendEbo(m_bufferSet); glutils::sendEbo(m_bufferSet);
} }
ox::Vec2 TileSheetPixels::pixelSize(ox::Vec2 const&paneSize) const noexcept { ox::Vec2 TileSheetPixels::pixelSize(ox::Vec2 const &paneSize) const noexcept {
auto const [sw, sh] = paneSize; auto const [sw, sh] = paneSize;
constexpr float ymod = 0.35f / 10.0f; constexpr float ymod = 0.35f / 10.0f;
auto const xmod = ymod * sh / sw; auto const xmod = ymod * sh / sw;
@@ -85,7 +85,7 @@ ox::Vec2 TileSheetPixels::pixelSize(ox::Vec2 const&paneSize) const noexcept {
} }
void TileSheetPixels::setPixelBufferObject( void TileSheetPixels::setPixelBufferObject(
ox::Vec2 const&paneSize, ox::Vec2 const &paneSize,
unsigned const vertexRow, unsigned const vertexRow,
float x, float y, float x, float y,
Color16 const color, Color16 const color,
@@ -112,15 +112,15 @@ void TileSheetPixels::setPixelBufferObject(
ox::spancpy(ebo, ox::SpanView<GLuint>{elms}); ox::spancpy(ebo, ox::SpanView<GLuint>{elms});
} }
void TileSheetPixels::setBufferObjects(ox::Vec2 const&paneSize) noexcept { void TileSheetPixels::setBufferObjects(ox::Vec2 const &paneSize) noexcept {
// set buffer lengths // set buffer lengths
auto const&subSheet = m_model.activeSubSheet(); auto const &subSheet = m_model.activeSubSheet();
if (subSheet.columns < 1 || subSheet.rows < 1) { if (subSheet.columns < 1 || subSheet.rows < 1) {
m_bufferSet.vertices.clear(); m_bufferSet.vertices.clear();
m_bufferSet.elements.clear(); m_bufferSet.elements.clear();
return; return;
} }
auto const&pal = m_model.pal(); auto const &pal = m_model.pal();
auto const width = subSheet.columns * TileWidth; auto const width = subSheet.columns * TileWidth;
auto const height = subSheet.rows * TileHeight; auto const height = subSheet.rows * TileHeight;
auto const pixels = static_cast<size_t>(width) * static_cast<size_t>(height); auto const pixels = static_cast<size_t>(width) * static_cast<size_t>(height);

View File

@@ -22,7 +22,7 @@ class TileSheetPixels {
float m_pixelSizeMod = 1; float m_pixelSizeMod = 1;
glutils::GLProgram m_shader; glutils::GLProgram m_shader;
glutils::BufferSet m_bufferSet; glutils::BufferSet m_bufferSet;
class TileSheetEditorModel const&m_model; class TileSheetEditorModel const &m_model;
public: public:
explicit TileSheetPixels(class TileSheetEditorModel &model) noexcept; explicit TileSheetPixels(class TileSheetEditorModel &model) noexcept;
@@ -31,18 +31,18 @@ class TileSheetPixels {
ox::Error buildShader() noexcept; ox::Error buildShader() noexcept;
void draw(bool update, ox::Vec2 const&scroll) noexcept; void draw(bool update, ox::Vec2 const &scroll) noexcept;
void initBufferSet(ox::Vec2 const&paneSize) noexcept; void initBufferSet(ox::Vec2 const &paneSize) noexcept;
void update(ox::Vec2 const&paneSize) noexcept; void update(ox::Vec2 const &paneSize) noexcept;
[[nodiscard]] [[nodiscard]]
ox::Vec2 pixelSize(ox::Vec2 const&paneSize) const noexcept; ox::Vec2 pixelSize(ox::Vec2 const &paneSize) const noexcept;
private: private:
void setPixelBufferObject( void setPixelBufferObject(
ox::Vec2 const&paneSize, ox::Vec2 const &paneSize,
unsigned vertexRow, unsigned vertexRow,
float x, float x,
float y, float y,
@@ -50,7 +50,7 @@ class TileSheetPixels {
ox::Span<float> vbo, ox::Span<float> vbo,
ox::Span<GLuint> ebo) const noexcept; ox::Span<GLuint> ebo) const noexcept;
void setBufferObjects(ox::Vec2 const&paneSize) noexcept; void setBufferObjects(ox::Vec2 const &paneSize) noexcept;
}; };

View File

@@ -12,16 +12,16 @@
namespace nostalgia::gfx { namespace nostalgia::gfx {
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 {
return ptToIdx(pt, ss.columns); return ptToIdx(pt, ss.columns);
} }
[[nodiscard]] [[nodiscard]]
static TileSheet::SubSheet const *getSubsheet(TileSheet::SubSheet const&ss, SubSheetId const id) noexcept { static TileSheet::SubSheet const *getSubsheet(TileSheet::SubSheet const &ss, SubSheetId const id) noexcept {
if (ss.id == id) { if (ss.id == id) {
return &ss; return &ss;
} }
for (auto const&child: ss.subsheets) { for (auto const &child: ss.subsheets) {
if (auto out = getSubsheet(child, id)) { if (auto out = getSubsheet(child, id)) {
return out; return out;
} }
@@ -30,31 +30,31 @@ static TileSheet::SubSheet const *getSubsheet(TileSheet::SubSheet const&ss, SubS
} }
[[nodiscard]] [[nodiscard]]
static size_t getTileCnt(TileSheet::SubSheet const&ss) noexcept { static size_t getTileCnt(TileSheet::SubSheet const &ss) noexcept {
if (ss.subsheets.empty()) { if (ss.subsheets.empty()) {
return ss.pixels.size() / PixelsPerTile; return ss.pixels.size() / PixelsPerTile;
} else { } else {
size_t out{}; size_t out{};
for (auto const&child: ss.subsheets) { for (auto const &child: ss.subsheets) {
out += getTileCnt(child); out += getTileCnt(child);
} }
return out; return out;
} }
} }
size_t getTileCnt(TileSheet const&ts) noexcept { size_t getTileCnt(TileSheet const &ts) noexcept {
return getTileCnt(ts.subsheet); return getTileCnt(ts.subsheet);
} }
TileSheet::SubSheet const *getSubsheet(TileSheet const&ts, SubSheetId const id) noexcept { TileSheet::SubSheet const *getSubsheet(TileSheet const &ts, SubSheetId const id) noexcept {
return getSubsheet(ts.subsheet, id); return getSubsheet(ts.subsheet, id);
} }
static ox::Optional<size_t> getPixelIdx( static ox::Optional<size_t> getPixelIdx(
TileSheet::SubSheet const&ss, TileSheet::SubSheet const &ss,
SubSheetId const id, SubSheetId const id,
size_t &idx) noexcept { size_t &idx) noexcept {
for (auto const&child: ss.subsheets) { for (auto const &child: ss.subsheets) {
if (child.id == id) { if (child.id == id) {
return ox::Optional<size_t>(ox::in_place, idx); return ox::Optional<size_t>(ox::in_place, idx);
} }
@@ -66,17 +66,17 @@ static ox::Optional<size_t> getPixelIdx(
return ox::Optional<size_t>{}; return ox::Optional<size_t>{};
} }
ox::Optional<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{}; size_t idx{};
auto const out = getPixelIdx(ts.subsheet, id, idx); auto const out = getPixelIdx(ts.subsheet, id, idx);
return out ? ox::Optional<size_t>{ox::in_place, *out / PixelsPerTile} : out; return out ? ox::Optional<size_t>{ox::in_place, *out / PixelsPerTile} : out;
} }
uint8_t getPixel(TileSheet::SubSheet const&ss, std::size_t const idx) noexcept { uint8_t getPixel(TileSheet::SubSheet const &ss, std::size_t const idx) noexcept {
return ss.pixels[idx]; return ss.pixels[idx];
} }
uint8_t getPixel(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept { uint8_t getPixel(TileSheet::SubSheet const &ss, ox::Point const &pt) noexcept {
auto const idx = ptToIdx(pt, ss.columns); auto const idx = ptToIdx(pt, ss.columns);
return getPixel(ss, idx); return getPixel(ss, idx);
} }
@@ -84,14 +84,14 @@ uint8_t getPixel(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept {
static void setPixel( static void setPixel(
ox::Vector<uint8_t> &pixels, ox::Vector<uint8_t> &pixels,
int const columns, int const columns,
ox::Point const&pt, ox::Point const &pt,
uint8_t const palIdx) noexcept { uint8_t const palIdx) noexcept {
const auto idx = ptToIdx(pt, columns); auto const idx = ptToIdx(pt, columns);
pixels[idx] = palIdx; pixels[idx] = palIdx;
} }
void setPixel(TileSheet::SubSheet &ss, ox::Point const&pt, uint8_t const palIdx) noexcept { void setPixel(TileSheet::SubSheet &ss, ox::Point const &pt, uint8_t const palIdx) noexcept {
const auto idx = ptToIdx(pt, ss.columns); auto const idx = ptToIdx(pt, ss.columns);
ss.pixels[idx] = palIdx; ss.pixels[idx] = palIdx;
} }
@@ -129,11 +129,11 @@ void flipY(TileSheet::SubSheet &ss, ox::Point const &a, ox::Point const &b) noex
} }
} }
unsigned pixelCnt(TileSheet::SubSheet const&ss) noexcept { unsigned pixelCnt(TileSheet::SubSheet const &ss) noexcept {
return static_cast<unsigned>(ss.pixels.size()); return static_cast<unsigned>(ss.pixels.size());
} }
ox::Error resizeSubsheet(TileSheet::SubSheet &ss, ox::Size const&sz) noexcept { ox::Error resizeSubsheet(TileSheet::SubSheet &ss, ox::Size const &sz) noexcept {
ox::Vector<uint8_t> out; ox::Vector<uint8_t> out;
OX_RETURN_ERROR(setPixelCount(out, static_cast<size_t>(sz.width * sz.height) * PixelsPerTile)); OX_RETURN_ERROR(setPixelCount(out, static_cast<size_t>(sz.width * sz.height) * PixelsPerTile));
auto const w = ox::min<int32_t>(ss.columns, sz.width) * TileWidth; auto const w = ox::min<int32_t>(ss.columns, sz.width) * TileWidth;
@@ -150,12 +150,12 @@ ox::Error resizeSubsheet(TileSheet::SubSheet &ss, ox::Size const&sz) noexcept {
return {}; return {};
} }
ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const&ss, SubSheetId const pId) noexcept { ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const &ss, SubSheetId const pId) noexcept {
if (ss.id == pId) { if (ss.id == pId) {
return ox::StringView(ss.name); return ox::StringView(ss.name);
} }
for (const auto &sub : ss.subsheets) { for (auto const &sub : ss.subsheets) {
const auto [name, err] = getNameFor(sub, pId); auto const [name, err] = getNameFor(sub, pId);
if (!err) { if (!err) {
return name; return name;
} }
@@ -167,7 +167,7 @@ ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const&ss, SubSheetId c
TileSheet::SubSheetIdx validateSubSheetIdx( TileSheet::SubSheetIdx validateSubSheetIdx(
TileSheet::SubSheetIdx &&pIdx, TileSheet::SubSheetIdx &&pIdx,
std::size_t const pIdxIt, std::size_t const pIdxIt,
TileSheet::SubSheet const&pSubsheet) noexcept { TileSheet::SubSheet const &pSubsheet) noexcept {
if (pIdxIt >= pIdx.size()) { if (pIdxIt >= pIdx.size()) {
return std::move(pIdx); return std::move(pIdx);
} }
@@ -185,7 +185,7 @@ TileSheet::SubSheetIdx validateSubSheetIdx(
return validateSubSheetIdx(std::move(pIdx), pIdxIt + 1, pSubsheet.subsheets[currentIdx]); return validateSubSheetIdx(std::move(pIdx), pIdxIt + 1, pSubsheet.subsheets[currentIdx]);
} }
TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const&ts, TileSheet::SubSheetIdx idx) noexcept { TileSheet::SubSheetIdx validateSubSheetIdx(TileSheet const &ts, TileSheet::SubSheetIdx idx) noexcept {
return validateSubSheetIdx(std::move(idx), 0, ts.subsheet); return validateSubSheetIdx(std::move(idx), 0, ts.subsheet);
} }
@@ -215,14 +215,14 @@ ox::Result<TileSheet::SubSheetIdx> getSubSheetIdx(TileSheet const &ts, SubSheetI
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-reference" #pragma GCC diagnostic ignored "-Wdangling-reference"
#endif #endif
static TileSheet::SubSheet const&getSubSheet( static TileSheet::SubSheet const &getSubSheet(
ox::SpanView<uint32_t> const &idx, ox::SpanView<uint32_t> const &idx,
std::size_t const idxIt, std::size_t const idxIt,
TileSheet::SubSheet const &pSubsheet) noexcept { TileSheet::SubSheet const &pSubsheet) noexcept {
if (idxIt == idx.size()) { if (idxIt == idx.size()) {
return pSubsheet; return pSubsheet;
} }
const auto currentIdx = idx[idxIt]; auto const currentIdx = idx[idxIt];
if (pSubsheet.subsheets.size() < currentIdx) { if (pSubsheet.subsheets.size() < currentIdx) {
return pSubsheet; return pSubsheet;
} }
@@ -246,7 +246,7 @@ TileSheet::SubSheet &getSubSheet(
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-reference" #pragma GCC diagnostic ignored "-Wdangling-reference"
#endif #endif
TileSheet::SubSheet const&getSubSheet(TileSheet const &ts, ox::SpanView<uint32_t> const &idx) noexcept { TileSheet::SubSheet const &getSubSheet(TileSheet const &ts, ox::SpanView<uint32_t> const &idx) noexcept {
return gfx::getSubSheet(idx, 0, ts.subsheet); return gfx::getSubSheet(idx, 0, ts.subsheet);
} }
@@ -257,7 +257,7 @@ TileSheet::SubSheet &getSubSheet(TileSheet &ts, ox::SpanView<uint32_t> const &id
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
ox::Error addSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept { ox::Error addSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const &idx) noexcept {
auto &parent = getSubSheet(ts, idx); auto &parent = getSubSheet(ts, idx);
if (parent.subsheets.size() < 2) { if (parent.subsheets.size() < 2) {
parent.subsheets.emplace_back(++ts.idIt, ox::sfmt("Subsheet {}", parent.subsheets.size()), 1, 1); parent.subsheets.emplace_back(++ts.idIt, ox::sfmt("Subsheet {}", parent.subsheets.size()), 1, 1);
@@ -268,7 +268,7 @@ ox::Error addSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept
return {}; return {};
} }
ox::Error insertSubSheet(TileSheet &ts, ox::SpanView<uint32_t> const&idx, TileSheet::SubSheet ss) noexcept { ox::Error insertSubSheet(TileSheet &ts, ox::SpanView<uint32_t> const &idx, TileSheet::SubSheet ss) noexcept {
if (idx.empty()) { if (idx.empty()) {
return ox::Error{1, "invalid insert idx"}; return ox::Error{1, "invalid insert idx"};
} }
@@ -283,7 +283,7 @@ ox::Error insertSubSheet(TileSheet &ts, ox::SpanView<uint32_t> const&idx, TileSh
ox::Error rmSubSheet( ox::Error rmSubSheet(
TileSheet &ts, TileSheet &ts,
TileSheet::SubSheetIdx const&idx, TileSheet::SubSheetIdx const &idx,
std::size_t const idxIt, std::size_t const idxIt,
TileSheet::SubSheet &pSubsheet) noexcept { TileSheet::SubSheet &pSubsheet) noexcept {
if (idxIt == idx.size() - 1) { if (idxIt == idx.size() - 1) {
@@ -292,21 +292,21 @@ ox::Error rmSubSheet(
return rmSubSheet(ts, idx, idxIt + 1, pSubsheet.subsheets[idx[idxIt]]); return rmSubSheet(ts, idx, idxIt + 1, pSubsheet.subsheets[idx[idxIt]]);
} }
ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept { ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const &idx) noexcept {
return rmSubSheet(ts, idx, 0, ts.subsheet); return rmSubSheet(ts, idx, 0, ts.subsheet);
} }
uint8_t getPixel( uint8_t getPixel(
TileSheet const&ts, TileSheet const &ts,
ox::Point const&pt, ox::Point const &pt,
TileSheet::SubSheetIdx const&subsheetIdx) noexcept { TileSheet::SubSheetIdx const &subsheetIdx) noexcept {
auto &s = getSubSheet(ts, subsheetIdx); auto &s = getSubSheet(ts, subsheetIdx);
auto const idx = ptToIdx(pt, s.columns); auto const idx = ptToIdx(pt, s.columns);
return getPixel(s, idx); return getPixel(s, idx);
} }
uint8_t getPixel4Bpp( uint8_t getPixel4Bpp(
CompactTileSheet const&ts, CompactTileSheet const &ts,
size_t const idx) noexcept { size_t const idx) noexcept {
oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp"); oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp");
if (idx & 1) { if (idx & 1) {
@@ -317,14 +317,14 @@ uint8_t getPixel4Bpp(
} }
uint8_t getPixel8Bpp( uint8_t getPixel8Bpp(
CompactTileSheet const&ts, CompactTileSheet const &ts,
size_t const idx) noexcept { size_t const idx) noexcept {
oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp"); oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp");
return ts.pixels[idx]; return ts.pixels[idx];
} }
ox::Pair<uint8_t> get2Pixels4Bpp( ox::Pair<uint8_t> get2Pixels4Bpp(
CompactTileSheet const&ts, CompactTileSheet const &ts,
size_t const idx) noexcept { size_t const idx) noexcept {
oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp"); oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp");
auto const out = ts.pixels[idx / 2]; auto const out = ts.pixels[idx / 2];
@@ -335,7 +335,7 @@ ox::Pair<uint8_t> get2Pixels4Bpp(
} }
ox::Pair<uint8_t> get2Pixels8Bpp( ox::Pair<uint8_t> get2Pixels8Bpp(
CompactTileSheet const&ts, CompactTileSheet const &ts,
size_t const idx) noexcept { size_t const idx) noexcept {
oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp"); oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp");
return { return {
@@ -345,8 +345,8 @@ ox::Pair<uint8_t> get2Pixels8Bpp(
} }
static ox::Result<SubSheetId> getIdFor( static ox::Result<SubSheetId> getIdFor(
TileSheet::SubSheet const&ss, TileSheet::SubSheet const &ss,
ox::SpanView<ox::StringView> const&pNamePath, ox::SpanView<ox::StringView> const &pNamePath,
std::size_t const pIt = 0) noexcept { std::size_t const pIt = 0) noexcept {
for (auto &sub : ss.subsheets) { for (auto &sub : ss.subsheets) {
if (sub.name == pNamePath[pIt]) { if (sub.name == pNamePath[pIt]) {
@@ -359,7 +359,7 @@ static ox::Result<SubSheetId> getIdFor(
return ox::Error(1, "SubSheet not found"); return ox::Error(1, "SubSheet not found");
} }
ox::Result<SubSheetId> getIdFor(TileSheet const&ts, ox::StringViewCR path) noexcept { ox::Result<SubSheetId> getIdFor(TileSheet const &ts, ox::StringViewCR path) noexcept {
return getIdFor(ts.subsheet, ox::split<8>(path, '.')); return getIdFor(ts.subsheet, ox::split<8>(path, '.'));
} }
@@ -367,8 +367,8 @@ ox::Result<SubSheetId> getIdFor(TileSheet const&ts, ox::StringViewCR path) noexc
* Gets the offset in tiles of the desired subsheet. * Gets the offset in tiles of the desired subsheet.
*/ */
static ox::Result<uint32_t> getTileOffset( static ox::Result<uint32_t> getTileOffset(
TileSheet::SubSheet const&ss, TileSheet::SubSheet const &ss,
ox::SpanView<ox::StringView> const&pNamePath, ox::SpanView<ox::StringView> const &pNamePath,
std::size_t const pIt = 0, std::size_t const pIt = 0,
uint32_t pCurrentTotal = 0) noexcept { uint32_t pCurrentTotal = 0) noexcept {
// pIt == pNamePath.size() - 1 && // pIt == pNamePath.size() - 1 &&
@@ -391,7 +391,7 @@ static ox::Result<uint32_t> getTileOffset(
return ox::Error(1, "SubSheet not found"); return ox::Error(1, "SubSheet not found");
} }
ox::Result<uint32_t> getTileOffset(TileSheet const&ts, ox::StringViewCR pNamePath) noexcept { ox::Result<uint32_t> getTileOffset(TileSheet const &ts, ox::StringViewCR pNamePath) noexcept {
return gfx::getTileOffset(ts.subsheet, ox::split<8>(pNamePath, '.')); return gfx::getTileOffset(ts.subsheet, ox::split<8>(pNamePath, '.'));
} }
@@ -399,7 +399,7 @@ ox::Result<ox::StringView> getNameFor(TileSheet &ts, SubSheetId const pId) noexc
return gfx::getNameFor(ts.subsheet, pId); return gfx::getNameFor(ts.subsheet, pId);
} }
ox::Result<ox::StringView> getNameFor(TileSheet const&ts, SubSheetId const pId) noexcept { ox::Result<ox::StringView> getNameFor(TileSheet const &ts, SubSheetId const pId) noexcept {
return gfx::getNameFor(ts.subsheet, pId); return gfx::getNameFor(ts.subsheet, pId);
} }
@@ -431,19 +431,19 @@ ox::Vector<uint8_t> pixels(TileSheet &ts) noexcept {
ox::Vector<uint32_t> resizeTileSheetData( ox::Vector<uint32_t> resizeTileSheetData(
ox::Vector<uint32_t> const&srcPixels, ox::Vector<uint32_t> const &srcPixels,
ox::Size const&srcSize, ox::Size const &srcSize,
int const scale) noexcept { int const scale) noexcept {
ox::Vector<uint32_t> dst; ox::Vector<uint32_t> dst;
auto dstWidth = srcSize.width * scale; auto dstWidth = srcSize.width * scale;
auto dstHeight = srcSize.height * scale; auto dstHeight = srcSize.height * scale;
const auto pixelCnt = dstWidth * dstHeight; auto const pixelCnt = dstWidth * dstHeight;
dst.resize(static_cast<std::size_t>(pixelCnt)); dst.resize(static_cast<std::size_t>(pixelCnt));
for (auto i = 0; i < pixelCnt; ++i) { for (auto i = 0; i < pixelCnt; ++i) {
const auto dstPt = idxToPt(i, 1, scale); auto const dstPt = idxToPt(i, 1, scale);
const auto srcPt = dstPt / ox::Point{scale, scale}; auto const srcPt = dstPt / ox::Point{scale, scale};
const auto srcIdx = ptToIdx(srcPt, 1); auto const srcIdx = ptToIdx(srcPt, 1);
const auto srcPixel = srcPixels[srcIdx]; auto const srcPixel = srcPixels[srcIdx];
dst[static_cast<std::size_t>(i)] = srcPixel; dst[static_cast<std::size_t>(i)] = srcPixel;
} }
return dst; return dst;

View File

@@ -24,7 +24,7 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
}, },
}; };
int main(int argc, const char **argv) { int main(int argc, char const **argv) {
int retval = -1; int retval = -1;
if (argc > 0) { if (argc > 0) {
auto const args = ox::Span{argv, static_cast<size_t>(argc)}; auto const args = ox::Span{argv, static_cast<size_t>(argc)};

View File

@@ -11,7 +11,7 @@
static std::map<ox::StringView, ox::Error(*)()> tests = { static std::map<ox::StringView, ox::Error(*)()> tests = {
}; };
int main(int argc, const char **argv) { int main(int argc, char const **argv) {
int retval = -1; int retval = -1;
if (argc > 0) { if (argc > 0) {
auto const args = ox::Span{argv, static_cast<size_t>(argc)}; auto const args = ox::Span{argv, static_cast<size_t>(argc)};

View File

@@ -15,7 +15,7 @@ target_link_libraries(
target_compile_definitions( target_compile_definitions(
NostalgiaStudio PUBLIC NostalgiaStudio PUBLIC
OLYMPIC_APP_VERSION="d2025.06.0" OLYMPIC_APP_VERSION="dev build"
) )
install( install(

View File

@@ -18,7 +18,7 @@
<string>APPL</string> <string>APPL</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>d2025.06.0</string> <string>dev build</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>12.0.0</string> <string>12.0.0</string>

View File

@@ -55,7 +55,7 @@ void registerStudioModules() noexcept;
#if defined(_WIN32) && OLYMPIC_GUI_APP #if defined(_WIN32) && OLYMPIC_GUI_APP
int WinMain() { int WinMain() {
auto const argc = __argc; auto const argc = __argc;
auto const argv = const_cast<const char**>(__argv); auto const argv = const_cast<char const**>(__argv);
#else #else
int main(int const argc, char const **argv) { int main(int const argc, char const **argv) {
#endif #endif

View File

@@ -26,7 +26,7 @@ ox::Error writeUuidHeader(ox::Writer_c auto &writer, ox::UUID const&uuid) noexce
template<typename T> template<typename T>
ox::Result<T> readAsset(ox::BufferView buff) noexcept { ox::Result<T> readAsset(ox::BufferView buff) noexcept {
std::size_t offset = 0; std::size_t offset = 0;
const auto err = readUuidHeader(buff).error; auto const err = readUuidHeader(buff).error;
if (!err) { if (!err) {
offset = K1HdrSz; // the size of K1 headers offset = K1HdrSz; // the size of K1 headers
} }

View File

@@ -37,8 +37,8 @@ ox::Result<ox::ModelObject> readAsset(ox::TypeStore &ts, ox::BufferView buff) no
} }
ox::Result<ox::StringView> readAssetTypeId(ox::BufferView const buff) noexcept { ox::Result<ox::StringView> readAssetTypeId(ox::BufferView const buff) noexcept {
const auto err = readUuidHeader(buff).error; auto const err = readUuidHeader(buff).error;
const auto offset = err ? 0u : K1HdrSz; auto const offset = err ? 0u : K1HdrSz;
if (offset >= buff.size()) [[unlikely]] { if (offset >= buff.size()) [[unlikely]] {
return ox::Error(1, "Buffer too small for expected data"); return ox::Error(1, "Buffer too small for expected data");
} }
@@ -47,8 +47,8 @@ ox::Result<ox::StringView> readAssetTypeId(ox::BufferView const buff) noexcept {
ox::Result<AssetHdr> readAssetHeader(ox::BufferView buff) noexcept { ox::Result<AssetHdr> readAssetHeader(ox::BufferView buff) noexcept {
ox::Result<AssetHdr> out; ox::Result<AssetHdr> out;
const auto err = readUuidHeader(buff).moveTo(out.value.uuid); auto const err = readUuidHeader(buff).moveTo(out.value.uuid);
const auto offset = err ? 0u : K1HdrSz; auto const offset = err ? 0u : K1HdrSz;
if (offset >= buff.size()) [[unlikely]] { if (offset >= buff.size()) [[unlikely]] {
return ox::Error(1, "Buffer too small for expected data"); return ox::Error(1, "Buffer too small for expected data");
} }

View File

@@ -49,7 +49,7 @@ static ox::Result<ox::UPtr<Wrap>> convert(
if (!subConverter.converter().dstMatches(dstTypeName, dstTypeVersion)) { if (!subConverter.converter().dstMatches(dstTypeName, dstTypeVersion)) {
continue; continue;
} }
const auto [intermediate, chainErr] = auto const [intermediate, chainErr] =
convert(ctx, converters, src, srcTypeName, srcTypeVersion, convert(ctx, converters, src, srcTypeName, srcTypeVersion,
subConverter.converter().srcTypeName(), subConverter.converter().srcTypeVersion()); subConverter.converter().srcTypeName(), subConverter.converter().srcTypeVersion());
if (!chainErr) { if (!chainErr) {

View File

@@ -25,7 +25,7 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
}, },
}; };
int main(int argc, const char **argv) { int main(int argc, char const **argv) {
int retval = -1; int retval = -1;
if (argc > 0) { if (argc > 0) {
auto const args = ox::Span{argv, static_cast<size_t>(argc)}; auto const args = ox::Span{argv, static_cast<size_t>(argc)};

View File

@@ -61,7 +61,7 @@ static ox::Error runApp(
static ox::Error run( static ox::Error run(
ox::StringViewCR appName, ox::StringViewCR appName,
ox::StringViewCR projectDataDir, ox::StringViewCR projectDataDir,
ox::SpanView<const char*>) { ox::SpanView<ox::CString>) {
// seed UUID generator // seed UUID generator
auto const time = std::time(nullptr); auto const time = std::time(nullptr);
ox::UUID::seedGenerator({ ox::UUID::seedGenerator({

View File

@@ -28,7 +28,7 @@ void ClawEditor::draw(Context&) noexcept {
ImGui::EndChild(); ImGui::EndChild();
} }
void ClawEditor::drawRow(ox::ModelValue const&value) noexcept { void ClawEditor::drawRow(ox::ModelValue const &value) noexcept {
using Str = ox::BasicString<100>; using Str = ox::BasicString<100>;
Str val, type; Str val, type;
switch (value.type()) { switch (value.type()) {
@@ -93,13 +93,13 @@ void ClawEditor::drawRow(ox::ModelValue const&value) noexcept {
ImGui::Text("%s", val.c_str()); ImGui::Text("%s", val.c_str());
} }
void ClawEditor::drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const&value) noexcept { void ClawEditor::drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const &value) noexcept {
using Str = ox::BasicString<100>; using Str = ox::BasicString<100>;
path.push_back(name); path.push_back(name);
if (value.type() == ox::ModelValue::Type::Object) { if (value.type() == ox::ModelValue::Type::Object) {
drawTree(path, value.get<ox::ModelObject>()); drawTree(path, value.get<ox::ModelObject>());
} else if (value.type() == ox::ModelValue::Type::Vector) { } else if (value.type() == ox::ModelValue::Type::Vector) {
auto const&vec = value.get<ox::ModelValueVector>(); auto const &vec = value.get<ox::ModelValueVector>();
auto const pathStr = ox::join<Str>("##", path).unwrap(); auto const pathStr = ox::join<Str>("##", path).unwrap();
auto const lbl = ox::sfmt<Str>("{}##{}", name, pathStr); auto const lbl = ox::sfmt<Str>("{}##{}", name, pathStr);
auto const flags = ImGuiTreeNodeFlags_SpanFullWidth auto const flags = ImGuiTreeNodeFlags_SpanFullWidth
@@ -110,7 +110,7 @@ void ClawEditor::drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue co
ImGui::SameLine(); ImGui::SameLine();
drawRow(value); drawRow(value);
if (open) { if (open) {
for (auto i = 0lu; auto const&e: vec) { for (auto i = 0lu; auto const &e: vec) {
auto const iStr = ox::sfmt<Str>("{}", i); auto const iStr = ox::sfmt<Str>("{}", i);
path.push_back(iStr); path.push_back(iStr);
ImGui::TableNextRow(0, 5); ImGui::TableNextRow(0, 5);
@@ -138,16 +138,16 @@ void ClawEditor::drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue co
path.pop_back(); path.pop_back();
} }
void ClawEditor::drawTree(ObjPath &path, ox::ModelObject const&obj) noexcept { void ClawEditor::drawTree(ObjPath &path, ox::ModelObject const &obj) noexcept {
using Str = ox::BasicString<100>; using Str = ox::BasicString<100>;
for (const auto &c : obj) { for (auto const &c : obj) {
ImGui::TableNextRow(0, 5); ImGui::TableNextRow(0, 5);
auto pathStr = ox::join<Str>("##", path).unwrap(); auto pathStr = ox::join<Str>("##", path).unwrap();
auto lbl = ox::sfmt<Str>("{}##{}", c->name, pathStr); auto lbl = ox::sfmt<Str>("{}##{}", c->name, pathStr);
const auto rowSelected = false; auto const rowSelected = false;
const auto hasChildren = c->value.type() == ox::ModelValue::Type::Object auto const hasChildren = c->value.type() == ox::ModelValue::Type::Object
|| c->value.type() == ox::ModelValue::Type::Vector; || c->value.type() == ox::ModelValue::Type::Vector;
const auto flags = ImGuiTreeNodeFlags_SpanFullWidth auto const flags = ImGuiTreeNodeFlags_SpanFullWidth
| ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnArrow
| (hasChildren ? 0 : ImGuiTreeNodeFlags_Leaf) | (hasChildren ? 0 : ImGuiTreeNodeFlags_Leaf)
| (rowSelected ? ImGuiTreeNodeFlags_Selected : 0); | (rowSelected ? ImGuiTreeNodeFlags_Selected : 0);
@@ -158,7 +158,7 @@ void ClawEditor::drawTree(ObjPath &path, ox::ModelObject const&obj) noexcept {
//} //}
path.push_back(c->name); path.push_back(c->name);
if (c->value.type() == ox::ModelValue::Type::Object) { if (c->value.type() == ox::ModelValue::Type::Object) {
const auto open = ImGui::TreeNodeEx(lbl.c_str(), flags); auto const open = ImGui::TreeNodeEx(lbl.c_str(), flags);
ImGui::SameLine(); ImGui::SameLine();
drawRow(c->value); drawRow(c->value);
if (open) { if (open) {

View File

@@ -21,11 +21,11 @@ class ClawEditor: public Editor {
void draw(Context&) noexcept final; void draw(Context&) noexcept final;
private: private:
static void drawRow(ox::ModelValue const&value) noexcept; static void drawRow(ox::ModelValue const &value) noexcept;
void drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const&value) noexcept; void drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const &value) noexcept;
void drawTree(ObjPath &path, ox::ModelObject const&obj) noexcept; void drawTree(ObjPath &path, ox::ModelObject const &obj) noexcept;
}; };
} }

View File

@@ -24,7 +24,7 @@ void NewMenu::open() noexcept {
m_useDefaultPath = true; m_useDefaultPath = true;
m_explorer.setModel(buildFileTreeModel( m_explorer.setModel(buildFileTreeModel(
m_explorer, m_explorer,
[](ox::StringViewCR, ox::FileStat const&s) { [](ox::StringViewCR, ox::FileStat const &s) {
return s.fileType == ox::FileType::Directory; return s.fileType == ox::FileType::Directory;
}).or_value(ox::UPtr<FileTreeModel>{})); }).or_value(ox::UPtr<FileTreeModel>{}));
} }
@@ -75,26 +75,26 @@ void NewMenu::addItemMaker(ox::UPtr<ItemMaker> &&im) noexcept {
m_types.emplace_back(std::move(im)); m_types.emplace_back(std::move(im));
std::sort( std::sort(
m_types.begin(), m_types.end(), m_types.begin(), m_types.end(),
[](ox::UPtr<ItemMaker> const&im1, ox::UPtr<ItemMaker> const&im2) { [](ox::UPtr<ItemMaker> const &im1, ox::UPtr<ItemMaker> const &im2) {
return im1->typeDisplayName() < im2->typeDisplayName(); return im1->typeDisplayName() < im2->typeDisplayName();
}); });
} }
void NewMenu::installItemTemplate(ox::UPtr<ItemTemplate> &&tmplt) noexcept { void NewMenu::installItemTemplate(ox::UPtr<ItemTemplate> &&tmplt) noexcept {
for (auto const&im : m_types) { for (auto const &im : m_types) {
if (im->installTemplate(std::move(tmplt))) { if (im->installTemplate(std::move(tmplt))) {
break; break;
} }
} }
} }
void NewMenu::drawNewItemType(Context const&sctx) noexcept { void NewMenu::drawNewItemType(Context const &sctx) noexcept {
setSize({280, 180}); setSize({280, 180});
drawWindow(sctx.tctx, m_open, [this] { drawWindow(sctx.tctx, m_open, [this] {
ig::ListBox("Item Type", [&](size_t const i) -> ox::CStringView { ig::ListBox("Item Type", [&](size_t const i) -> ox::CStringView {
return m_types[i]->typeDisplayName(); return m_types[i]->typeDisplayName();
}, m_types.size(), m_selectedType, {200, 100}); }, m_types.size(), m_selectedType, {200, 100});
auto const&im = *m_types[m_selectedType]; auto const &im = *m_types[m_selectedType];
drawFirstPageButtons(im.itemTemplates().size() == 1 ? drawFirstPageButtons(im.itemTemplates().size() == 1 ?
Stage::NewItemTransitioningToPath : Stage::NewItemTemplate); Stage::NewItemTransitioningToPath : Stage::NewItemTemplate);
if (m_stage == Stage::NewItemTransitioningToPath || m_stage == Stage::NewItemTemplate) { if (m_stage == Stage::NewItemTransitioningToPath || m_stage == Stage::NewItemTemplate) {
@@ -105,10 +105,10 @@ void NewMenu::drawNewItemType(Context const&sctx) noexcept {
}); });
} }
void NewMenu::drawNewItemTemplate(Context const&sctx) noexcept { void NewMenu::drawNewItemTemplate(Context const &sctx) noexcept {
setSize({280, 180}); setSize({280, 180});
drawWindow(sctx.tctx, m_open, [this] { drawWindow(sctx.tctx, m_open, [this] {
auto const&templates = auto const &templates =
m_types[m_selectedType]->itemTemplates(); m_types[m_selectedType]->itemTemplates();
ig::ListBox("Template", [&](size_t const i) -> ox::CStringView { ig::ListBox("Template", [&](size_t const i) -> ox::CStringView {
return templates[i]->name(); return templates[i]->name();

View File

@@ -75,7 +75,7 @@ class NewMenu final: public Popup {
void installItemTemplate(ox::UPtr<ItemTemplate> &&tmplt) noexcept; void installItemTemplate(ox::UPtr<ItemTemplate> &&tmplt) noexcept;
private: private:
void drawNewItemType(Context const&sctx) noexcept; void drawNewItemType(Context const &sctx) noexcept;
void drawNewItemPath(Context &sctx) noexcept; void drawNewItemPath(Context &sctx) noexcept;

View File

@@ -13,7 +13,7 @@
namespace studio { namespace studio {
class NewProject: public studio::Popup { class NewProject: public Popup {
public: public:
enum class Stage { enum class Stage {
Closed, Closed,

View File

@@ -635,8 +635,7 @@ ox::Error StudioUI::openProjectPath(ox::StringParam path) noexcept {
keel::DuplicateSet ds; keel::DuplicateSet ds;
OX_RETURN_ERROR(keel::setRomFs(keelCtx(m_tctx), std::move(fs), ds)); OX_RETURN_ERROR(keel::setRomFs(keelCtx(m_tctx), std::move(fs), ds));
if (ds.size()) { if (ds.size()) {
ox::String msg; ox::String msg{"Multiple files have the same UUID:\n"};
msg += "Multiple files have the same UUID:\n";
for (auto const &k : ds.keys()) { for (auto const &k : ds.keys()) {
msg += ox::sfmt("\n\t{}:\n", k.toString()); msg += ox::sfmt("\n\t{}:\n", k.toString());
for (auto const &v : ds[k]) { for (auto const &v : ds[k]) {

View File

@@ -140,7 +140,7 @@ class Editor: public studio::BaseEditor {
ox::Error pushCommand(Args&&... args) noexcept { ox::Error pushCommand(Args&&... args) noexcept {
try { try {
return m_undoStack.push(ox::make_unique<UC>(ox::forward<Args>(args)...)); return m_undoStack.push(ox::make_unique<UC>(ox::forward<Args>(args)...));
} catch (ox::Exception const&ex) { } catch (ox::Exception const &ex) {
return ex.toError(); return ex.toError();
} }
} }
@@ -148,7 +148,7 @@ class Editor: public studio::BaseEditor {
private: private:
ox::Error markUnsavedChanges(UndoCommand const*) noexcept; ox::Error markUnsavedChanges(UndoCommand const*) noexcept;
ox::Error handleRename(ox::StringViewCR oldPath, ox::StringViewCR newPath, ox::UUID const&id) noexcept; ox::Error handleRename(ox::StringViewCR oldPath, ox::StringViewCR newPath, ox::UUID const &id) noexcept;
}; };

View File

@@ -21,7 +21,7 @@ struct FDFilterItem {
FDFilterItem(ox::StringViewCR pName, ox::StringViewCR pSpec) noexcept; FDFilterItem(ox::StringViewCR pName, ox::StringViewCR pSpec) noexcept;
}; };
ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const&exts) noexcept; ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const &exts) noexcept;
ox::Result<ox::String> chooseDirectory() noexcept; ox::Result<ox::String> chooseDirectory() noexcept;

View File

@@ -24,6 +24,8 @@ class FilePickerPopup {
public: public:
explicit FilePickerPopup(ox::StringParam name, keel::Context &kctx, ox::StringParam fileExt) noexcept; explicit FilePickerPopup(ox::StringParam name, keel::Context &kctx, ox::StringParam fileExt) noexcept;
explicit FilePickerPopup(ox::StringParam name, keel::Context &kctx, ox::SpanView<ox::StringLiteral> fileExts) noexcept;
explicit FilePickerPopup(ox::StringParam name, keel::Context &kctx, ox::Vector<ox::String> fileExts) noexcept; explicit FilePickerPopup(ox::StringParam name, keel::Context &kctx, ox::Vector<ox::String> fileExts) noexcept;
void refresh() noexcept; void refresh() noexcept;

View File

@@ -78,7 +78,7 @@ class FileExplorer: public ox::SignalHandler {
} }
private: private:
ox::Result<bool> setSelectedPath(ox::StringViewCR path, FileTreeModel const&node) noexcept; ox::Result<bool> setSelectedPath(ox::StringViewCR path, FileTreeModel const &node) noexcept;
}; };
@@ -106,7 +106,7 @@ class FileTreeModel {
void setChildren(ox::Vector<ox::UPtr<FileTreeModel>> children) noexcept; void setChildren(ox::Vector<ox::UPtr<FileTreeModel>> children) noexcept;
[[nodiscard]] [[nodiscard]]
ox::Vector<ox::UPtr<FileTreeModel>> const&children() const noexcept { ox::Vector<ox::UPtr<FileTreeModel>> const &children() const noexcept {
return m_children; return m_children;
} }
@@ -129,13 +129,13 @@ ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
ox::StringParam name, ox::StringParam name,
ox::StringViewCR path, ox::StringViewCR path,
FileTreeModel *parent = nullptr, FileTreeModel *parent = nullptr,
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const&filter = std::function<bool(ox::StringViewCR, ox::FileStat const&)> const &filter =
[](ox::StringViewCR, ox::FileStat const&) {return true;}, [](ox::StringViewCR, ox::FileStat const&) {return true;},
bool showEmptyDirs = true) noexcept; bool showEmptyDirs = true) noexcept;
ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel( ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
FileExplorer &explorer, FileExplorer &explorer,
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const&filter = std::function<bool(ox::StringViewCR, ox::FileStat const&)> const &filter =
[](ox::StringViewCR, ox::FileStat const&) {return true;}, [](ox::StringViewCR, ox::FileStat const&) {return true;},
bool showEmptyDirs = true) noexcept; bool showEmptyDirs = true) noexcept;

View File

@@ -131,7 +131,7 @@ class ChildStackItem {
class IDStackItem { class IDStackItem {
public: public:
explicit IDStackItem(int id) noexcept; explicit IDStackItem(int id) noexcept;
explicit IDStackItem(const char *id) noexcept; explicit IDStackItem(ox::CString const id) noexcept;
explicit IDStackItem(ox::CStringViewCR id) noexcept; explicit IDStackItem(ox::CStringViewCR id) noexcept;
~IDStackItem() noexcept; ~IDStackItem() noexcept;
}; };
@@ -244,7 +244,7 @@ bool BeginPopup(turbine::Context &ctx, ox::CStringViewCR popupName, bool &show,
* @return true if new value selected, false otherwise * @return true if new value selected, false otherwise
*/ */
bool ComboBox( bool ComboBox(
ox::CStringView lbl, ox::CStringView const &lbl,
ox::SpanView<ox::CStringView> list, ox::SpanView<ox::CStringView> list,
size_t &selectedIdx) noexcept; size_t &selectedIdx) noexcept;
@@ -255,7 +255,7 @@ bool ComboBox(
* @param selectedIdx * @param selectedIdx
* @return true if new value selected, false otherwise * @return true if new value selected, false otherwise
*/ */
bool ComboBox(ox::CStringView lbl, ox::Span<const ox::String> list, size_t &selectedIdx) noexcept; bool ComboBox(ox::CStringView const &lbl, ox::Span<ox::String const> list, size_t &selectedIdx) noexcept;
/** /**
* *

View File

@@ -27,11 +27,11 @@ class ItemTemplate {
virtual ~ItemTemplate() = default; virtual ~ItemTemplate() = default;
[[nodiscard]] [[nodiscard]]
constexpr ox::String const&name() const noexcept { constexpr ox::String const &name() const noexcept {
return m_name; return m_name;
} }
constexpr bool operator<=>(ItemTemplate const&other) const noexcept { constexpr bool operator<=>(ItemTemplate const &other) const noexcept {
return m_name != other.name() ? (m_name < other.name() ? -1 : 1) : 0; return m_name != other.name() ? (m_name < other.name() ? -1 : 1) : 0;
} }
@@ -105,7 +105,7 @@ class ItemMaker {
virtual ~ItemMaker() noexcept = default; virtual ~ItemMaker() noexcept = default;
[[nodiscard]] [[nodiscard]]
ox::String const&typeDisplayName() const noexcept { ox::String const &typeDisplayName() const noexcept {
return m_typeDisplayName; return m_typeDisplayName;
} }
@@ -120,17 +120,17 @@ class ItemMaker {
return false; return false;
} }
constexpr ox::Vector<ox::UPtr<ItemTemplate>> const&itemTemplates() const noexcept { constexpr ox::Vector<ox::UPtr<ItemTemplate>> const &itemTemplates() const noexcept {
return m_templates; return m_templates;
} }
[[nodiscard]] [[nodiscard]]
ox::String const&fileExt() const noexcept { ox::String const &fileExt() const noexcept {
return m_fileExt; return m_fileExt;
} }
[[nodiscard]] [[nodiscard]]
ox::String const&defaultPath() const noexcept { ox::String const &defaultPath() const noexcept {
return m_parentDir; return m_parentDir;
} }
@@ -212,7 +212,7 @@ class ItemMakerT final: public ItemMaker {
ox::StringParam pDisplayName, ox::StringParam pDisplayName,
ox::StringViewCR pParentDir, ox::StringViewCR pParentDir,
ox::StringParam fileExt, ox::StringParam fileExt,
T const&pItem, T const &pItem,
ox::ClawFormat const pFmt) noexcept: ox::ClawFormat const pFmt) noexcept:
ItemMaker( ItemMaker(
std::move(pDisplayName), std::move(pDisplayName),
@@ -249,7 +249,7 @@ class ItemMakerT final: public ItemMaker {
ox::StringViewCR pPath, ox::StringViewCR pPath,
size_t const pTemplateIdx) const noexcept override { size_t const pTemplateIdx) const noexcept override {
createUuidMapping(keelCtx(ctx.tctx), pPath, ox::UUID::generate().unwrap()); createUuidMapping(keelCtx(ctx.tctx), pPath, ox::UUID::generate().unwrap());
auto const&templates = itemTemplates(); auto const &templates = itemTemplates();
auto const tmplIdx = pTemplateIdx < templates.size() ? pTemplateIdx : 0; auto const tmplIdx = pTemplateIdx < templates.size() ? pTemplateIdx : 0;
OX_REQUIRE_M(tmpl, templates[tmplIdx]->getItem( OX_REQUIRE_M(tmpl, templates[tmplIdx]->getItem(
keelCtx(ctx), typeName(), typeVersion())); keelCtx(ctx), typeName(), typeVersion()));

View File

@@ -43,11 +43,11 @@ class Popup: public Widget {
m_title = std::move(title); m_title = std::move(title);
} }
constexpr ox::String const&title() const noexcept { constexpr ox::String const &title() const noexcept {
return m_title; return m_title;
} }
void drawWindow(turbine::Context &ctx, bool &open, std::function<void()> const&drawContents); void drawWindow(turbine::Context &ctx, bool &open, std::function<void()> const &drawContents);
}; };

View File

@@ -64,7 +64,7 @@ class Project: public ox::SignalHandler {
ox::Error create() noexcept; ox::Error create() noexcept;
[[nodiscard]] [[nodiscard]]
ox::String const&projectPath() const noexcept; ox::String const &projectPath() const noexcept;
[[nodiscard]] [[nodiscard]]
ox::FileSystem &romFs() noexcept; ox::FileSystem &romFs() noexcept;
@@ -77,7 +77,7 @@ class Project: public ox::SignalHandler {
template<typename T> template<typename T>
ox::Error writeObj( ox::Error writeObj(
ox::StringViewCR path, ox::StringViewCR path,
T const&obj, T const &obj,
ox::ClawFormat fmt) noexcept; ox::ClawFormat fmt) noexcept;
/** /**
@@ -86,7 +86,7 @@ class Project: public ox::SignalHandler {
template<typename T> template<typename T>
ox::Error writeObj( ox::Error writeObj(
ox::StringViewCR path, ox::StringViewCR path,
T const&obj) noexcept; T const &obj) noexcept;
template<typename T> template<typename T>
ox::Result<T> loadObj(ox::StringViewCR path) const noexcept; ox::Result<T> loadObj(ox::StringViewCR path) const noexcept;
@@ -108,7 +108,7 @@ class Project: public ox::SignalHandler {
ox::Error subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&slot) const noexcept; ox::Error subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&slot) const noexcept;
[[nodiscard]] [[nodiscard]]
ox::Vector<ox::String> const&fileList(ox::StringViewCR ext) noexcept; ox::Vector<ox::String> const &fileList(ox::StringViewCR ext) noexcept;
ox::Error writeTypeStore() noexcept; ox::Error writeTypeStore() noexcept;
@@ -117,7 +117,7 @@ class Project: public ox::SignalHandler {
void indexFile(ox::StringViewCR path) noexcept; void indexFile(ox::StringViewCR path) noexcept;
ox::Error writeBuff(ox::StringViewCR path, ox::BufferView const&buff) noexcept; ox::Error writeBuff(ox::StringViewCR path, ox::BufferView const &buff) noexcept;
ox::Result<ox::Buffer> loadBuff(ox::StringViewCR path) const noexcept; ox::Result<ox::Buffer> loadBuff(ox::StringViewCR path) const noexcept;
@@ -136,13 +136,13 @@ class Project: public ox::SignalHandler {
ox::Signal<ox::Error(ox::StringViewCR)> fileRecognized; ox::Signal<ox::Error(ox::StringViewCR)> fileRecognized;
ox::Signal<ox::Error(ox::StringViewCR)> fileDeleted; ox::Signal<ox::Error(ox::StringViewCR)> fileDeleted;
ox::Signal<ox::Error(ox::StringViewCR)> dirDeleted; ox::Signal<ox::Error(ox::StringViewCR)> dirDeleted;
ox::Signal<ox::Error(ox::StringViewCR path, ox::UUID const&id)> fileUpdated; ox::Signal<ox::Error(ox::StringViewCR path, ox::UUID const &id)> fileUpdated;
ox::Signal<ox::Error(ox::StringViewCR oldPath, ox::StringViewCR newPath, ox::UUID const&id)> fileMoved; ox::Signal<ox::Error(ox::StringViewCR oldPath, ox::StringViewCR newPath, ox::UUID const &id)> fileMoved;
}; };
template<typename T> template<typename T>
ox::Error Project::writeObj(ox::StringViewCR path, T const&obj, ox::ClawFormat fmt) noexcept { ox::Error Project::writeObj(ox::StringViewCR path, T const &obj, ox::ClawFormat fmt) noexcept {
OX_REQUIRE_M(buff, ox::writeClaw(obj, fmt)); OX_REQUIRE_M(buff, ox::writeClaw(obj, fmt));
if (fmt == ox::ClawFormat::Organic) { if (fmt == ox::ClawFormat::Organic) {
buff.pop_back(); buff.pop_back();
@@ -167,7 +167,7 @@ ox::Error Project::writeObj(ox::StringViewCR path, T const&obj, ox::ClawFormat f
} }
template<typename T> template<typename T>
ox::Error Project::writeObj(ox::StringViewCR path, T const&obj) noexcept { ox::Error Project::writeObj(ox::StringViewCR path, T const &obj) noexcept {
OX_REQUIRE(ext, fileExt(path)); OX_REQUIRE(ext, fileExt(path));
auto const fmt = m_typeFmt[ext].or_value(ox::ClawFormat::Metal); auto const fmt = m_typeFmt[ext].or_value(ox::ClawFormat::Metal);
return writeObj(path, obj, fmt); return writeObj(path, obj, fmt);
@@ -197,7 +197,7 @@ ox::Error Project::subscribe(ProjectEvent e, ox::SignalHandler *tgt, Functor &&s
case ProjectEvent::FileRecognized: case ProjectEvent::FileRecognized:
{ {
OX_REQUIRE(files, listFiles()); OX_REQUIRE(files, listFiles());
for (auto const&f : files) { for (auto const &f : files) {
slot(f); slot(f);
} }
connect(this, &Project::fileRecognized, tgt, slot); connect(this, &Project::fileRecognized, tgt, slot);

View File

@@ -16,19 +16,19 @@ namespace studio {
struct Selection { struct Selection {
ox::Point a, b; ox::Point a, b;
constexpr Selection() noexcept = default; constexpr Selection() noexcept = default;
constexpr Selection(ox::Point const&pA, ox::Point const&pB) noexcept: a(pA), b(pB) {} constexpr Selection(ox::Point const &pA, ox::Point const &pB) noexcept: a(pA), b(pB) {}
[[nodiscard]] [[nodiscard]]
constexpr ox::Size size() const noexcept { constexpr ox::Size size() const noexcept {
return {b.x - a.x, b.y - a.y}; return {b.x - a.x, b.y - a.y};
} }
[[nodiscard]] [[nodiscard]]
constexpr bool contains(ox::Point const&pt) const noexcept { constexpr bool contains(ox::Point const &pt) const noexcept {
return a.x <= pt.x && a.y <= pt.y return a.x <= pt.x && a.y <= pt.y
&& b.x >= pt.x && b.y >= pt.y; && b.x >= pt.x && b.y >= pt.y;
} }
}; };
constexpr auto iterateSelection(studio::Selection const&sel, auto const&cb) { constexpr auto iterateSelection(Selection const &sel, auto const &cb) {
constexpr auto retErr = ox::is_same_v<decltype(cb(0, 0)), ox::Error>; constexpr auto retErr = ox::is_same_v<decltype(cb(0, 0)), ox::Error>;
for (auto x = sel.a.x; x <= sel.b.x; ++x) { for (auto x = sel.a.x; x <= sel.b.x; ++x) {
for (auto y = sel.a.y; y <= sel.b.y; ++y) { for (auto y = sel.a.y; y <= sel.b.y; ++y) {
@@ -44,7 +44,7 @@ constexpr auto iterateSelection(studio::Selection const&sel, auto const&cb) {
} }
}; };
constexpr auto iterateSelectionRows(studio::Selection const&sel, auto const&cb) { constexpr auto iterateSelectionRows(Selection const &sel, auto const &cb) {
constexpr auto retErr = ox::is_same_v<decltype(cb(0, 0)), ox::Error>; constexpr auto retErr = ox::is_same_v<decltype(cb(0, 0)), ox::Error>;
for (auto y = sel.a.y; y <= sel.b.y; ++y) { for (auto y = sel.a.y; y <= sel.b.y; ++y) {
for (auto x = sel.a.x; x <= sel.b.x; ++x) { for (auto x = sel.a.x; x <= sel.b.x; ++x) {

View File

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

View File

@@ -20,7 +20,7 @@ FDFilterItem::FDFilterItem(ox::StringViewCR pName, ox::StringViewCR pSpec) noexc
OX_ALLOW_UNSAFE_BUFFERS_END OX_ALLOW_UNSAFE_BUFFERS_END
} }
static ox::Result<ox::String> toResult(nfdresult_t r, NFD::UniquePathN const&path) noexcept { static ox::Result<ox::String> toResult(nfdresult_t r, NFD::UniquePathN const &path) noexcept {
switch (r) { switch (r) {
case NFD_OKAY: { case NFD_OKAY: {
ox::String out; ox::String out;
@@ -39,11 +39,11 @@ OX_ALLOW_UNSAFE_BUFFERS_END
} }
} }
ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const&exts) noexcept { ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const &exts) noexcept {
NFD::Guard const guard; NFD::Guard const guard;
NFD::UniquePathN path; NFD::UniquePathN path;
ox::Vector<nfdnfilteritem_t, 5> filterItems(exts.size()); ox::Vector<nfdnfilteritem_t, 5> filterItems(exts.size());
for (auto i = 0u; auto const&f : exts) { for (auto i = 0u; auto const &f : exts) {
filterItems[i].name = f.name.data(); filterItems[i].name = f.name.data();
filterItems[i].spec = f.spec.data(); filterItems[i].spec = f.spec.data();
++i; ++i;

View File

@@ -26,6 +26,22 @@ FilePickerPopup::FilePickerPopup(
m_fileExts{std::move(fileExt)} { m_fileExts{std::move(fileExt)} {
} }
FilePickerPopup::FilePickerPopup(
ox::StringParam name,
keel::Context &kctx,
ox::SpanView<ox::StringLiteral> fileExts) noexcept:
m_name{std::move(name)},
m_explorer{kctx},
m_fileExts{[fileExts] {
ox::Vector<ox::String> out;
out.reserve(fileExts.size());
for (auto &s : fileExts) {
out.emplace_back(s);
}
return out;
}()} {
}
FilePickerPopup::FilePickerPopup( FilePickerPopup::FilePickerPopup(
ox::StringParam name, ox::StringParam name,
keel::Context &kctx, keel::Context &kctx,

View File

@@ -60,7 +60,7 @@ void FileExplorer::fileContextMenu(ox::StringViewCR) const noexcept {}
void FileExplorer::dirContextMenu(ox::StringViewCR) const noexcept {} void FileExplorer::dirContextMenu(ox::StringViewCR) const noexcept {}
ox::Result<bool> FileExplorer::setSelectedPath( ox::Result<bool> FileExplorer::setSelectedPath(
ox::StringViewCR path, FileTreeModel const&node) noexcept { ox::StringViewCR path, FileTreeModel const &node) noexcept {
if (path == node.path()) { if (path == node.path()) {
m_selected = &node; m_selected = &node;
return {}; return {};
@@ -117,7 +117,7 @@ void FileTreeModel::draw(turbine::Context &tctx) const noexcept {
} }
} }
if (nodeOpen) { if (nodeOpen) {
for (auto const&child : m_children) { for (auto const &child : m_children) {
child->draw(tctx); child->draw(tctx);
} }
ImGui::TreePop(); ImGui::TreePop();
@@ -160,16 +160,16 @@ ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
ox::StringParam name, ox::StringParam name,
ox::StringViewCR path, ox::StringViewCR path,
FileTreeModel *parent, FileTreeModel *parent,
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const &filter, std::function<bool(ox::StringViewCR, ox::FileStat const &)> const &filter,
bool const showEmptyDirs) noexcept { bool const showEmptyDirs) noexcept {
auto const&fs = explorer.romFs(); auto const &fs = explorer.romFs();
OX_REQUIRE(stat, fs.stat(path)); OX_REQUIRE(stat, fs.stat(path));
auto out = ox::make_unique<FileTreeModel>(explorer, std::move(name), stat.fileType, parent); auto out = ox::make_unique<FileTreeModel>(explorer, std::move(name), stat.fileType, parent);
if (stat.fileType == ox::FileType::Directory) { if (stat.fileType == ox::FileType::Directory) {
OX_REQUIRE_M(children, fs.ls(path)); OX_REQUIRE_M(children, fs.ls(path));
std::sort(children.begin(), children.end()); std::sort(children.begin(), children.end());
ox::Vector<ox::UPtr<FileTreeModel>> outChildren; ox::Vector<ox::UPtr<FileTreeModel>> outChildren;
for (auto const&childName : children) { for (auto const &childName : children) {
if (childName[0] != '.') { if (childName[0] != '.') {
auto const childPath = ox::sfmt("{}/{}", path, childName); auto const childPath = ox::sfmt("{}/{}", path, childName);
OX_REQUIRE(childStat, fs.stat(childPath)); OX_REQUIRE(childStat, fs.stat(childPath));
@@ -195,7 +195,7 @@ ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel( ox::Result<ox::UPtr<FileTreeModel>> buildFileTreeModel(
FileExplorer &explorer, FileExplorer &explorer,
std::function<bool(ox::StringViewCR, ox::FileStat const&)> const&filter, std::function<bool(ox::StringViewCR, ox::FileStat const&)> const &filter,
bool const showEmptyDirs) noexcept { bool const showEmptyDirs) noexcept {
return buildFileTreeModel(explorer, "Project", "/", nullptr, filter, showEmptyDirs); return buildFileTreeModel(explorer, "Project", "/", nullptr, filter, showEmptyDirs);
} }

View File

@@ -18,11 +18,11 @@ ChildStackItem::~ChildStackItem() noexcept {
ImGui::EndChild(); ImGui::EndChild();
} }
IDStackItem::IDStackItem(int id) noexcept { IDStackItem::IDStackItem(int const id) noexcept {
ImGui::PushID(id); ImGui::PushID(id);
} }
IDStackItem::IDStackItem(const char *id) noexcept { IDStackItem::IDStackItem(ox::CString const id) noexcept {
ImGui::PushID(id); ImGui::PushID(id);
} }
@@ -55,7 +55,7 @@ bool PushButton(ox::CStringViewCR lbl, ImVec2 const &btnSz) noexcept {
} }
PopupResponse PopupControlsOkCancel( PopupResponse PopupControlsOkCancel(
float popupWidth, float const popupWidth,
bool &popupOpen, bool &popupOpen,
ox::CStringViewCR ok, ox::CStringViewCR ok,
ox::CStringViewCR cancel) { ox::CStringViewCR cancel) {
@@ -110,14 +110,14 @@ bool BeginPopup(turbine::Context &ctx, ox::CStringViewCR popupName, bool &show,
} }
bool ComboBox( bool ComboBox(
ox::CStringView lbl, ox::CStringView const &lbl,
ox::SpanView<ox::CStringView> list, ox::SpanView<ox::CStringView> const list,
size_t &selectedIdx) noexcept { size_t &selectedIdx) noexcept {
bool out{}; bool out{};
auto const first = selectedIdx < list.size() ? list[selectedIdx].c_str() : ""; auto const first = selectedIdx < list.size() ? list[selectedIdx].c_str() : "";
if (ImGui::BeginCombo(lbl.c_str(), first, 0)) { if (ImGui::BeginCombo(lbl.c_str(), first, 0)) {
for (auto i = 0u; i < list.size(); ++i) { for (auto i = 0u; i < list.size(); ++i) {
const auto selected = (selectedIdx == i); auto const selected = (selectedIdx == i);
if (ImGui::Selectable(list[i].c_str(), selected) && selectedIdx != i) { if (ImGui::Selectable(list[i].c_str(), selected) && selectedIdx != i) {
selectedIdx = i; selectedIdx = i;
out = true; out = true;
@@ -129,14 +129,14 @@ bool ComboBox(
} }
bool ComboBox( bool ComboBox(
ox::CStringView lbl, ox::CStringView const &lbl,
ox::Span<const ox::String> list, ox::Span<ox::String const> const list,
size_t &selectedIdx) noexcept { size_t &selectedIdx) noexcept {
bool out{}; bool out{};
auto const first = selectedIdx < list.size() ? list[selectedIdx].c_str() : ""; auto const first = selectedIdx < list.size() ? list[selectedIdx].c_str() : "";
if (ImGui::BeginCombo(lbl.c_str(), first, 0)) { if (ImGui::BeginCombo(lbl.c_str(), first, 0)) {
for (auto i = 0u; i < list.size(); ++i) { for (auto i = 0u; i < list.size(); ++i) {
const auto selected = (selectedIdx == i); auto const selected = (selectedIdx == i);
if (ImGui::Selectable(list[i].c_str(), selected) && selectedIdx != i) { if (ImGui::Selectable(list[i].c_str(), selected) && selectedIdx != i) {
selectedIdx = i; selectedIdx = i;
out = true; out = true;
@@ -150,13 +150,13 @@ bool ComboBox(
bool ComboBox( bool ComboBox(
ox::CStringViewCR lbl, ox::CStringViewCR lbl,
std::function<ox::CStringView(size_t)> const &f, std::function<ox::CStringView(size_t)> const &f,
size_t strCnt, size_t const strCnt,
size_t &selectedIdx) noexcept { size_t &selectedIdx) noexcept {
bool out{}; bool out{};
auto const first = selectedIdx < strCnt ? f(selectedIdx).c_str() : ""; auto const first = selectedIdx < strCnt ? f(selectedIdx).c_str() : "";
if (ImGui::BeginCombo(lbl.c_str(), first, 0)) { if (ImGui::BeginCombo(lbl.c_str(), first, 0)) {
for (auto i = 0u; i < strCnt; ++i) { for (auto i = 0u; i < strCnt; ++i) {
const auto selected = (selectedIdx == i); auto const selected = (selectedIdx == i);
if (ImGui::Selectable(f(i).c_str(), selected) && selectedIdx != i) { if (ImGui::Selectable(f(i).c_str(), selected) && selectedIdx != i) {
selectedIdx = i; selectedIdx = i;
out = true; out = true;

View File

@@ -7,8 +7,8 @@
namespace studio { namespace studio {
void Popup::drawWindow(turbine::Context &ctx, bool &open, std::function<void()> const&drawContents) { void Popup::drawWindow(turbine::Context &ctx, bool &open, std::function<void()> const &drawContents) {
studio::ig::centerNextWindow(ctx); ig::centerNextWindow(ctx);
ImGui::SetNextWindowSize(static_cast<ImVec2>(m_size)); ImGui::SetNextWindowSize(static_cast<ImVec2>(m_size));
constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; constexpr auto modalFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
if (ImGui::BeginPopupModal(m_title.c_str(), &open, modalFlags)) { if (ImGui::BeginPopupModal(m_title.c_str(), &open, modalFlags)) {

View File

@@ -75,7 +75,7 @@ ox::Error Project::create() noexcept {
return ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"); return ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed");
} }
ox::String const&Project::projectPath() const noexcept { ox::String const &Project::projectPath() const noexcept {
return m_path; return m_path;
} }
@@ -137,7 +137,7 @@ ox::Error Project::deleteItem(ox::StringViewCR path) noexcept {
if (stat.fileType == ox::FileType::Directory) { if (stat.fileType == ox::FileType::Directory) {
bool partialRemoval{}; bool partialRemoval{};
OX_REQUIRE(members, m_fs.ls(path)); OX_REQUIRE(members, m_fs.ls(path));
for (auto const&p : members) { for (auto const &p : members) {
partialRemoval = m_fs.remove(ox::sfmt("{}/{}", path, p)) || partialRemoval; partialRemoval = m_fs.remove(ox::sfmt("{}/{}", path, p)) || partialRemoval;
} }
if (partialRemoval) { if (partialRemoval) {
@@ -161,7 +161,7 @@ bool Project::exists(ox::StringViewCR path) const noexcept {
return m_fs.stat(path).error == 0; return m_fs.stat(path).error == 0;
} }
ox::Vector<ox::String> const&Project::fileList(ox::StringViewCR ext) noexcept { ox::Vector<ox::String> const &Project::fileList(ox::StringViewCR ext) noexcept {
return m_fileExtFileMap[ext]; return m_fileExtFileMap[ext];
} }
@@ -185,7 +185,7 @@ void Project::buildFileIndex() noexcept {
} }
m_fileExtFileMap.clear(); m_fileExtFileMap.clear();
std::sort(files.begin(), files.end()); std::sort(files.begin(), files.end());
for (auto const&file : files) { for (auto const &file : files) {
if (!beginsWith(file, ox::sfmt("/.{}/", m_projectDataDir))) { if (!beginsWith(file, ox::sfmt("/.{}/", m_projectDataDir))) {
indexFile(file); indexFile(file);
} }
@@ -200,7 +200,7 @@ void Project::indexFile(ox::StringViewCR path) noexcept {
m_fileExtFileMap[ext].emplace_back(path); m_fileExtFileMap[ext].emplace_back(path);
} }
ox::Error Project::writeBuff(ox::StringViewCR path, ox::BufferView const&buff) noexcept { ox::Error Project::writeBuff(ox::StringViewCR path, ox::BufferView const &buff) noexcept {
constexpr auto HdrSz = 40; constexpr auto HdrSz = 40;
ox::Buffer outBuff; ox::Buffer outBuff;
outBuff.reserve(buff.size() + HdrSz); outBuff.reserve(buff.size() + HdrSz);
@@ -227,7 +227,7 @@ ox::Result<ox::Buffer> Project::loadBuff(ox::StringViewCR path) const noexcept {
ox::Error Project::lsProcDir(ox::Vector<ox::String> &paths, ox::StringViewCR path) const noexcept { ox::Error Project::lsProcDir(ox::Vector<ox::String> &paths, ox::StringViewCR path) const noexcept {
OX_REQUIRE(files, m_fs.ls(path)); OX_REQUIRE(files, m_fs.ls(path));
for (auto const&name : files) { for (auto const &name : files) {
auto fullPath = ox::sfmt("{}/{}", path, name); auto fullPath = ox::sfmt("{}/{}", path, name);
OX_REQUIRE(stat, m_fs.stat(ox::StringView(fullPath))); OX_REQUIRE(stat, m_fs.stat(ox::StringView(fullPath)));
switch (stat.fileType) { switch (stat.fileType) {

View File

@@ -28,7 +28,7 @@ class ClipboardObject: public BaseClipboardObject {
} }
}; };
ox::String getClipboardText(Context &ctx) noexcept; ox::String getClipboardText(Context const &ctx) noexcept;
void setClipboardText(Context &ctx, ox::StringViewCR text) noexcept; void setClipboardText(Context &ctx, ox::StringViewCR text) noexcept;

View File

@@ -15,11 +15,11 @@ class Context;
void safeDelete(Context *p); void safeDelete(Context *p);
keel::Context const&keelCtx(Context const&ctx) noexcept; keel::Context const &keelCtx(Context const &ctx) noexcept;
keel::Context &keelCtx(Context &ctx) noexcept; keel::Context &keelCtx(Context &ctx) noexcept;
inline ox::FileSystem const*rom(Context const&ctx) noexcept { inline ox::FileSystem const*rom(Context const &ctx) noexcept {
return keelCtx(ctx).rom.get(); return keelCtx(ctx).rom.get();
} }
@@ -27,7 +27,7 @@ inline ox::FileSystem *rom(Context &ctx) noexcept {
return keelCtx(ctx).rom.get(); return keelCtx(ctx).rom.get();
} }
void setApplicationDataRaw(Context &ctx, ox::AnyPtr const&applicationData) noexcept; void setApplicationDataRaw(Context &ctx, ox::AnyPtr const &applicationData) noexcept;
template<typename T> template<typename T>
void setApplicationData(Context &ctx, T *applicationData) noexcept { void setApplicationData(Context &ctx, T *applicationData) noexcept {
@@ -35,7 +35,7 @@ void setApplicationData(Context &ctx, T *applicationData) noexcept {
} }
[[nodiscard]] [[nodiscard]]
ox::AnyPtr const&applicationDataRaw(Context &ctx) noexcept; ox::AnyPtr const &applicationDataRaw(Context &ctx) noexcept;
template<typename T> template<typename T>
[[nodiscard]] [[nodiscard]]

View File

@@ -41,7 +41,7 @@ ox::Size getScreenSize(Context const &ctx) noexcept;
ox::Bounds getWindowBounds(Context const &ctx) noexcept; ox::Bounds getWindowBounds(Context const &ctx) noexcept;
ox::Error setWindowBounds(Context &ctx, ox::Bounds const&bnds) noexcept; ox::Error setWindowBounds(Context &ctx, ox::Bounds const &bnds) noexcept;
/** /**
* Tells Turbine to refresh the screen within the specified period of time. * Tells Turbine to refresh the screen within the specified period of time.

View File

@@ -89,7 +89,7 @@ void setMouseButtonEventHandler(Context &ctx, MouseButtonEventHandler h) noexcep
KeyEventHandler keyEventHandler(Context const &ctx) noexcept; KeyEventHandler keyEventHandler(Context const &ctx) noexcept;
[[nodiscard]] [[nodiscard]]
bool buttonDown(Context const&ctx, Key) noexcept; bool buttonDown(Context const &ctx, Key) noexcept;
ox::Result<ox::UPtr<Context>> init(ox::UPtr<ox::FileSystem> &&fs, ox::StringViewCR appName) noexcept; ox::Result<ox::UPtr<Context>> init(ox::UPtr<ox::FileSystem> &&fs, ox::StringViewCR appName) noexcept;
@@ -100,7 +100,7 @@ ox::Error run(Context &ctx) noexcept;
// Returns the number of milliseconds that have passed since the start of the // Returns the number of milliseconds that have passed since the start of the
// program. // program.
[[nodiscard]] [[nodiscard]]
TimeMs ticksMs(Context const&ctx) noexcept; TimeMs ticksMs(Context const &ctx) noexcept;
void requestShutdown(Context &ctx, bool force = false) noexcept; void requestShutdown(Context &ctx, bool force = false) noexcept;

View File

@@ -9,7 +9,7 @@
namespace turbine { namespace turbine {
ox::String getClipboardText(Context&) noexcept { ox::String getClipboardText(Context const &) noexcept {
return {}; return {};
} }

View File

@@ -10,7 +10,7 @@ void safeDelete(Context *p) {
delete p; delete p;
} }
keel::Context const&keelCtx(Context const&ctx) noexcept { keel::Context const &keelCtx(Context const &ctx) noexcept {
return ctx.keelCtx; return ctx.keelCtx;
} }
@@ -18,11 +18,11 @@ keel::Context &keelCtx(Context &ctx) noexcept {
return ctx.keelCtx; return ctx.keelCtx;
} }
void setApplicationDataRaw(Context &ctx, ox::AnyPtr const&applicationData) noexcept { void setApplicationDataRaw(Context &ctx, ox::AnyPtr const &applicationData) noexcept {
ctx.applicationData = applicationData; ctx.applicationData = applicationData;
} }
ox::AnyPtr const&applicationDataRaw(Context &ctx) noexcept { ox::AnyPtr const &applicationDataRaw(Context &ctx) noexcept {
return ctx.applicationData; return ctx.applicationData;
} }

View File

@@ -23,8 +23,8 @@ class Context final {
Context() noexcept = default; Context() noexcept = default;
Context(Context &other) noexcept = delete; Context(Context &other) noexcept = delete;
Context(Context const&other) noexcept = delete; Context(Context const &other) noexcept = delete;
Context(Context const&&other) noexcept = delete; Context(Context const &&other) noexcept = delete;
}; };

View File

@@ -12,7 +12,7 @@
namespace turbine { namespace turbine {
ox::String getClipboardText(Context &ctx) noexcept { ox::String getClipboardText(Context const &ctx) noexcept {
return ox::String(glfwGetClipboardString(ctx.window)); return ox::String(glfwGetClipboardString(ctx.window));
} }

View File

@@ -12,7 +12,7 @@ void safeDelete(Context *p) {
delete p; delete p;
} }
keel::Context const&keelCtx(Context const&ctx) noexcept { keel::Context const &keelCtx(Context const &ctx) noexcept {
return ctx.keelCtx; return ctx.keelCtx;
} }
@@ -20,11 +20,11 @@ keel::Context &keelCtx(Context &ctx) noexcept {
return ctx.keelCtx; return ctx.keelCtx;
} }
void setApplicationDataRaw(Context &ctx, ox::AnyPtr const&applicationData) noexcept { void setApplicationDataRaw(Context &ctx, ox::AnyPtr const &applicationData) noexcept {
ctx.applicationData = applicationData; ctx.applicationData = applicationData;
} }
ox::AnyPtr const&applicationDataRaw(Context &ctx) noexcept { ox::AnyPtr const &applicationDataRaw(Context &ctx) noexcept {
return ctx.applicationData; return ctx.applicationData;
} }

View File

@@ -35,8 +35,8 @@ class Context {
Context() noexcept = default; Context() noexcept = default;
Context(Context const&other) noexcept = delete; Context(Context const &other) noexcept = delete;
Context(Context const&&other) noexcept = delete; Context(Context const &&other) noexcept = delete;
}; };

View File

@@ -214,7 +214,7 @@ ox::Bounds getWindowBounds(Context const &ctx) noexcept {
return bnds; return bnds;
} }
ox::Error setWindowBounds(Context &ctx, ox::Bounds const&bnds) noexcept { ox::Error setWindowBounds(Context &ctx, ox::Bounds const &bnds) noexcept {
glfwSetWindowPos(ctx.window, bnds.x, bnds.y); glfwSetWindowPos(ctx.window, bnds.x, bnds.y);
glfwSetWindowSize(ctx.window, bnds.width, bnds.height); glfwSetWindowSize(ctx.window, bnds.width, bnds.height);
return {}; return {};
@@ -430,13 +430,13 @@ ox::Error run(Context &ctx) noexcept {
return {}; return {};
} }
TimeMs ticksMs(Context const&ctx) noexcept { TimeMs ticksMs(Context const &ctx) noexcept {
using namespace std::chrono; using namespace std::chrono;
auto const now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); auto const now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
return static_cast<TimeMs>(now) - ctx.startTime; return static_cast<TimeMs>(now) - ctx.startTime;
} }
bool buttonDown(Context const&ctx, Key const key) noexcept { bool buttonDown(Context const &ctx, Key const key) noexcept {
return (ctx.keysDown >> static_cast<int>(key)) & 1; return (ctx.keysDown >> static_cast<int>(key)) & 1;
} }