Compare commits
3 Commits
861d177a27
...
8764444758
Author | SHA1 | Date | |
---|---|---|---|
8764444758 | |||
ce9a0b1fdb | |||
f7a468ea1e |
20
deps/ox/src/ox/std/span.hpp
vendored
20
deps/ox/src/ox/std/span.hpp
vendored
@ -14,7 +14,7 @@
|
|||||||
#include "iterator.hpp"
|
#include "iterator.hpp"
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
|
|
||||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ class Span {
|
|||||||
return m_items[i];
|
return m_items[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const T &operator[](std::size_t i) const noexcept {
|
constexpr T const&operator[](std::size_t i) const noexcept {
|
||||||
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
|
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
|
||||||
return m_items[i];
|
return m_items[i];
|
||||||
}
|
}
|
||||||
@ -168,8 +168,20 @@ class Span {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using SpanView = Span<const T>;
|
using SpanView = Span<T const>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr void spancpy(ox::Span<T> const dst, ox::SpanView<T> const src) noexcept {
|
||||||
|
auto const sz = ox::min(dst.size(), src.size());
|
||||||
|
if (std::is_constant_evaluated() || std::is_trivially_copyable_v<T>) {
|
||||||
|
for (size_t i{}; i < sz; ++i) {
|
||||||
|
dst.data()[i] = src.data()[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(dst.data(), src.data(), sz * sizeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OX_CLANG_NOWARN_END
|
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||||
|
10
deps/ox/src/ox/std/typetraits.hpp
vendored
10
deps/ox/src/ox/std/typetraits.hpp
vendored
@ -19,12 +19,15 @@
|
|||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr bool is_union_v = __is_union(T);
|
inline constexpr bool is_union_v = __is_union(T);
|
||||||
|
|
||||||
constexpr bool is_constant_evaluated() noexcept {
|
inline constexpr bool is_constant_evaluated() noexcept {
|
||||||
return __builtin_is_constant_evaluated();
|
return __builtin_is_constant_evaluated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -156,6 +159,9 @@ static_assert(is_class<int>::value == false);
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr bool is_class_v = is_class<T>();
|
constexpr bool is_class_v = is_class<T>();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline constexpr bool is_trivially_copyable_v = std::is_trivially_copyable_v<T>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr bool is_signed_v = integral_constant<bool, T(-1) < T(0)>::value;
|
constexpr bool is_signed_v = integral_constant<bool, T(-1) < T(0)>::value;
|
||||||
|
|
||||||
|
@ -142,6 +142,10 @@ ox::Error loadBgTileSheet(
|
|||||||
unsigned cbb,
|
unsigned cbb,
|
||||||
TileSheetSet const&set) noexcept;
|
TileSheetSet const&set) noexcept;
|
||||||
|
|
||||||
|
void clearCbb(Context &ctx, unsigned cbb) noexcept;
|
||||||
|
|
||||||
|
void clearCbbs(Context &ctx) noexcept;
|
||||||
|
|
||||||
ox::Error loadBgTileSheet(
|
ox::Error loadBgTileSheet(
|
||||||
Context &ctx,
|
Context &ctx,
|
||||||
unsigned cbb,
|
unsigned cbb,
|
||||||
|
11
src/nostalgia/modules/core/include/nostalgia/core/studio.hpp
Normal file
11
src/nostalgia/modules/core/include/nostalgia/core/studio.hpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <studio/studio.hpp>
|
||||||
|
|
||||||
|
namespace nostalgia::core {
|
||||||
|
|
||||||
|
}
|
@ -18,6 +18,23 @@
|
|||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
|
struct SubSheetTemplate {
|
||||||
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.SubSheetTemplate";
|
||||||
|
static constexpr auto TypeVersion = 1;
|
||||||
|
ox::String name;
|
||||||
|
int32_t width{};
|
||||||
|
int32_t height{};
|
||||||
|
ox::Vector<SubSheetTemplate> subsheets;
|
||||||
|
};
|
||||||
|
|
||||||
|
OX_MODEL_BEGIN(SubSheetTemplate)
|
||||||
|
OX_MODEL_FIELD(name)
|
||||||
|
OX_MODEL_FIELD(width)
|
||||||
|
OX_MODEL_FIELD(height)
|
||||||
|
OX_MODEL_FIELD(subsheets)
|
||||||
|
OX_MODEL_END()
|
||||||
|
|
||||||
|
|
||||||
// Predecessor to TileSheet, kept for backward compatibility
|
// Predecessor to TileSheet, kept for backward compatibility
|
||||||
struct TileSheetV1 {
|
struct TileSheetV1 {
|
||||||
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.NostalgiaGraphic";
|
static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.NostalgiaGraphic";
|
||||||
|
@ -63,6 +63,19 @@ ox::Error loadSpritePalette(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clearCbb(Context&, unsigned const cbb) noexcept {
|
||||||
|
for (auto &v : MEM_BG_TILES[cbb]) {
|
||||||
|
v = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearCbbs(Context &ctx) noexcept {
|
||||||
|
clearCbb(ctx, 0);
|
||||||
|
clearCbb(ctx, 1);
|
||||||
|
clearCbb(ctx, 2);
|
||||||
|
clearCbb(ctx, 3);
|
||||||
|
}
|
||||||
|
|
||||||
static ox::Error loadTileSheetSet(
|
static ox::Error loadTileSheetSet(
|
||||||
Context &ctx,
|
Context &ctx,
|
||||||
ox::Span<uint16_t> tileMapTargetMem,
|
ox::Span<uint16_t> tileMapTargetMem,
|
||||||
|
@ -118,8 +118,8 @@ static void setSpriteBufferObject(
|
|||||||
uint_t textureRow,
|
uint_t textureRow,
|
||||||
uint_t flipX,
|
uint_t flipX,
|
||||||
uint_t priority,
|
uint_t priority,
|
||||||
float *vbo,
|
ox::Span<float> vbo,
|
||||||
GLuint *ebo) noexcept {
|
ox::Span<GLuint> ebo) noexcept {
|
||||||
// don't worry, this memcpy gets optimized to something much more ideal
|
// don't worry, this memcpy gets optimized to something much more ideal
|
||||||
constexpr float xmod = 0.1f;
|
constexpr float xmod = 0.1f;
|
||||||
constexpr float ymod = 0.1f;
|
constexpr float ymod = 0.1f;
|
||||||
@ -138,12 +138,12 @@ static void setSpriteBufferObject(
|
|||||||
enabled, x + xmod, y + ymod, prif, R, textureRowf + 0, // top right
|
enabled, x + xmod, y + ymod, prif, R, textureRowf + 0, // top right
|
||||||
enabled, x, y + ymod, prif, L, textureRowf + 0, // top left
|
enabled, x, y + ymod, prif, L, textureRowf + 0, // top left
|
||||||
};
|
};
|
||||||
memcpy(vbo, vertices.data(), sizeof(vertices));
|
ox::spancpy<float>(vbo, vertices);
|
||||||
ox::Array<GLuint, SpriteVertexEboLength> const elms {
|
ox::Array<GLuint, SpriteVertexEboLength> const elms {
|
||||||
vi + 0, vi + 1, vi + 2,
|
vi + 0, vi + 1, vi + 2,
|
||||||
vi + 2, vi + 3, vi + 0,
|
vi + 2, vi + 3, vi + 0,
|
||||||
};
|
};
|
||||||
memcpy(ebo, elms.data(), sizeof(elms));
|
ox::spancpy<GLuint>(ebo, elms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setTileBufferObject(
|
static void setTileBufferObject(
|
||||||
@ -155,8 +155,8 @@ static void setTileBufferObject(
|
|||||||
float palOffset,
|
float palOffset,
|
||||||
bool flipX,
|
bool flipX,
|
||||||
bool flipY,
|
bool flipY,
|
||||||
float *vbo,
|
ox::Span<float> vbo,
|
||||||
GLuint *ebo) noexcept {
|
ox::Span<GLuint> ebo) noexcept {
|
||||||
// don't worry, this memcpy gets optimized to something much more ideal
|
// don't worry, this memcpy gets optimized to something much more ideal
|
||||||
constexpr float ymod = 0.1f;
|
constexpr float ymod = 0.1f;
|
||||||
constexpr float xmod = 0.1f;
|
constexpr float xmod = 0.1f;
|
||||||
@ -175,19 +175,30 @@ static void setTileBufferObject(
|
|||||||
x + xmod, y + ymod, prif, R, T, textureTileIdx, palOffset, // top right
|
x + xmod, y + ymod, prif, R, T, textureTileIdx, palOffset, // top right
|
||||||
x, y + ymod, prif, L, T, textureTileIdx, palOffset, // top left
|
x, y + ymod, prif, L, T, textureTileIdx, palOffset, // top left
|
||||||
};
|
};
|
||||||
memcpy(vbo, vertices.data(), sizeof(vertices));
|
ox::spancpy<float>(vbo, vertices);
|
||||||
ox::Array<GLuint, BgVertexEboLength> const elms {
|
ox::Array<GLuint, BgVertexEboLength> const elms {
|
||||||
vi + 0, vi + 1, vi + 2,
|
vi + 0, vi + 1, vi + 2,
|
||||||
vi + 2, vi + 3, vi + 0,
|
vi + 2, vi + 3, vi + 0,
|
||||||
};
|
};
|
||||||
memcpy(ebo, elms.data(), sizeof(elms));
|
ox::spancpy<GLuint>(ebo, elms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initSpriteBufferObjects(Context &ctx, glutils::BufferSet &bs) noexcept {
|
static void initSpriteBufferObjects(Context &ctx, glutils::BufferSet &bs) noexcept {
|
||||||
for (auto i = 0u; i < ctx.spriteCount; ++i) {
|
for (auto i = 0u; i < ctx.spriteCount; ++i) {
|
||||||
auto vbo = &bs.vertices[i * static_cast<std::size_t>(SpriteVertexVboLength)];
|
auto const vbo = ox::Span{bs.vertices}
|
||||||
auto ebo = &bs.elements[i * static_cast<std::size_t>(SpriteVertexEboLength)];
|
+ i * static_cast<std::size_t>(SpriteVertexVboLength);
|
||||||
setSpriteBufferObject(i * static_cast<uint_t>(SpriteVertexVboRows) * ctx.blocksPerSprite, 0, 0, 0, 0, false, 0, vbo, ebo);
|
auto const ebo = ox::Span{bs.elements}
|
||||||
|
+ i * static_cast<std::size_t>(SpriteVertexEboLength);
|
||||||
|
setSpriteBufferObject(
|
||||||
|
i * static_cast<uint_t>(SpriteVertexVboRows) * ctx.blocksPerSprite,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
vbo,
|
||||||
|
ebo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,8 +206,10 @@ static void initBackgroundBufferObjects(glutils::BufferSet &bs) noexcept {
|
|||||||
for (auto x = 0u; x < TileColumns; ++x) {
|
for (auto x = 0u; x < TileColumns; ++x) {
|
||||||
for (auto y = 0u; y < TileRows; ++y) {
|
for (auto y = 0u; y < TileRows; ++y) {
|
||||||
const auto i = bgVertexRow(x, y);
|
const auto i = bgVertexRow(x, y);
|
||||||
auto vbo = &bs.vertices[i * static_cast<std::size_t>(BgVertexVboLength)];
|
auto const vbo = ox::Span{bs.vertices}
|
||||||
auto ebo = &bs.elements[i * static_cast<std::size_t>(BgVertexEboLength)];
|
+ i * static_cast<std::size_t>(BgVertexVboLength);
|
||||||
|
auto const ebo = ox::Span{bs.elements}
|
||||||
|
+ i * static_cast<std::size_t>(BgVertexEboLength);
|
||||||
setTileBufferObject(
|
setTileBufferObject(
|
||||||
static_cast<uint_t>(i * BgVertexVboRows),
|
static_cast<uint_t>(i * BgVertexVboRows),
|
||||||
static_cast<float>(x),
|
static_cast<float>(x),
|
||||||
@ -421,8 +434,8 @@ static void setSprite(
|
|||||||
auto const eboIdx = eboBase + renderer::SpriteVertexEboLength * i;
|
auto const eboIdx = eboBase + renderer::SpriteVertexEboLength * i;
|
||||||
oxAssert(vboIdx < ctx.spriteBlocks.vertices.size(), "vbo overflow");
|
oxAssert(vboIdx < ctx.spriteBlocks.vertices.size(), "vbo overflow");
|
||||||
oxAssert(eboIdx < ctx.spriteBlocks.elements.size(), "ebo overflow");
|
oxAssert(eboIdx < ctx.spriteBlocks.elements.size(), "ebo overflow");
|
||||||
auto const vbo = &ctx.spriteBlocks.vertices[vboIdx];
|
auto const vbo = ox::Span{ctx.spriteBlocks.vertices} + vboIdx;
|
||||||
auto const ebo = &ctx.spriteBlocks.elements[eboIdx];
|
auto const ebo = ox::Span{ctx.spriteBlocks.elements} + eboIdx;
|
||||||
renderer::setSpriteBufferObject(
|
renderer::setSpriteBufferObject(
|
||||||
static_cast<uint_t>(vboIdx),
|
static_cast<uint_t>(vboIdx),
|
||||||
enabled,
|
enabled,
|
||||||
@ -556,7 +569,7 @@ static void copyPixels(
|
|||||||
CompactTileSheet const&ts,
|
CompactTileSheet const&ts,
|
||||||
ox::Span<uint32_t> dst,
|
ox::Span<uint32_t> dst,
|
||||||
size_t const srcPxIdx,
|
size_t const srcPxIdx,
|
||||||
size_t pxlCnt) noexcept {
|
size_t const pxlCnt) noexcept {
|
||||||
size_t idx{};
|
size_t idx{};
|
||||||
if (ts.bpp == 4) {
|
if (ts.bpp == 4) {
|
||||||
for (size_t i = 0; i < pxlCnt; i += 2) {
|
for (size_t i = 0; i < pxlCnt; i += 2) {
|
||||||
@ -573,6 +586,18 @@ static void copyPixels(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clearCbb(Context &ctx, unsigned const cbb) noexcept {
|
||||||
|
for (auto &v : ctx.cbbs[cbb].pixels) {
|
||||||
|
v = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearCbbs(Context &ctx) noexcept {
|
||||||
|
for (unsigned i = 0 ; i < ctx.cbbs.size(); ++i) {
|
||||||
|
clearCbb(ctx, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ox::Error loadBgTileSheet(
|
ox::Error loadBgTileSheet(
|
||||||
Context &ctx,
|
Context &ctx,
|
||||||
unsigned const cbb,
|
unsigned const cbb,
|
||||||
@ -656,8 +681,8 @@ void setBgTile(
|
|||||||
const auto x = static_cast<uint_t>(column);
|
const auto x = static_cast<uint_t>(column);
|
||||||
const auto i = renderer::bgVertexRow(x, y);
|
const auto i = renderer::bgVertexRow(x, y);
|
||||||
auto &cbb = ctx.cbbs[z];
|
auto &cbb = ctx.cbbs[z];
|
||||||
const auto vbo = &cbb.vertices[i * renderer::BgVertexVboLength];
|
const auto vbo = ox::Span{cbb.vertices} + i * renderer::BgVertexVboLength;
|
||||||
const auto ebo = &cbb.elements[i * renderer::BgVertexEboLength];
|
const auto ebo = ox::Span{cbb.elements} + i * renderer::BgVertexEboLength;
|
||||||
auto &bg = ctx.backgrounds[bgIdx];
|
auto &bg = ctx.backgrounds[bgIdx];
|
||||||
renderer::setTileBufferObject(
|
renderer::setTileBufferObject(
|
||||||
static_cast<uint_t>(i * renderer::BgVertexVboRows),
|
static_cast<uint_t>(i * renderer::BgVertexVboRows),
|
||||||
|
Loading…
Reference in New Issue
Block a user