Compare commits
1 Commits
f40d5515f9
...
david/clar
| Author | SHA1 | Date | |
|---|---|---|---|
| e07cfc8ec3 |
163
deps/ox/ox-docs.md
vendored
163
deps/ox/ox-docs.md
vendored
@@ -181,169 +181,6 @@ variant for creating a non-const value.
|
||||
|
||||
* ```OX_REQUIRE_M``` - OX_REQUIRE Mutable
|
||||
|
||||
### Ox String Types
|
||||
|
||||
Ox has six different major string types.
|
||||
These types are divided into two categories: store types and view types.
|
||||
|
||||
String stores maintain a copy of the string data, whereas view types only
|
||||
maintain a reference to the data.
|
||||
Views should be used where you otherwise might use a const reference to a
|
||||
string store type.
|
||||
|
||||
#### String Store Types
|
||||
|
||||
##### String
|
||||
|
||||
```ox::String```, or really ```ox::BasicString```, is Ox's version of
|
||||
```std::string```.
|
||||
Like ```std::string```, ```String``` allocates to store the string data.
|
||||
Also like ```std::string```, ```String``` allows for small string
|
||||
optimization for strings under 8 bytes.
|
||||
Unlike ```std::string```, the template that ```String``` is based on,
|
||||
```BasicString```, takes a parameter that allows adjusting to different size
|
||||
small string buffers.
|
||||
```ox::String``` is an alias to ```ox::BasicString<8>```.
|
||||
|
||||
```cpp
|
||||
// s can hold up to 100 bytes, plus one for a null terminator before allocating
|
||||
ox::BasicString<100> s;
|
||||
```
|
||||
Also ulike ```std::string```, ```String``` has an explicit C-string conversion
|
||||
constructor.
|
||||
This prevents accidental instantiations of ```String```.
|
||||
|
||||
Consider the following:
|
||||
|
||||
```cpp
|
||||
void fStd(std::string const&);
|
||||
void fOx(ox::String const&);
|
||||
|
||||
int main() {
|
||||
// implicit and silent instantiation of std::string, which includes an
|
||||
// allocation
|
||||
fStd("123456789");
|
||||
// Will fail to compile:
|
||||
fOx("123456789");
|
||||
// But explicit String instantiation will work:
|
||||
fOx(ox::String{"123456789"});
|
||||
}
|
||||
```
|
||||
|
||||
##### IString
|
||||
|
||||
```IString```, or "inline string", is like ```BasicString```, but it will cut
|
||||
off strings that exceed that limit.
|
||||
|
||||
```cpp
|
||||
ox::IString<5> s; // s can hold up to 5 characters, plus a null terminator
|
||||
s = "12345"; // valid
|
||||
s = "123456"; // will compile and run, but will get cut off at '5'
|
||||
```
|
||||
|
||||
##### StringParam
|
||||
|
||||
```StringParam``` is a weird type.
|
||||
Because ```String::String(const char*)``` is explicit, it becomes a pain for
|
||||
functions to take ```String```s.
|
||||
|
||||
```cpp
|
||||
struct Type {
|
||||
ox::String m_s;
|
||||
explicit Type(ox::String p): m_s(std::move(p)) {
|
||||
}
|
||||
};
|
||||
|
||||
void f() {
|
||||
ox::String s{"asdf"};
|
||||
Type t1{"asdf"}; // invalid - will not compile
|
||||
Type t2{s}; // invalid - will not compile
|
||||
Type t3{std::move(s)}; // valid
|
||||
Type t4{ox::String{"asdf"}}; // valid
|
||||
}
|
||||
```
|
||||
|
||||
```StringParam``` has implicit conversion constructors, and will appropriately
|
||||
move from r-value ```String```s.
|
||||
It will create a ```String``` if not passed ownership of an existing
|
||||
```String```.
|
||||
|
||||
```StringParam``` can access the string as a view through the ```view()```
|
||||
function, and the ```String``` inside can be accessed by moving from the
|
||||
```StringParams```.
|
||||
|
||||
```cpp
|
||||
struct Type {
|
||||
ox::String m_s;
|
||||
explicit Type(ox::StringParam p): m_s(std::move(p)) {
|
||||
}
|
||||
};
|
||||
|
||||
void f() {
|
||||
ox::String s{"asdf"};
|
||||
Type t1{"asdf"}; // valid
|
||||
Type t2{s}; // valid
|
||||
Type t3{std::move(s)}; // valid
|
||||
}
|
||||
```
|
||||
|
||||
#### String View Types
|
||||
|
||||
##### StringView
|
||||
|
||||
```ox::StringView``` is Ox's version of ```std::string_view```.
|
||||
```StringView``` contains a pointer to a string, along with its size.
|
||||
|
||||
This should be the normal type taken when a function needs a string that will
|
||||
exist until it returns.
|
||||
|
||||
##### CStringView
|
||||
|
||||
```CStringView``` is like ```StringView```, but it comes with the promise that
|
||||
the string ends with a null terminator.
|
||||
Accordingly, it has a ```c_str()``` function in addition to the ```data()```
|
||||
function that ```StringView``` has.
|
||||
|
||||
```CStringView``` should be used when wrapping a C API that only takes C
|
||||
strings.
|
||||
|
||||
##### StringLiteral
|
||||
|
||||
```StringLiteral``` is a string view type, but it kind of straddles the line
|
||||
between view and store types.
|
||||
Creating a ```StringLiteral``` is a promise that you are passing a string
|
||||
literal into the constructor.
|
||||
This means you can treat it like a store, that can be safely used as a copy of
|
||||
the data.
|
||||
Functions that take ```StringLiteral```s are allowed to assume that the data
|
||||
will have no lifetime concerns and hold onto it without any need to make a
|
||||
copy.
|
||||
It has a consteval constructor to enforce the promise that it is a compile time
|
||||
string.
|
||||
|
||||
```cpp
|
||||
void f(ox::StringLiteral const&);
|
||||
|
||||
int main() {
|
||||
f("123456789"); // valid
|
||||
f(ox::String{"123456789"}.c_str()); // invalid - will not compile
|
||||
}
|
||||
```
|
||||
|
||||
#### Other Variants
|
||||
|
||||
There are a few convenience aliases as well.
|
||||
|
||||
* StringCR = String const&
|
||||
* StringViewCR = StringView const&
|
||||
* CStringViewCR = CStringView const&
|
||||
|
||||
String views do not generally need const references, but it does make debugging
|
||||
easier, as we can skip the constructor call if a string view already exists.
|
||||
|
||||
These kind of aliases probably should not exist for most types, but strings are
|
||||
fundamental and ease of use is desirable.
|
||||
|
||||
### Logging and Output
|
||||
|
||||
Ox provides for logging and debug prints via the ```oxTrace```, ```oxDebug```, and ```oxError``` macros.
|
||||
|
||||
2
deps/ox/src/ox/clargs/clargs.cpp
vendored
2
deps/ox/src/ox/clargs/clargs.cpp
vendored
@@ -40,7 +40,7 @@ ClArgs::ClArgs(ox::SpanView<const char*> args) noexcept {
|
||||
}
|
||||
|
||||
bool ClArgs::getBool(ox::StringViewCR arg, bool defaultValue) const noexcept {
|
||||
auto const [value, err] = m_ints.at(arg);
|
||||
auto const [value, err] = m_bools.at(arg);
|
||||
return !err ? *value : defaultValue;
|
||||
}
|
||||
|
||||
|
||||
8
deps/ox/src/ox/std/vector.hpp
vendored
8
deps/ox/src/ox/std/vector.hpp
vendored
@@ -247,8 +247,6 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
||||
|
||||
constexpr void resize(std::size_t size) noexcept(useNoexcept);
|
||||
|
||||
constexpr void reserveResize(std::size_t size) noexcept(useNoexcept);
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr T *data() noexcept {
|
||||
return m_items;
|
||||
@@ -519,12 +517,6 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::resize(std::size_t size) n
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr void Vector<T, SmallVectorSize, Allocator>::reserveResize(std::size_t const size) noexcept(useNoexcept) {
|
||||
reserve(size);
|
||||
resize(size);
|
||||
}
|
||||
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr bool Vector<T, SmallVectorSize, Allocator>::contains(MaybeView_t<T> const&v) const noexcept {
|
||||
for (std::size_t i = 0; i < m_size; ++i) {
|
||||
|
||||
20
deps/teagba/include/teagba/addresses.hpp
vendored
20
deps/teagba/include/teagba/addresses.hpp
vendored
@@ -99,23 +99,23 @@ volatile OffsetPair ®BgOfs(auto const bgIdx) noexcept {
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// Memory Addresses
|
||||
|
||||
#define MEM_EWRAM (*(reinterpret_cast<ox::Array<uint16_t, 0x0203'FFFF - 0x0200'0000>*>(0x0200'0000)))
|
||||
#define MEM_EWRAM (*reinterpret_cast<ox::Array<uint16_t, 0x0203'FFFF - 0x0200'0000>*>(0x0200'0000))
|
||||
|
||||
#define MEM_IWRAM (*(reinterpret_cast<ox::Array<uint8_t, 0x0300'7FFF - 0x0300'0000>*>(0x0300'0000)))
|
||||
#define MEM_IWRAM (*reinterpret_cast<ox::Array<uint8_t, 0x0300'7FFF - 0x0300'0000>*>(0x0300'0000))
|
||||
|
||||
#define REG_BLNDCTL (*reinterpret_cast<uint16_t*>(0x0400'0050))
|
||||
|
||||
using Palette = ox::Array<uint16_t, 128>;
|
||||
#define MEM_BG_PALETTE (*(reinterpret_cast<::Palette*>(0x0500'0000)))
|
||||
#define MEM_SPRITE_PALETTE (*(reinterpret_cast<::Palette*>(0x0500'0200)))
|
||||
#define MEM_BG_PALETTE (*reinterpret_cast<::Palette*>(0x0500'0000))
|
||||
#define MEM_SPRITE_PALETTE (*reinterpret_cast<::Palette*>(0x0500'0200))
|
||||
|
||||
using BgMapTile = ox::Array<uint16_t, 8192>;
|
||||
#define MEM_BG_TILES (*(reinterpret_cast<ox::Array<BgMapTile, 4>*>(0x0600'0000)))
|
||||
#define MEM_BG_MAP (*(reinterpret_cast<ox::Array<BgMapTile, 4>*>(0x0600'e000)))
|
||||
#define MEM_BG_TILES (*reinterpret_cast<ox::Array<BgMapTile, 4>*>(0x0600'0000))
|
||||
#define MEM_BG_MAP (*reinterpret_cast<ox::Array<BgMapTile, 4>*>(0x0600'e000))
|
||||
|
||||
#define MEM_SPRITE_TILES (*(reinterpret_cast<ox::Array<uint16_t, 32 * ox::units::KB>*>(0x0601'0000)))
|
||||
#define MEM_OAM (*(reinterpret_cast<ox::Array<uint64_t, 64>*>(0x0700'0000)))
|
||||
#define MEM_SPRITE_TILES (*reinterpret_cast<ox::Array<uint16_t, 32 * ox::units::KB>*>(0x0601'0000))
|
||||
#define MEM_OAM (*reinterpret_cast<ox::Array<uint64_t, 64>*>(0x0700'0000))
|
||||
|
||||
#define MEM_ROM (*(reinterpret_cast<ox::Array<char, 32 * ox::units::MB>*>(0x0700'0000)))
|
||||
#define MEM_ROM (*reinterpret_cast<ox::Array<char, 32 * ox::units::MB>*>(0x0700'0000))
|
||||
|
||||
#define MEM_SRAM (*(reinterpret_cast<ox::Array<char, 64 * ox::units::KB>*>(0x0e00'0000)))
|
||||
#define MEM_SRAM (*reinterpret_cast<ox::Array<char, 64 * ox::units::KB>*>(0x0e00'0000))
|
||||
|
||||
2
deps/teagba/include/teagba/gfx.hpp
vendored
2
deps/teagba/include/teagba/gfx.hpp
vendored
@@ -43,4 +43,6 @@ void applySpriteUpdates() noexcept;
|
||||
|
||||
void setBgOffset(uint16_t bg, int16_t x, int16_t y) noexcept;
|
||||
|
||||
void scrollBgOffset(uint16_t bg, int16_t x, int16_t y) noexcept;
|
||||
|
||||
}
|
||||
|
||||
8
deps/teagba/src/gfx.cpp
vendored
8
deps/teagba/src/gfx.cpp
vendored
@@ -18,7 +18,7 @@ GbaSpriteAttrUpdate &spriteAttr(size_t const i) noexcept {
|
||||
|
||||
void addSpriteUpdate(GbaSpriteAttrUpdate const &upd) noexcept {
|
||||
const auto ie = REG_IE; // disable vblank interrupt handler
|
||||
REG_IE = REG_IE & static_cast<uint16_t>(~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;
|
||||
REG_IE = ie; // enable vblank interrupt handler
|
||||
}
|
||||
@@ -35,4 +35,10 @@ void setBgOffset(uint16_t const bg, int16_t const x, int16_t const y) noexcept {
|
||||
o.y = y;
|
||||
}
|
||||
|
||||
void scrollBgOffset(uint16_t const bg, int16_t const x, int16_t const y) noexcept {
|
||||
auto &o = regBgOfs(bg);
|
||||
o.x = o.x + x;
|
||||
o.y = o.y + y;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,15 +23,17 @@ struct BgCbbData {
|
||||
unsigned bpp = 4;
|
||||
};
|
||||
|
||||
class Context final {
|
||||
class Context {
|
||||
|
||||
public:
|
||||
turbine::Context &turbineCtx;
|
||||
ox::Array<BgCbbData, 4> cbbData;
|
||||
ox::Array<OffsetPair, 4> bgOffsets;
|
||||
|
||||
explicit Context(turbine::Context &tctx) noexcept: turbineCtx{tctx} {}
|
||||
Context(Context &other) noexcept = delete;
|
||||
Context(Context const &other) noexcept = delete;
|
||||
Context(Context const &&other) noexcept = delete;
|
||||
virtual ~Context() noexcept = default;
|
||||
|
||||
};
|
||||
|
||||
@@ -293,16 +295,12 @@ void setBgPriority(Context&, uint_t const bgIdx, uint_t const priority) noexcept
|
||||
bgCtl = (bgCtl & 0b1111'1111'1111'1100u) | (priority & 0b11);
|
||||
}
|
||||
|
||||
void setBgOffset(Context &ctx, uint16_t const bg, int16_t const x, int16_t const y) noexcept {
|
||||
ctx.bgOffsets[bg] = {.x = x, .y = y};
|
||||
void setBgOffset(Context&, uint16_t const bg, int16_t const x, int16_t const y) noexcept {
|
||||
teagba::setBgOffset(bg, x, y);
|
||||
}
|
||||
|
||||
void scrollBgOffset(Context &ctx, uint16_t const bg, int16_t const x, int16_t const y) noexcept {
|
||||
auto &o = ctx.bgOffsets[bg];
|
||||
o.x += x;
|
||||
o.y += y;
|
||||
teagba::setBgOffset(bg, o.x, o.y);
|
||||
void scrollBgOffset(Context&, uint16_t const bg, int16_t const x, int16_t const y) noexcept {
|
||||
teagba::scrollBgOffset(bg, x, y);
|
||||
}
|
||||
|
||||
void hideSprite(Context&, unsigned const idx) noexcept {
|
||||
|
||||
@@ -87,7 +87,9 @@ class Context {
|
||||
blocksPerSprite{params.glBlocksPerSprite} {
|
||||
}
|
||||
Context(Context const&) = delete;
|
||||
Context(Context&&) = delete;
|
||||
Context &operator=(Context const&) = delete;
|
||||
Context &operator=(Context&&) = delete;
|
||||
~Context() noexcept {
|
||||
turbine::gl::removeDrawer(turbineCtx, &drawer);
|
||||
}
|
||||
@@ -111,7 +113,7 @@ namespace renderer {
|
||||
static constexpr auto Scale = 1;
|
||||
static constexpr auto PriorityScale = 0.01f;
|
||||
|
||||
static constexpr ox::StringLiteral bgvshadTmpl{R"glsl(
|
||||
static constexpr ox::CStringView bgvshadTmpl = R"glsl(
|
||||
{}
|
||||
in vec2 vTexCoord;
|
||||
in vec3 vPosition;
|
||||
@@ -133,9 +135,9 @@ static constexpr ox::StringLiteral bgvshadTmpl{R"glsl(
|
||||
vTexCoord.x,
|
||||
vTexCoord.y * vTileHeight + vTileIdx * vTileHeight);
|
||||
fPalOffset = vPalOffset;
|
||||
})glsl"};
|
||||
})glsl";
|
||||
|
||||
static constexpr ox::StringLiteral bgfshadTmpl{R"glsl(
|
||||
static constexpr ox::CStringView bgfshadTmpl = R"glsl(
|
||||
{}
|
||||
out vec4 outColor;
|
||||
in float fPalOffset;
|
||||
@@ -149,9 +151,9 @@ static constexpr ox::StringLiteral bgfshadTmpl{R"glsl(
|
||||
if (outColor.a == 0) {
|
||||
discard;
|
||||
}
|
||||
})glsl"};
|
||||
})glsl";
|
||||
|
||||
static constexpr ox::StringLiteral spritevshadTmpl{R"glsl(
|
||||
static constexpr ox::CStringView spritevshadTmpl = R"glsl(
|
||||
{}
|
||||
in float vEnabled;
|
||||
in vec3 vPosition;
|
||||
@@ -168,9 +170,9 @@ static constexpr ox::StringLiteral spritevshadTmpl{R"glsl(
|
||||
vPosition.z - 0.004,
|
||||
1.0) * vEnabled;
|
||||
fTexCoord = vTexCoord * vec2(1, vTileHeight);
|
||||
})glsl"};
|
||||
})glsl";
|
||||
|
||||
static constexpr ox::StringLiteral spritefshadTmpl{R"glsl(
|
||||
static constexpr ox::CStringView spritefshadTmpl = R"glsl(
|
||||
{}
|
||||
out vec4 outColor;
|
||||
in vec2 fTexCoord;
|
||||
@@ -183,7 +185,7 @@ static constexpr ox::StringLiteral spritefshadTmpl{R"glsl(
|
||||
if (outColor.a == 0) {
|
||||
discard;
|
||||
}
|
||||
})glsl"};
|
||||
})glsl";
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto bgVertexRow(uint_t const x, uint_t const y) noexcept {
|
||||
@@ -839,12 +841,6 @@ void setBgPriority(Context &ctx, uint_t const bgIdx, uint_t const priority) noex
|
||||
bg.priority = static_cast<float>(priority & 0b11);
|
||||
}
|
||||
|
||||
void setBgOffset(Context&, uint16_t const, int16_t const, int16_t const) noexcept {
|
||||
}
|
||||
|
||||
void scrollBgOffset(Context&, uint16_t const, int16_t const, int16_t const) noexcept {
|
||||
}
|
||||
|
||||
void hideSprite(Context &ctx, uint_t const idx) noexcept {
|
||||
auto &s = ctx.spriteStates[idx];
|
||||
s.enabled = false;
|
||||
|
||||
@@ -69,7 +69,7 @@ void TileSheetGrid::update(ox::Vec2 const &paneSize, TileSheet::SubSheet const &
|
||||
glBindVertexArray(m_bufferSet.vao);
|
||||
setBufferObjects(paneSize, subsheet);
|
||||
glutils::sendVbo(m_bufferSet);
|
||||
//glutils::sendEbo(m_bufferSet);
|
||||
glutils::sendEbo(m_bufferSet);
|
||||
}
|
||||
|
||||
void TileSheetGrid::setBufferObject(
|
||||
@@ -89,6 +89,7 @@ void TileSheetGrid::setBufferObject(
|
||||
|
||||
void TileSheetGrid::setBufferObjects(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept {
|
||||
if (subsheet.columns < 1 || subsheet.rows < 1) {
|
||||
m_bufferSet.elements.clear();
|
||||
m_bufferSet.vertices.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -285,11 +285,11 @@ static void handleKeyPress(Context &ctx, int const key, bool const down) noexcep
|
||||
map[GLFW_KEY_ESCAPE] = Key::Escape;
|
||||
return map;
|
||||
}();
|
||||
auto const eventHandler = keyEventHandler(ctx);
|
||||
auto const keyIdx = static_cast<std::size_t>(key);
|
||||
if (keyIdx < keyMap.size()) {
|
||||
auto const k = keyMap[keyIdx];
|
||||
setKeyDownStatus(ctx, k, down);
|
||||
auto const eventHandler = keyEventHandler(ctx);
|
||||
if (eventHandler) {
|
||||
eventHandler(ctx, k, down);
|
||||
}
|
||||
@@ -306,9 +306,7 @@ static void handleGlfwMouseButtonEvent(
|
||||
int) noexcept {
|
||||
auto &ctx = *static_cast<Context*>(glfwGetWindowUserPointer(window));
|
||||
setMandatoryRefreshPeriod(ctx, ticksMs(ctx) + config::MandatoryRefreshPeriod);
|
||||
if (ctx.mouseButtonEventHandler) {
|
||||
ctx.mouseButtonEventHandler(ctx, btn, action == 1);
|
||||
}
|
||||
ctx.mouseButtonEventHandler(ctx, btn, action == 1);
|
||||
}
|
||||
|
||||
static void handleGlfwKeyEvent(GLFWwindow *window, int const key, int, int const action, int) noexcept {
|
||||
|
||||
Reference in New Issue
Block a user