Compare commits

...
5 Commits
Author SHA1 Message Date
tobid7 dac78d9c82 yet another memory debugger fix 2026-01-11 16:12:47 +01:00
tobid7 a16bce419d Add safe Memory Freeing
(cause in some cases random crashes could happen)
2026-01-10 12:58:04 +01:00
tobid7 bed24ff28a Add Memory debugger 2026-01-04 18:02:45 +01:00
tobid7 1acecd03ee Merge branch 'main' of github.com:tobid7/amethyst 2026-01-01 21:37:05 +01:00
tobid7 5e5907ed30 Rename to DrawFromAtlas 2025-12-31 10:30:20 +01:00
7 changed files with 159 additions and 23 deletions
+9 -9
View File
@@ -7,9 +7,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED true)
option(AMY_GOD_DEV "Turn this on if you think you are god" OFF) option(AMY_GOD_DEV "Turn this on if you think you are god" OFF)
# THis option should be disabled if you use STB_IMAGE in you main project # THis option should be disabled if you use STB_IMAGE in you main project
set(AMY_BUILD_STB_IMAGE 0) option(AMY_BUILD_STB_IMAGE ON)
set(AMY_BUILD_STB_TRUETYPE 1) option(AMY_BUILD_STB_TRUETYPE ON)
set(AMY_WITH_MPG123 "Include MP3 Support" CACHE BOOL 1)
add_subdirectory(vendor/libpicasso) add_subdirectory(vendor/libpicasso)
@@ -38,12 +37,13 @@ target_include_directories(${PROJECT_NAME} PRIVATE
) )
target_link_libraries(${PROJECT_NAME} PUBLIC pica::pica) target_link_libraries(${PROJECT_NAME} PUBLIC pica::pica)
target_link_libraries(${PROJECT_NAME} PUBLIC m z ctru citro3d mpg123) target_link_libraries(${PROJECT_NAME} PUBLIC m z ctru citro3d mpg123)
target_compile_definitions(${PROJECT_NAME} PUBLIC if(${AMY_BUILD_STB_IMAGE})
AMY_3DS target_compile_definitions(${PROJECT_NAME} PUBLIC AMY_STB_IMAGE)
AMY_STB_IMAGE=${AMY_BUILD_STB_IMAGE} endif()
AMY_STB_TT=${AMY_BUILD_STB_TRUETYPE} if(${AMY_BUILD_STB_TRUETYPE})
AMY_WITH_MPG123=${AMY_WITH_MPG123} target_compile_definitions(${PROJECT_NAME} PUBLIC AMY_STB_TT)
) endif()
target_compile_options(${PROJECT_NAME} PUBLIC -Wno-psabi) target_compile_options(${PROJECT_NAME} PUBLIC -Wno-psabi)
add_subdirectory(example) add_subdirectory(example)
+18 -1
View File
@@ -10,10 +10,27 @@
#include <amethyst/renderer.hpp> #include <amethyst/renderer.hpp>
#include <amethyst/texture.hpp> #include <amethyst/texture.hpp>
#include <amethyst/utils.hpp> #include <amethyst/utils.hpp>
#include <atomic>
namespace Amy { namespace Amy {
void RegisterCxxExceptionHandler(); void RegisterCxxExceptionHandler();
} void* Malloc(size_t size);
void Free(void* ptr);
namespace Memory {
struct MemMetrics {
std::atomic<ull> Allocated = 0; ///< Total Allocated Memory
std::atomic<ull> Current = 0; ///< Current Allocated Memory
std::atomic<ull> Deleted = 0; ///< Total Deleted Memory
std::atomic<ull> Allocations = 0; ///< Current Allocations count
/// @brief Gets the Currently Allocated Memory
ull CurrentlyAllocated() { return Current; }
};
ull GetTotalAllocated();
ull GetTotalFreed();
ull GetCurrent();
ull GetAllocationCount();
} // namespace Memory
} // namespace Amy
using Iron = Amy::Iron; using Iron = Amy::Iron;
using C3D = Amy::C3D; using C3D = Amy::C3D;
+5 -5
View File
@@ -122,12 +122,12 @@ class Iron {
void DrawSolid(); void DrawSolid();
void DrawTex(Texture::Ref tex) { pTex = tex; } void DrawTex(Texture::Ref tex) { pTex = tex; }
void DrawCutTex(fvec2 pos, fvec2 size, fvec4 cut_rect, void DrawFromAtlas(fvec2 pos, fvec2 size, fvec4 cut_rect,
ui color = 0xffffffff); ui color = 0xffffffff);
void DrawCutTex(fvec2 pos, fvec2 size, fvec4 cut_rect, Texture::Ref tex, void DrawFromAtlas(fvec2 pos, fvec2 size, fvec4 cut_rect, Texture::Ref tex,
ui color = 0xffffffff) { ui color = 0xffffffff) {
DrawTex(tex); DrawTex(tex);
DrawCutTex(pos, size, cut_rect, color); DrawFromAtlas(pos, size, cut_rect, color);
DrawSolid(); DrawSolid();
} }
void SetFont(Font::Ref fnt) { pCurrentFont = fnt; } void SetFont(Font::Ref fnt) { pCurrentFont = fnt; }
+120 -1
View File
@@ -1,6 +1,10 @@
#include <amethyst.hpp> #include <amethyst.hpp>
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <map>
#include <vector>
#define TRACK_NEW_DELETE
#ifdef AMY_3DS #ifdef AMY_3DS
#include <3ds.h> #include <3ds.h>
@@ -11,7 +15,7 @@ void NpiD7CxxExceptionHandler() {
std::cout << "[C++ Error Handler]" << std::endl; std::cout << "[C++ Error Handler]" << std::endl;
try { try {
std::rethrow_exception(std::current_exception()); std::rethrow_exception(std::current_exception());
} catch (const std::exception& e) { } catch (const std::exception &e) {
std::cout << "\n\n" << e.what() << std::endl; std::cout << "\n\n" << e.what() << std::endl;
} }
aptSetHomeAllowed(false); aptSetHomeAllowed(false);
@@ -26,6 +30,103 @@ void NpiD7CxxExceptionHandler() {
} }
#endif #endif
static Amy::Memory::MemMetrics metrics;
#ifdef TRACK_NEW_DELETE
constexpr uint32_t MemDBGMagic = 0x774733d7;
struct MemDBGHeader {
MemDBGHeader(size_t s) {
Magic = MemDBGMagic;
Size = s;
}
uint32_t Magic = MemDBGMagic;
size_t Size = 0;
};
void *MemDBGAllocate(size_t size) {
void *ptr = malloc(size + sizeof(MemDBGHeader));
if (!ptr) return reinterpret_cast<void *>(ptr);
MemDBGHeader *hdr = reinterpret_cast<MemDBGHeader *>(ptr);
hdr->Magic = MemDBGMagic;
hdr->Size = size;
metrics.Allocated.fetch_add(hdr->Size, std::memory_order_relaxed);
metrics.Current.fetch_add(hdr->Size, std::memory_order_relaxed);
metrics.Allocations.fetch_add(1, std::memory_order_relaxed);
return reinterpret_cast<void *>(hdr + 1);
}
void MemDBGFree(void *ptr) {
if (!ptr) return;
MemDBGHeader *hdr = reinterpret_cast<MemDBGHeader *>(ptr) - 1;
if (hdr->Magic == MemDBGMagic) {
hdr->Magic = 0;
size_t szs = hdr->Size;
metrics.Deleted.fetch_add(szs, std::memory_order_relaxed);
metrics.Current.fetch_sub(szs, std::memory_order_relaxed);
metrics.Allocations.fetch_sub(1, std::memory_order_relaxed);
free(reinterpret_cast<void *>(hdr));
} else {
std::abort();
}
}
void *operator new(size_t size) { return MemDBGAllocate(size); }
void *operator new[](size_t size) { return MemDBGAllocate(size); }
void operator delete(void *ptr) noexcept { MemDBGFree(ptr); }
void operator delete(void *ptr, size_t) noexcept { MemDBGFree(ptr); }
void operator delete[](void *ptr) noexcept { MemDBGFree(ptr); }
void operator delete[](void *ptr, size_t) noexcept { MemDBGFree(ptr); }
void *operator new(size_t size, const std::nothrow_t &) noexcept {
return MemDBGAllocate(size);
}
void *operator new[](size_t size, const std::nothrow_t &) noexcept {
return MemDBGAllocate(size);
}
void operator delete(void *ptr, const std::nothrow_t &) noexcept {
MemDBGFree(ptr);
}
void operator delete[](void *ptr, const std::nothrow_t &) noexcept {
MemDBGFree(ptr);
}
void *operator new(size_t size, std::align_val_t) {
return MemDBGAllocate(size);
}
void *operator new[](size_t size, std::align_val_t) {
return MemDBGAllocate(size);
}
void operator delete(void *ptr, std::align_val_t) noexcept { MemDBGFree(ptr); }
void operator delete[](void *ptr, std::align_val_t) noexcept {
MemDBGFree(ptr);
}
void *operator new(size_t size, std::align_val_t,
const std::nothrow_t &) noexcept {
return MemDBGAllocate(size);
}
void *operator new[](size_t size, std::align_val_t,
const std::nothrow_t &) noexcept {
return MemDBGAllocate(size);
}
void operator delete(void *ptr, size_t, std::align_val_t) noexcept {
MemDBGFree(ptr);
}
void operator delete[](void *ptr, size_t, std::align_val_t) noexcept {
MemDBGFree(ptr);
}
void operator delete(void *ptr, size_t, std::align_val_t,
const std::nothrow_t &) noexcept {
MemDBGFree(ptr);
}
void operator delete[](void *ptr, size_t, std::align_val_t,
const std::nothrow_t &) noexcept {
MemDBGFree(ptr);
}
#endif
namespace Amy { namespace Amy {
void RegisterCxxExceptionHandler() { void RegisterCxxExceptionHandler() {
@@ -33,4 +134,22 @@ void RegisterCxxExceptionHandler() {
std::set_terminate(NpiD7CxxExceptionHandler); std::set_terminate(NpiD7CxxExceptionHandler);
#endif #endif
} }
void *Malloc(size_t size) {
#ifdef TRACK_NEW_DELETE
return MemDBGAllocate(size);
#else
return malloc(size);
#endif
}
void Free(void *ptr) {
#ifdef TRACK_NEW_DELETE
MemDBGFree(ptr);
#else
free(ptr);
#endif
}
ull Memory::GetTotalAllocated() { return metrics.Allocated; }
ull Memory::GetTotalFreed() { return metrics.Deleted; }
ull Memory::GetCurrent() { return metrics.CurrentlyAllocated(); }
ull Memory::GetAllocationCount() { return metrics.Allocations; }
} // namespace Amy } // namespace Amy
+1 -1
View File
@@ -4,7 +4,7 @@
// Only include stb Code if we need it // Only include stb Code if we need it
// Otherwise we just build the header // Otherwise we just build the header
#if AMY_STB_IMAGE == 1 #ifdef AMY_STB_IMAGE
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#endif #endif
#include <stb_image.h> #include <stb_image.h>
+2 -2
View File
@@ -209,8 +209,8 @@ void Iron::Drawlist::DrawCircleFilled(const fvec2& center, float rad, ui color,
PathFill(color); PathFill(color);
} }
void Iron::Drawlist::DrawCutTex(fvec2 pos, fvec2 size, fvec4 cut_rect, void Iron::Drawlist::DrawFromAtlas(fvec2 pos, fvec2 size, fvec4 cut_rect,
ui color) { ui color) {
auto r = Iron::PrimRect(pos, size); auto r = Iron::PrimRect(pos, size);
auto cmd = NewCommand(); auto cmd = NewCommand();
auto uv = cut_rect / fvec4(pTex->Size(), pTex->Size()); auto uv = cut_rect / fvec4(pTex->Size(), pTex->Size());
+2 -2
View File
@@ -3,9 +3,9 @@
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#if AMY_STB_TT == 1 //#ifdef AMY_STB_TT
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
#endif //#endif
#include <stb_truetype.h> #include <stb_truetype.h>
namespace Amy { namespace Amy {