From 6b48ba070c3c26362e8cfbf4eb404c68d6f8b46c Mon Sep 17 00:00:00 2001 From: Tobi Date: Fri, 18 Nov 2022 20:57:05 +0100 Subject: [PATCH] RenderD7 0.8.2 --- .vscode/c_cpp_properties.json | 16 ++ .vscode/settings.json | 26 ++- Makefile | 2 +- include/renderd7/FileSystem.hpp | 98 +-------- include/renderd7/Image.hpp | 1 + include/renderd7/renderd7.hpp | 5 +- source/FileSystem.cpp | 340 +------------------------------- source/Image.cpp | 90 ++++++++- source/stb.cpp | 2 + 9 files changed, 150 insertions(+), 430 deletions(-) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 source/stb.cpp diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..c6717e9 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "3DS | Windows", + "includePath": [ + "${workspaceFolder}/**", + "C:/devkitpro/libctru/include/**", + "C:/devkitpro/devkitARM/include/**", + "C:/devkitpro/devkitARM/arm-none-eabi/include/**", + "C:/devkitpro/portlibs/3ds/include/**" + + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 401f997..4b97e7f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -62,6 +62,30 @@ "concepts": "cpp", "numbers": "cpp", "filesystem": "cpp", - "xstring": "cpp" + "xstring": "cpp", + "charconv": "cpp", + "format": "cpp", + "ios": "cpp", + "list": "cpp", + "locale": "cpp", + "mutex": "cpp", + "stack": "cpp", + "stop_token": "cpp", + "thread": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xstddef": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp" } } \ No newline at end of file diff --git a/Makefile b/Makefile index 1df2b1d..7fc308d 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ include $(DEVKITARM)/3ds_rules export renderd7_MAJOR := 0 export renderd7_MINOR := 8 -export renderd7_PATCH := 1 +export renderd7_PATCH := 2 VERSION := $(renderd7_MAJOR).$(renderd7_MINOR).$(renderd7_PATCH) diff --git a/include/renderd7/FileSystem.hpp b/include/renderd7/FileSystem.hpp index 86bfe5d..9c725cd 100644 --- a/include/renderd7/FileSystem.hpp +++ b/include/renderd7/FileSystem.hpp @@ -4,102 +4,14 @@ #include #include -#include - -#define RD7_FSYS_GETINFO(path) \ - ({ \ - RenderD7::FileSystem::Info inf; \ - RenderD7::FileSystem::GetInfo(path, inf); \ - inf; \ - }) - namespace RenderD7 { namespace FileSystem { -static constexpr auto MAX_STAMP = 0x20000000000000LL; - -enum FileMode { FileMode_Open, FileMode_Read, FileMode_Write, FileMode_Closed }; - -enum FileType { - FileType_File, - FileType_Directory, - FileType_SymLink, - FileType_Other +struct Entry { + std::string path; + std::string name; + bool dir = false; }; -struct File { - PHYSFS_file *handle; - FileMode mode; - - File() { - this->handle = nullptr; - this->mode = FileMode_Closed; - } - - int64_t GetSize() { - if (this->handle == nullptr) - return 0; - - return (int64_t)PHYSFS_fileLength(this->handle); - } -}; - -struct Info { - int64_t size; - int64_t mod_time; - FileType type; -}; - -int Init(const char *argv); - -void Initialize(); - -/* -** mounts a specific directory for physfs to search in -** this is typically a main directory -*/ -bool SetSource(const char *source); - -/* -** mounts a specific directory as a "save" directory -** if appended, it will be added to the search path -*/ -bool SetIdentity(const char *name, bool append); - -static std::string savePath; - -/* gets the last physfs error */ -const char *GetPhysfsError(); - -/* strips any duplicate slashes */ -std::string Normalize(const std::string &input); - -/* gets the user directory from physfs */ -std::string GetUserDirectory(); - -/* gets the save directory */ -std::string GetSaveDirectory(); - -/* sets up the writing directory for physfs */ -bool SetupWriteDirectory(); - -/* gets a list of files in a directory */ -void GetDirectoryItems(const char *directory, std::vector &items); - -/* gets the size, mod_time, and type of a file */ -bool GetInfo(const char *filename, Info &info); - -/* creates a new directory */ -bool CreateDirectory(const char *name); - -bool CloseFile(File &file); - -/* creates a new file */ -bool OpenFile(File &file, const char *name, FileMode mode); - -/* writes to a file */ -bool WriteFile(File &file, const void *data, int64_t size); - -/* reads a file's content */ -int64_t ReadFile(File &file, void *destination, int64_t size); +std::vector GetDirContent(std::string path); } // namespace FileSystem } // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/Image.hpp b/include/renderd7/Image.hpp index 08f038b..2a11d72 100644 --- a/include/renderd7/Image.hpp +++ b/include/renderd7/Image.hpp @@ -27,6 +27,7 @@ public: /// \param buffer the frame buffer void LoadPFromBuffer(const std::vector &buffer); void LoadFromBitmap(BMP bitmap); + void LoadJpg(std::string path); /// Draw the Image directly /// \param x The x position /// \param y the y position diff --git a/include/renderd7/renderd7.hpp b/include/renderd7/renderd7.hpp index 4d972bd..f1bc8e7 100644 --- a/include/renderd7/renderd7.hpp +++ b/include/renderd7/renderd7.hpp @@ -46,9 +46,10 @@ extern "C" { #include } -#define RENDERD7VSTRING "0.8.1" +#define RENDERD7VSTRING "0.8.2" #define CHANGELOG \ - "0.8.1: Add abillity to Get Stdout as string to render it to the " \ + "0.8.2: Fix a lot of Stuff and add c++17 based filesystem class.\n0.8.1: " \ + "Add abillity to Get Stdout as string to render it to the " \ "screen.\n0.8.0: Implement BitmapPrinter\n0.7.3: Implement Over Render " \ "Overlay " \ "Framework\n0.7.2: Implement MT to csv file saving. Add RGB2HEX. \n0.7.1: " \ diff --git a/source/FileSystem.cpp b/source/FileSystem.cpp index 2b0193c..63dbc87 100644 --- a/source/FileSystem.cpp +++ b/source/FileSystem.cpp @@ -5,340 +5,16 @@ #include #include #include +#include -const char *RenderD7::FileSystem::GetPhysfsError() { - return PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()); -} +#include -std::string RenderD7::FileSystem::Normalize(const std::string &input) { - std::string out; - bool seenSep = false, isSep = false; - - for (size_t i = 0; i < input.size(); ++i) { - isSep = (input[i] == '/'); - - if (!isSep || !seenSep) - out += input[i]; - - seenSep = isSep; +std::vector RenderD7::FileSystem::GetDirContent(std::string path) +{ + std::vector res; + for(const auto& entry : std::filesystem::directory_iterator(std::filesystem::path(path))) + { + res.push_back({entry.path().string(), GetFileName(entry.path().string()), entry.is_directory()}); } - - return out; -} - -void RenderD7::FileSystem::Initialize() { RenderD7::FileSystem::savePath = ""; } - -int RenderD7::FileSystem::Init(const char *argv) { - int res = PHYSFS_init(argv); - if (res != 1) { - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - } - return res; -} - -bool RenderD7::FileSystem::SetSource(const char *source) { - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - std::string searchPath = source; - if (!PHYSFS_mount(searchPath.c_str(), NULL, 1)) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - return true; -} - -bool RenderD7::FileSystem::SetIdentity(const char *name, bool append) { - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - std::string old = RenderD7::FileSystem::savePath; - - RenderD7::FileSystem::savePath = RenderD7::FileSystem::Normalize( - RenderD7::FileSystem::GetUserDirectory() + "/save/" + name); - printf("Save Path set to %s\n", savePath.c_str()); - - if (!old.empty()) - PHYSFS_unmount(old.c_str()); - - int success = PHYSFS_mount(savePath.c_str(), NULL, append); - printf("Save Path mounted %d\n", success); - - PHYSFS_setWriteDir(nullptr); - - return true; -} - -std::string RenderD7::FileSystem::GetSaveDirectory() { - return RenderD7::FileSystem::Normalize( - RenderD7::FileSystem::GetUserDirectory() + "/save"); -} - -bool RenderD7::FileSystem::SetupWriteDirectory() { - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - if (RenderD7::FileSystem::savePath.empty()) - RenderD7::AddOvl( - std::make_unique("PHYSFS-Error", "Path is Empty")); - return false; - - std::string tmpWritePath = RenderD7::FileSystem::savePath; - std::string tmpDirectoryPath = RenderD7::FileSystem::savePath; - - if (RenderD7::FileSystem::savePath.find( - RenderD7::FileSystem::GetUserDirectory()) == 0) { - tmpWritePath = RenderD7::FileSystem::GetUserDirectory(); - tmpDirectoryPath = - savePath.substr(RenderD7::FileSystem::GetUserDirectory().length()); - - /* strip leading '/' characters from the path we want to create */ - size_t startPosition = tmpDirectoryPath.find_first_not_of('/'); - - if (startPosition != std::string::npos) - tmpDirectoryPath = tmpDirectoryPath.substr(startPosition); - } - - if (!PHYSFS_setWriteDir(tmpWritePath.c_str())) { - printf("Failed to set write dir to %s\n", tmpWritePath.c_str()); - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", - RenderD7::FormatString("Failed to set write dir to %s\n", - tmpWritePath.c_str()))); - return false; - } - - if (!RenderD7::FileSystem::CreateDirectory(tmpDirectoryPath.c_str())) { - printf("Failed to create dir %s\n", tmpDirectoryPath.c_str()); - /* clear the write directory in case of error */ - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FormatString("Failed to create dir %s\n", - tmpDirectoryPath.c_str()))); - PHYSFS_setWriteDir(nullptr); - return false; - } - - if (!PHYSFS_setWriteDir(savePath.c_str())) { - printf("Failed to set write dir to %s\n", savePath.c_str()); - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", - RenderD7::FormatString("Failed to set write dir to %s\n", - savePath.c_str()))); - return false; - } - - if (!PHYSFS_mount(savePath.c_str(), nullptr, 0)) { - printf("Failed to mount write dir (%s)\n", - RenderD7::FileSystem::GetPhysfsError()); - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", - RenderD7::FormatString("Failed to mount write dir (%s)\n", - RenderD7::FileSystem::GetPhysfsError()))); - /* clear the write directory in case of error */ - PHYSFS_setWriteDir(nullptr); - return false; - } - - return true; -} - -std::string RenderD7::FileSystem::GetUserDirectory() { - return RenderD7::FileSystem::Normalize( - PHYSFS_getPrefDir("npi-d7", "renderd7")); -} - -bool RenderD7::FileSystem::GetInfo(const char *filename, - RenderD7::FileSystem::Info &info) { - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - PHYSFS_Stat stat = {}; - - if (!PHYSFS_stat(filename, &stat)) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - info.mod_time = - std::min(stat.modtime, RenderD7::FileSystem::MAX_STAMP); - info.size = std::min(stat.filesize, RenderD7::FileSystem::MAX_STAMP); - - if (stat.filetype == PHYSFS_FILETYPE_REGULAR) - info.type = RenderD7::FileSystem::FileType_File; - else if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY) - info.type = RenderD7::FileSystem::FileType_Directory; - else if (stat.filetype == PHYSFS_FILETYPE_SYMLINK) - info.type = RenderD7::FileSystem::FileType_SymLink; - else - info.type = RenderD7::FileSystem::FileType_Other; - - return true; -} - -void RenderD7::FileSystem::GetDirectoryItems(const char *path, - std::vector &items) { - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return; - - char **results = PHYSFS_enumerateFiles(path); - - if (results == nullptr) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return; - - for (char **item = results; *item != 0; item++) - items.push_back(*item); - - PHYSFS_freeList(results); -} - -bool RenderD7::FileSystem::OpenFile(File &file, const char *name, - FileMode mode) { - if (mode == FileMode_Closed) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - if (file.handle) - RenderD7::FileSystem::CloseFile(file); - - if (mode == FileMode_Read && !PHYSFS_exists(name)) { - printf("Could not open file %s, does not exist.\n", name); - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", - RenderD7::FormatString("Could not open file %s, does not exist.\n", - name))); - return false; - } - - if ((mode == FileMode_Write) && - (PHYSFS_getWriteDir() == nullptr && - RenderD7::FileSystem::SetupWriteDirectory())) { - printf("Could not set write directory.\n"); - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", - RenderD7::FormatString("Could not set write directory.\n"))); - return false; - } - - PHYSFS_getLastErrorCode(); - - switch (mode) { - case FileMode_Read: - file.handle = PHYSFS_openRead(name); - break; - case FileMode_Write: - file.handle = PHYSFS_openWrite(name); - break; - default: - break; - } - - if (!file.handle) { - const char *error = RenderD7::FileSystem::GetPhysfsError(); - - if (error == nullptr) - error = "unknown error"; - - printf("Could not open file %s (%s)\n", name, error); - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", - RenderD7::FormatString("Could not open file %s (%s)\n", name, error))); - - return false; - } - - file.mode = mode; - - return true; -} - -bool RenderD7::FileSystem::CloseFile(File &file) { - if (file.handle == nullptr || !PHYSFS_close(file.handle)) - return false; - - file.handle = nullptr; - - return true; -} - -bool RenderD7::FileSystem::CreateDirectory(const char *name) { - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - if (PHYSFS_getWriteDir() == nullptr && - !RenderD7::FileSystem::SetupWriteDirectory()) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - if (!PHYSFS_mkdir(name)) - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - - return true; -} - -int64_t RenderD7::FileSystem::ReadFile(File &file, void *destination, - int64_t size) { - if (!file.handle || file.mode != FileMode_Read) { - printf("File is not opened for reading.\n"); - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", "File is not opened for reading.\n")); - return 0; - } - - if (size > file.GetSize()) - size = file.GetSize(); - else if (size < 0) { - printf("Invalid read size %lld\n", size); - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", - RenderD7::FormatString("Invalid read size %lld\n", size))); - return 0; - } - - return PHYSFS_readBytes(file.handle, destination, (PHYSFS_uint64)size); -} - -bool RenderD7::FileSystem::WriteFile(File &file, const void *data, - int64_t size) { - if (!file.handle || file.mode != FileMode_Write) { - printf("File is not opened for writing.\n"); - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", "File is not opened for writing.\n")); - return false; - } - - int64_t written = PHYSFS_writeBytes(file.handle, data, (PHYSFS_uint64)size); - - if (written != size) { - RenderD7::AddOvl(std::make_unique( - "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; - } - - return true; } \ No newline at end of file diff --git a/source/Image.cpp b/source/Image.cpp index bef9c00..7aa3312 100644 --- a/source/Image.cpp +++ b/source/Image.cpp @@ -1,6 +1,8 @@ #include #include #include + +#include extern bool usedbgmsg; static u32 GetNextPowerOf2(u32 v) { @@ -75,6 +77,78 @@ static bool C3DTexToC2DImage(C2D_Image *texture, u32 width, u32 height, return false; } +static void OLD_C3DTexToC2DImage(C3D_Tex *tex, Tex3DS_SubTexture *subtex, u8 *buf, u32 size, u32 width, u32 height, GPU_TEXCOLOR format) { + // RGBA -> ABGR + for (u32 row = 0; row < width; row++) { + for (u32 col = 0; col < height; col++) { + u32 z = (row + col * width) * 4; + + u8 r = *(u8 *)(buf + z); + u8 g = *(u8 *)(buf + z + 1); + u8 b = *(u8 *)(buf + z + 2); + u8 a = *(u8 *)(buf + z + 3); + + *(buf + z) = a; + *(buf + z + 1) = b; + *(buf + z + 2) = g; + *(buf + z + 3) = r; + } + } + + u32 w_pow2 = GetNextPowerOf2(width); + u32 h_pow2 = GetNextPowerOf2(height); + + subtex->width = (u16)width; + subtex->height = (u16)height; + subtex->left = 0.0f; + subtex->top = 1.0f; + subtex->right = (width / (float)w_pow2); + subtex->bottom = 1.0 - (height / (float)h_pow2); + + C3D_TexInit(tex, (u16)w_pow2, (u16)h_pow2, format); + C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST); + + u32 pixel_size = (size / width / height); + + memset(tex->data, 0, tex->size); + + for (u32 x = 0; x < width; x++) { + for (u32 y = 0; y < height; y++) { + u32 dst_pos = ((((y >> 3) * (w_pow2 >> 3) + (x >> 3)) << 6) + ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) * pixel_size; + u32 src_pos = (y * width + x) * pixel_size; + + memcpy(&((u8*)tex->data)[dst_pos], &((u8*)buf)[src_pos], pixel_size); + } + } + + C3D_TexFlush(tex); + + tex->border = 0x00000000; + C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER); + linearFree(buf); +} + +bool IMG_LoadImageFile(C2D_Image *texture, const char *path) { + stbi_uc *image = NULL; + int width = 0, height = 0; + int nc; + + image = stbi_load(path, &width, &height, &nc, 4); + + if (width > 1024 || height > 1024) { + stbi_image_free(image); + return false; + } + + C3D_Tex *tex = new C3D_Tex; + Tex3DS_SubTexture *subtex = new Tex3DS_SubTexture; + OLD_C3DTexToC2DImage(tex, subtex, image, (u32)(width * height * 4), (u32)width, (u32)height, GPU_RGBA8); + texture->tex = tex; + texture->subtex = subtex; + stbi_image_free(image); + return true; +} + extern "C" { #include } @@ -257,4 +331,18 @@ void RenderD7::Image::LoadFromBitmap(BMP bitmap) { RenderD7::AddOvl(std::make_unique( "Bmp - Error", "Code: " + std::to_string(error))); } -} \ No newline at end of file +} + +namespace RenderD7 { +void Image::LoadJpg(std::string path) { + if (usedbgmsg) { + // RenderD7::Msg::Display("RenderD7", "Loading Png:" + path, Top); + } + if (loadet) { + C3D_TexDelete(this->img.tex); + loadet = false; + } + IMG_LoadImageFile(&this->img, path.c_str()); + loadet = true; +} +} // namespace RenderD7 \ No newline at end of file diff --git a/source/stb.cpp b/source/stb.cpp new file mode 100644 index 0000000..1172512 --- /dev/null +++ b/source/stb.cpp @@ -0,0 +1,2 @@ +#define STB_IMAGE_IMPLEMENTATION +#include \ No newline at end of file