diff --git a/.vscode/settings.json b/.vscode/settings.json index 6dfc696..bedfa4b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -57,6 +57,9 @@ "shared_mutex": "cpp", "valarray": "cpp", "random": "cpp", - "cuchar": "cpp" + "cuchar": "cpp", + "compare": "cpp", + "concepts": "cpp", + "numbers": "cpp" } } \ No newline at end of file diff --git a/include/renderd7/BitmapPrinter.hpp b/include/renderd7/BitmapPrinter.hpp index 0859b6d..61f7b74 100644 --- a/include/renderd7/BitmapPrinter.hpp +++ b/include/renderd7/BitmapPrinter.hpp @@ -7,101 +7,105 @@ #include -#include #include +#include #include -namespace RenderD7 -{ - enum Encoder - { - BITMAP, ///< Encode Data to Bitmap - DIRECT, ///< Encode Direct to Framebuffer(No Decoder Required) - C3D ///< Encode Directly to C3D_Tex (Just an Idea) - }; +namespace RenderD7 { +enum Encoder { + BITMAP, ///< Encode Data to Bitmap + DIRECT, ///< Encode Direct to Framebuffer(No Decoder Required) + C3D ///< Encode Directly to C3D_Tex (Just an Idea) +}; - enum Decoder - { - BITMAP2C3D, ///< Decode and Encode to C3D_Tex (Currently Fastest) (47,4ms) - BITMAP2PNG2C3D ///< Decode Bitmap end Convert to Png, then C3D (Very Slow) (201,4ms) - }; +enum Decoder { + BITMAP2C3D, ///< Decode and Encode to C3D_Tex (Currently Fastest) (47,4ms) + BITMAP2PNG2C3D ///< Decode Bitmap end Convert to Png, then C3D (Very Slow) + ///< (201,4ms) +}; - class BitmapPrinter - { - public: - BitmapPrinter(int w, int h); - ~BitmapPrinter(); - bool DecodeFile(std::string file); - - void SetDecoder(Decoder deccc) { decc = deccc; } - void DrawPixel(int x, int y, u8 b, u8 g, u8 r, u8 a); - void DrawRect(int x, int y, int w, int h, u8 line_w, u8 b, u8 g, u8 r, u8 a); - void DrawRectFilled(int x, int y, int w, int h, u8 b, u8 g, u8 r, u8 a); - void UsePreMap(BMP map); - void UsePrePrintMap(BitmapPrinter printmap); - BMP GetBitmap(){ return bitmap; } - void SaveBmp(std::string name); - void SavePng(std::string name); +class BitmapPrinter { +public: + BitmapPrinter(int w, int h); + ~BitmapPrinter(); + bool DecodeFile(std::string file); - void CreateScreen(C3D_RenderTarget *target); - bool DrawScreenDirectF(int framerate); - bool DrawScreenDirect(); - void DrawScreenF(int framerate); - void DrawScreen(); - bool UpdateScreenF(int framerate); - bool UpdateScreen(); - void Clear(u8 b = 0, u8 g = 0, u8 r = 0, u8 a = 255); - void ClearBlank(); - RenderD7::Image GetImage(); - /// Test to Find out The Best Settings for BitmapPrinter - void Benchmark(); - /// Setup the Benchmark - /// \param framerate The Fps of the ScreenUpdates - void SetupBenchmark(int framerate); - bool IsBenchmarkRunning() { return this->benchmark; } + void SetDecoder(Decoder deccc) { decc = deccc; } + void DrawPixel(int x, int y, u8 b, u8 g, u8 r, u8 a); + void DrawRect(int x, int y, int w, int h, u8 line_w, u8 b, u8 g, u8 r, u8 a); + void DrawRectFilled(int x, int y, int w, int h, u8 b, u8 g, u8 r, u8 a); + void UsePreMap(BMP map); + void UsePrePrintMap(BitmapPrinter printmap); + BMP GetBitmap() { return bitmap; } + void SaveBmp(std::string name); + void SavePng(std::string name); - void DrawDebugText(int x, int y, int t_size, u32 color, std::string text); - void DrawText(int x, int y, float t_size, u32 color, std::string text, RenderD7::NFontApi font); - private: - //funcs - bool Decode(Decoder deccc); - void DrawDebugChar(u32 posX, u32 posY, int t_size, u32 color, char character); - void DrawChar(int posX, int posY, float t_size, u32 color, char character, RenderD7::NFontApi font); - //parameter - int frame = 0; - RenderD7::Image renderframe; - bool isscreen = false; - C3D_RenderTarget* targetr; - BMP bitmap = BMP(20, 20, true); //Need to Set e Predefined Bitmap. If not the System will Crash. - BMP blank = BMP(20, 20, true); //Need to Set e Predefined Bitmap. If not the System will Crash. + void CreateScreen(C3D_RenderTarget *target); + bool DrawScreenDirectF(int framerate); + bool DrawScreenDirect(); + void DrawScreenF(int framerate); + void DrawScreen(); + bool UpdateScreenF(int framerate); + bool UpdateScreen(); + void Clear(u8 b = 0, u8 g = 0, u8 r = 0, u8 a = 255); + void ClearBlank(); + RenderD7::Image GetImage(); + /// Test to Find out The Best Settings for BitmapPrinter + void Benchmark(); + /// Setup the Benchmark + /// \param framerate The Fps of the ScreenUpdates + void SetupBenchmark(int framerate); + bool IsBenchmarkRunning() { return this->benchmark; } - /////////////////////////////////////////////////////////////////////////////////////////////////// - //Benchmark Stuff; - int testfpsd; - bool benchmark = false; - bool setupbenchmark; - float frametime = 0; - uint64_t lastTime = 0; - float dtt = 0.f; - float dtt2 = 0.f; - float dtt3 = 0.f; - float timer = 0; - float mhdtt = 0; - float mdtt2; - float mdtt3; + void DrawDebugText(int x, int y, int t_size, u32 color, std::string text); + void DrawText(int x, int y, float t_size, u32 color, std::string text, + RenderD7::NFontApi font); - float fpsClock = 0.f; - int frameCounter = 0, fps = 0; +private: + // funcs + bool Decode(Decoder deccc); + void DrawDebugChar(u32 posX, u32 posY, int t_size, u32 color, char character); + void DrawChar(int posX, int posY, float t_size, u32 color, char character, + RenderD7::NFontApi font); + // parameter + int frame = 0; + RenderD7::Image renderframe; + bool isscreen = false; + C3D_RenderTarget *targetr; + BMP bitmap = BMP( + 20, 20, + true); // Need to Set e Predefined Bitmap. If not the System will Crash. + BMP blank = BMP( + 20, 20, + true); // Need to Set e Predefined Bitmap. If not the System will Crash. - std::vector hdttt; - std::vector hdttt2; - std::vector hdttt3; - std::vector fpscountc; - int renderedframes = 0; - int testfps = 60; - Encoder encc = Encoder::BITMAP; - Decoder decc = Decoder::BITMAP2C3D; - //////////////////////////////////////////////////////////////////////////////////////////////// - }; -} \ No newline at end of file + /////////////////////////////////////////////////////////////////////////////////////////////////// + // Benchmark Stuff; + int testfpsd; + bool benchmark = false; + bool setupbenchmark; + float frametime = 0; + uint64_t lastTime = 0; + float dtt = 0.f; + float dtt2 = 0.f; + float dtt3 = 0.f; + float timer = 0; + float mhdtt = 0; + float mdtt2; + float mdtt3; + + float fpsClock = 0.f; + int frameCounter = 0, fps = 0; + + std::vector hdttt; + std::vector hdttt2; + std::vector hdttt3; + std::vector fpscountc; + int renderedframes = 0; + int testfps = 60; + Encoder encc = Encoder::BITMAP; + Decoder decc = Decoder::BITMAP2C3D; + //////////////////////////////////////////////////////////////////////////////////////////////// +}; +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/Color.hpp b/include/renderd7/Color.hpp index 9f188c4..79d51c0 100644 --- a/include/renderd7/Color.hpp +++ b/include/renderd7/Color.hpp @@ -1,31 +1,31 @@ #pragma once -#include -#include -#include #include #include -#include +#include #include +#include +#include +#include -#define UNPACK_RGBA(col) (uint8_t) (col >> 24), (col >> 16), (col >> 8), (col) -#define UNPACK_BGRA(col) (uint8_t) (col >> 8), (col >> 16), (col >> 24), (col) +#define UNPACK_RGBA(col) (uint8_t)(col >> 24), (col >> 16), (col >> 8), (col) +#define UNPACK_BGRA(col) (uint8_t)(col >> 8), (col >> 16), (col >> 24), (col) -namespace RenderD7 -{ - namespace Color - { - struct rgba - { - uint8_t r, g, b, a; - }; - class RGBA{ - public: - RGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : m_r(r),m_g(g),m_b(b),m_a(a){} - uint32_t toRGBA() const {return (m_r << 24) | (m_g << 16) | (m_b << 8) | m_a;} - - uint8_t m_r, m_g ,m_b, m_a; - }; - std::string RGB2Hex(int r, int g, int b); - uint32_t Hex(const std::string color, uint8_t a = 255); - } -} \ No newline at end of file +namespace RenderD7 { +namespace Color { +struct rgba { + uint8_t r, g, b, a; +}; +class RGBA { +public: + RGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) + : m_r(r), m_g(g), m_b(b), m_a(a) {} + uint32_t toRGBA() const { + return (m_r << 24) | (m_g << 16) | (m_b << 8) | m_a; + } + + uint8_t m_r, m_g, m_b, m_a; +}; +std::string RGB2Hex(int r, int g, int b); +uint32_t Hex(const std::string color, uint8_t a = 255); +} // namespace Color +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/Draw.hpp b/include/renderd7/Draw.hpp index 89e3b4e..6f831ff 100644 --- a/include/renderd7/Draw.hpp +++ b/include/renderd7/Draw.hpp @@ -1,25 +1,28 @@ #pragma once -#include -#include #include <3ds.h> +#include +#include #include -namespace RenderD7 -{ - namespace Draw - { - bool Rect(float x, float y, float w, float h, u32 color); - bool NFRect(float p1x, float p1y, float w, float h, u32 color, float scale = 1); - bool Px(float x, float y, u32 color); - void TextCentered(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr); - void Text(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr); - void TextRight(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr); - float GetTextWidth(float size, std::string Text, C2D_Font fnt = nullptr); - void GetTextSize(float size, float *width, float *height, std::string Text, C2D_Font fnt = nullptr); - float GetTextHeight(float size, std::string Text, C2D_Font fnt = nullptr); - Result LoadFont(C2D_Font &fnt, const char * Path = ""); - Result UnloadFont(C2D_Font &fnt); - bool Circle(float x, float y, float radius, u32 color); - bool Image(C2D_Image img, float x, float y, float scaleX = 1.0f, float scaleY = 1.0f); - } -} \ No newline at end of file +namespace RenderD7 { +namespace Draw { +bool Rect(float x, float y, float w, float h, u32 color); +bool NFRect(float p1x, float p1y, float w, float h, u32 color, float scale = 1); +bool Px(float x, float y, u32 color); +void TextCentered(float x, float y, float size, u32 color, std::string Text, + int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr); +void Text(float x, float y, float size, u32 color, std::string Text, + int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr); +void TextRight(float x, float y, float size, u32 color, std::string Text, + int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr); +float GetTextWidth(float size, std::string Text, C2D_Font fnt = nullptr); +void GetTextSize(float size, float *width, float *height, std::string Text, + C2D_Font fnt = nullptr); +float GetTextHeight(float size, std::string Text, C2D_Font fnt = nullptr); +Result LoadFont(C2D_Font &fnt, const char *Path = ""); +Result UnloadFont(C2D_Font &fnt); +bool Circle(float x, float y, float radius, u32 color); +bool Image(C2D_Image img, float x, float y, float scaleX = 1.0f, + float scaleY = 1.0f); +} // namespace Draw +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/FileSystem.hpp b/include/renderd7/FileSystem.hpp index df74e2b..86bfe5d 100644 --- a/include/renderd7/FileSystem.hpp +++ b/include/renderd7/FileSystem.hpp @@ -1,116 +1,105 @@ -//FileSystem based on libphyfs based on https://github.com/TurtleP/3ds-examples/blob/fs/physfs/fs/physfs/include/filesystem.h +// FileSystem based on libphyfs based on +// https://github.com/TurtleP/3ds-examples/blob/fs/physfs/fs/physfs/include/filesystem.h #pragma once #include #include #include -#define RD7_FSYS_GETINFO(path) ({ \ - RenderD7::FileSystem::Info inf; \ - RenderD7::FileSystem::GetInfo(path, inf); \ - inf; \ - }) +#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; +namespace RenderD7 { +namespace FileSystem { +static constexpr auto MAX_STAMP = 0x20000000000000LL; - enum FileMode - { - FileMode_Open, - FileMode_Read, - FileMode_Write, - FileMode_Closed - }; +enum FileMode { FileMode_Open, FileMode_Read, FileMode_Write, FileMode_Closed }; - enum FileType - { - FileType_File, - FileType_Directory, - FileType_SymLink, - FileType_Other - }; +enum FileType { + FileType_File, + FileType_Directory, + FileType_SymLink, + FileType_Other +}; - struct File - { - PHYSFS_file* handle; - FileMode mode; +struct File { + PHYSFS_file *handle; + FileMode mode; - File() - { - this->handle = nullptr; - this->mode = FileMode_Closed; - } + File() { + this->handle = nullptr; + this->mode = FileMode_Closed; + } - int64_t GetSize() - { - if (this->handle == nullptr) - return 0; + int64_t GetSize() { + if (this->handle == nullptr) + return 0; - return (int64_t)PHYSFS_fileLength(this->handle); - } - }; + return (int64_t)PHYSFS_fileLength(this->handle); + } +}; - struct Info - { - int64_t size; - int64_t mod_time; - FileType type; - }; +struct Info { + int64_t size; + int64_t mod_time; + FileType type; +}; - int Init(const char* argv); +int Init(const char *argv); - void Initialize(); +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 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); +/* +** 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; +static std::string savePath; - /* gets the last physfs error */ - const char* GetPhysfsError(); +/* gets the last physfs error */ +const char *GetPhysfsError(); - /* strips any duplicate slashes */ - std::string Normalize(const std::string& input); +/* strips any duplicate slashes */ +std::string Normalize(const std::string &input); - /* gets the user directory from physfs */ - std::string GetUserDirectory(); +/* gets the user directory from physfs */ +std::string GetUserDirectory(); - /* gets the save directory */ - std::string GetSaveDirectory(); +/* gets the save directory */ +std::string GetSaveDirectory(); - /* sets up the writing directory for physfs */ - bool SetupWriteDirectory(); +/* 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 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); +/* 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); +/* creates a new directory */ +bool CreateDirectory(const char *name); - bool CloseFile(File& file); +bool CloseFile(File &file); - /* creates a new file */ - bool OpenFile(File& file, const char* name, FileMode mode); +/* 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); +/* 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); - } -} \ No newline at end of file +/* reads a file's content */ +int64_t ReadFile(File &file, void *destination, int64_t size); +} // namespace FileSystem +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/Fonts/NFontApi.hpp b/include/renderd7/Fonts/NFontApi.hpp index 1a94729..7b9a14f 100644 --- a/include/renderd7/Fonts/NFontApi.hpp +++ b/include/renderd7/Fonts/NFontApi.hpp @@ -1,149 +1,142 @@ #pragma once +#include #include #include -#include #include #include -#define MAXUNICODE 0x10FFFF +#define MAXUNICODE 0x10FFFF -namespace RenderD7 -{ - inline int utf8_decode(const char* o) { - static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; - const unsigned char *s = (const unsigned char *)o; - unsigned int c = s[0]; - unsigned int res = 0; /* final result */ - if (c < 0x80) /* ascii? */ - res = c; - else { - int count = 0; /* to count number of continuation bytes */ - while (c & 0x40) { /* still have continuation bytes? */ - int cc = s[++count]; /* read next byte */ - if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ - return -1; /* invalid byte sequence */ - res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ - c <<= 1; /* to test next bit */ - } - res |= ((c & 0x7F) << (count * 5)); /* add first byte */ - if (count > 3 || res > MAXUNICODE || res <= limits[count]) - return -1; /* invalid byte sequence */ - s += count; /* skip continuation bytes read */ - } - return res; +namespace RenderD7 { +inline int utf8_decode(const char *o) { + static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; + const unsigned char *s = (const unsigned char *)o; + unsigned int c = s[0]; + unsigned int res = 0; /* final result */ + if (c < 0x80) /* ascii? */ + res = c; + else { + int count = 0; /* to count number of continuation bytes */ + while (c & 0x40) { /* still have continuation bytes? */ + int cc = s[++count]; /* read next byte */ + if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ + return -1; /* invalid byte sequence */ + res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ + c <<= 1; /* to test next bit */ } - + res |= ((c & 0x7F) << (count * 5)); /* add first byte */ + if (count > 3 || res > MAXUNICODE || res <= limits[count]) + return -1; /* invalid byte sequence */ + s += count; /* skip continuation bytes read */ + } + return res; +} +inline std::string IntToUtf8(int convertval) { + // We only care about plane 1 right now, + // but know that we have other options (0x10FFFF) + // Technically UTF-8 is "limited" to 4 bytes, so it's not + // Like it matters much anyways these days - inline std::string IntToUtf8(int convertval){ - - // We only care about plane 1 right now, - // but know that we have other options (0x10FFFF) - // Technically UTF-8 is "limited" to 4 bytes, so it's not - // Like it matters much anyways these days - - if(convertval == 0) - return " "; - if( (convertval <= 0x7F) && (convertval > 0x00) ){ - - std::string out("."); - - std::bitset<8> x(convertval); - - unsigned long l = x.to_ulong(); - unsigned char c = static_cast(l); - out[0] = c; - - return out; - - } else if ( (convertval >= 0x80) && (convertval <= 0x07FF) ) { - - std::string out(".."); - - int firstShift = (convertval >> 0x06) ^ 0xC0; - int secondShift = ((convertval ^ 0xFFC0) | 0x80) & ~0x40; - - std::bitset<8> first(firstShift); - std::bitset<8> last(secondShift); - - - unsigned long l = first.to_ulong(); - unsigned char c = static_cast(l); - out[0] = c; - - unsigned long ltwo = last.to_ulong(); - unsigned char ctwo = static_cast(ltwo); - out[1] = ctwo; - - return out; - - } else if( (convertval >= 0x0800) && (convertval <= 0xFFFF) ){ - - - std::string out("..."); - - int firstShift = ((convertval ^ 0xFC0FFF) >> 0x0C) | 0xE0; - int secondShift = (((convertval ^ 0xFFF03F) >> 0x06) | 0x80) & ~0x40; - int thirdShift = ((convertval ^ 0xFFFC0) | 0x80) & ~0x40; - - std::bitset<8> first(firstShift); - std::bitset<8> second(secondShift); - std::bitset<8> third(thirdShift); - - unsigned long lone = first.to_ulong(); - unsigned char cone = static_cast(lone); - out[0] = cone; - - unsigned long ltwo = second.to_ulong(); - unsigned char ctwo = static_cast(ltwo); - out[1] = ctwo; - - unsigned long lthree = third.to_ulong(); - unsigned char cthree = static_cast(lthree); - out[2] = cthree; - - return out; - - } else{ - return " "; - } + if (convertval == 0) + return " "; + if ((convertval <= 0x7F) && (convertval > 0x00)) { + std::string out("."); + + std::bitset<8> x(convertval); + + unsigned long l = x.to_ulong(); + unsigned char c = static_cast(l); + out[0] = c; + + return out; + + } else if ((convertval >= 0x80) && (convertval <= 0x07FF)) { + + std::string out(".."); + + int firstShift = (convertval >> 0x06) ^ 0xC0; + int secondShift = ((convertval ^ 0xFFC0) | 0x80) & ~0x40; + + std::bitset<8> first(firstShift); + std::bitset<8> last(secondShift); + + unsigned long l = first.to_ulong(); + unsigned char c = static_cast(l); + out[0] = c; + + unsigned long ltwo = last.to_ulong(); + unsigned char ctwo = static_cast(ltwo); + out[1] = ctwo; + + return out; + + } else if ((convertval >= 0x0800) && (convertval <= 0xFFFF)) { + + std::string out("..."); + + int firstShift = ((convertval ^ 0xFC0FFF) >> 0x0C) | 0xE0; + int secondShift = (((convertval ^ 0xFFF03F) >> 0x06) | 0x80) & ~0x40; + int thirdShift = ((convertval ^ 0xFFFC0) | 0x80) & ~0x40; + + std::bitset<8> first(firstShift); + std::bitset<8> second(secondShift); + std::bitset<8> third(thirdShift); + + unsigned long lone = first.to_ulong(); + unsigned char cone = static_cast(lone); + out[0] = cone; + + unsigned long ltwo = second.to_ulong(); + unsigned char ctwo = static_cast(ltwo); + out[1] = ctwo; + + unsigned long lthree = third.to_ulong(); + unsigned char cthree = static_cast(lthree); + out[2] = cthree; + + return out; + + } else { + return " "; + } } #define I2U82I(val) RenderD7::utf8_decode(RenderD7::IntToUtf8(val).c_str()) - class NFontApi - { - public: - NFontApi(); - ~NFontApi(); - void LoadTTF(std::string path); - unsigned char* GetGlyphBitmap(char glyph); - std::string GetStatus(){ return status; } - float GetScale() {return scale; } - int GetGlyphWidth(char glyph); - int GetGlyphHeight(char glyph); - int GetLineHeight(){ return l_h; } - int GetBaseHeight(){ return height; } - private: - std::string status; +class NFontApi { +public: + NFontApi(); + ~NFontApi(); + void LoadTTF(std::string path); + unsigned char *GetGlyphBitmap(char glyph); + std::string GetStatus() { return status; } + float GetScale() { return scale; } + int GetGlyphWidth(char glyph); + int GetGlyphHeight(char glyph); + int GetLineHeight() { return l_h; } + int GetBaseHeight() { return height; } - int height; +private: + std::string status; - float scale; - int b_w; - int b_h; - int l_h; + int height; - int w; - int h; + float scale; + int b_w; + int b_h; + int l_h; - int x0,y0,x1,y1; - int ascent,baseline,decent,linegap; + int w; + int h; - int linespace; + int x0, y0, x1, y1; + int ascent, baseline, decent, linegap; - stbtt_fontinfo font; - }; -} \ No newline at end of file + int linespace; + + stbtt_fontinfo font; +}; +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/Image.hpp b/include/renderd7/Image.hpp index 825c19e..08f038b 100644 --- a/include/renderd7/Image.hpp +++ b/include/renderd7/Image.hpp @@ -7,42 +7,40 @@ #include #include -#include -#include #include #include +#include +#include -namespace RenderD7 -{ - /// Image Class - class Image - { - public: - Image(){} - ~Image(); +namespace RenderD7 { +/// Image Class +class Image { +public: + Image() {} + ~Image(); - void Unload(); - /// Load Image from Png - /// \param path path to png file - void LoadPng(const std::string path); - /// Load the Image from buffer - /// \param buffer the frame buffer - void LoadPFromBuffer(const std::vector &buffer); - void LoadFromBitmap(BMP bitmap); - /// Draw the Image directly - /// \param x The x position - /// \param y the y position - /// \param scaleX x scale from 0.0 to 1.0 - /// \param scaleY y scale from 0.0 to 1.0 - bool Draw(float x, float y, float scaleX = 1.0f, float scaleY = 1.0f); - /// \brief Get The Image - /// \return C2D_Image - C2D_Image Get(){return this->img;} + void Unload(); + /// Load Image from Png + /// \param path path to png file + void LoadPng(const std::string path); + /// Load the Image from buffer + /// \param buffer the frame buffer + void LoadPFromBuffer(const std::vector &buffer); + void LoadFromBitmap(BMP bitmap); + /// Draw the Image directly + /// \param x The x position + /// \param y the y position + /// \param scaleX x scale from 0.0 to 1.0 + /// \param scaleY y scale from 0.0 to 1.0 + bool Draw(float x, float y, float scaleX = 1.0f, float scaleY = 1.0f); + /// \brief Get The Image + /// \return C2D_Image + C2D_Image Get() { return this->img; } - void FromSheet(RenderD7::Sheet sheet, size_t index); - /// \param img this is the C2D_Image - C2D_Image img; - /// \param loadet whether the image is loadet or not - bool loadet = false; - }; -} \ No newline at end of file + void FromSheet(RenderD7::Sheet sheet, size_t index); + /// \param img this is the C2D_Image + C2D_Image img; + /// \param loadet whether the image is loadet or not + bool loadet = false; +}; +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/Ovl.hpp b/include/renderd7/Ovl.hpp index 0ef031f..a5e8c4a 100644 --- a/include/renderd7/Ovl.hpp +++ b/include/renderd7/Ovl.hpp @@ -1,17 +1,17 @@ #pragma once #include -namespace RenderD7 -{ - class Ovl { - public: - virtual ~Ovl(){} - virtual void Draw() const = 0; - virtual void Logic() = 0; - inline bool IsKilled() {return this->iskilled; } - inline void Kill() { iskilled = true; } - private: - bool iskilled = false; - }; - void AddOvl(std::unique_ptr scene); -} \ No newline at end of file +namespace RenderD7 { +class Ovl { +public: + virtual ~Ovl() {} + virtual void Draw() const = 0; + virtual void Logic() = 0; + inline bool IsKilled() { return this->iskilled; } + inline void Kill() { iskilled = true; } + +private: + bool iskilled = false; +}; +void AddOvl(std::unique_ptr scene); +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/Screen.hpp b/include/renderd7/Screen.hpp index e9f3410..9efb573 100644 --- a/include/renderd7/Screen.hpp +++ b/include/renderd7/Screen.hpp @@ -1,15 +1,13 @@ #pragma once -#include #include +#include +extern C3D_RenderTarget *Top; +extern C3D_RenderTarget *TopRight; +extern C3D_RenderTarget *Bottom; -extern C3D_RenderTarget* Top; -extern C3D_RenderTarget* TopRight; -extern C3D_RenderTarget* Bottom; - -namespace RenderD7 -{ - /// Set current RenderScreen - /// \param target The RenderTarget Top, Bottom - void OnScreen(C3D_RenderTarget *target); -} +namespace RenderD7 { +/// Set current RenderScreen +/// \param target The RenderTarget Top, Bottom +void OnScreen(C3D_RenderTarget *target); +} // namespace RenderD7 diff --git a/include/renderd7/Sheet.hpp b/include/renderd7/Sheet.hpp index 6d3465f..ff20fa3 100644 --- a/include/renderd7/Sheet.hpp +++ b/include/renderd7/Sheet.hpp @@ -2,22 +2,20 @@ #include #include -namespace RenderD7 -{ - /** The Spritesheet Class */ - class Sheet - { - public: - /// Construct sheet - Sheet(); - // Deconstruct sheet - ~Sheet(); - /// Load a Sritesheet - /// \param path Path to the Spritesheet (.t3x) - Result Load(const char *path); - /// Unload the Spritesheet - void Free(); - /// The Spritesheet - C2D_SpriteSheet spritesheet; - }; -} \ No newline at end of file +namespace RenderD7 { +/** The Spritesheet Class */ +class Sheet { +public: + /// Construct sheet + Sheet(); + // Deconstruct sheet + ~Sheet(); + /// Load a Sritesheet + /// \param path Path to the Spritesheet (.t3x) + Result Load(const char *path); + /// Unload the Spritesheet + void Free(); + /// The Spritesheet + C2D_SpriteSheet spritesheet; +}; +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/Sprite.hpp b/include/renderd7/Sprite.hpp index 7dabbf7..3832188 100644 --- a/include/renderd7/Sprite.hpp +++ b/include/renderd7/Sprite.hpp @@ -3,38 +3,37 @@ #include #include -#include #include +#include -namespace RenderD7 -{ - /// Sprite Class - class Sprite - { - public: - /// \brief Construct Sprite - Sprite(); - /// \brief Deconstruct Sprite - ~Sprite(); - /// \brief Load a Sprite From SpriteSheet - /// \param sheet the Sheet to load from.(RenderD7::Sheet) - /// \param index the number of the Sprite in the Sheet - void FromSheet(RenderD7::Sheet *sheet, size_t index); - /// \brief Load a Sprite From SpriteSheet - /// \param img the Image to load from.(RenderD7::Image) - void FromImage(RenderD7::Image *img); - bool Draw(); - void SetCenter(float x, float y); - void SetPos(float x, float y); - void SetScale(float x, float y); - void SetRotation(float rotation); - void Rotate(float speed); - float getWidth(); - float getHeigh(); - float getPosX(); - float getPosY(); - private: - C2D_ImageTint tint; - C2D_Sprite sprite; - }; -} \ No newline at end of file +namespace RenderD7 { +/// Sprite Class +class Sprite { +public: + /// \brief Construct Sprite + Sprite(); + /// \brief Deconstruct Sprite + ~Sprite(); + /// \brief Load a Sprite From SpriteSheet + /// \param sheet the Sheet to load from.(RenderD7::Sheet) + /// \param index the number of the Sprite in the Sheet + void FromSheet(RenderD7::Sheet *sheet, size_t index); + /// \brief Load a Sprite From SpriteSheet + /// \param img the Image to load from.(RenderD7::Image) + void FromImage(RenderD7::Image *img); + bool Draw(); + void SetCenter(float x, float y); + void SetPos(float x, float y); + void SetScale(float x, float y); + void SetRotation(float rotation); + void Rotate(float speed); + float getWidth(); + float getHeigh(); + float getPosX(); + float getPosY(); + +private: + C2D_ImageTint tint; + C2D_Sprite sprite; +}; +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/SpriteAnimation.hpp b/include/renderd7/SpriteAnimation.hpp index 72c2cbd..0f0679d 100644 --- a/include/renderd7/SpriteAnimation.hpp +++ b/include/renderd7/SpriteAnimation.hpp @@ -1,25 +1,25 @@ #pragma once -#include #include +#include #include #include -namespace RenderD7 -{ - class SpriteSheetAnimation : public RenderD7::Sprite - { - public: - SpriteSheetAnimation(); - ~SpriteSheetAnimation(); - void Setup(RenderD7::Sheet *sheet, size_t imagecount, size_t startimage, float frame_begin, float frame_finish); - void Play(float timespeed); - private: - size_t images; - size_t imgs = 0; - float D_totaltime; - RenderD7::Sheet *sheet; - float time; - }; -} \ No newline at end of file +namespace RenderD7 { +class SpriteSheetAnimation : public RenderD7::Sprite { +public: + SpriteSheetAnimation(); + ~SpriteSheetAnimation(); + void Setup(RenderD7::Sheet *sheet, size_t imagecount, size_t startimage, + float frame_begin, float frame_finish); + void Play(float timespeed); + +private: + size_t images; + size_t imgs = 0; + float D_totaltime; + RenderD7::Sheet *sheet; + float time; +}; +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/Time.hpp b/include/renderd7/Time.hpp index 9964d55..194825f 100644 --- a/include/renderd7/Time.hpp +++ b/include/renderd7/Time.hpp @@ -1,8 +1,7 @@ #pragma once #include -namespace RenderD7 -{ - std::string FormatString(std::string fmt_str, ...); - std::string GetTimeStr(void); -} \ No newline at end of file +namespace RenderD7 { +std::string FormatString(std::string fmt_str, ...); +std::string GetTimeStr(void); +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/Toast.hpp b/include/renderd7/Toast.hpp index 3091128..2d208da 100644 --- a/include/renderd7/Toast.hpp +++ b/include/renderd7/Toast.hpp @@ -1,23 +1,22 @@ #pragma once -#include -#include #include #include +#include +#include #include -namespace RenderD7 -{ - class Toast : public RenderD7::Ovl - { - public: - Toast(std::string head, std::string msg); - void Draw(void) const override; - void Logic() override; - private: - RenderD7::BitmapPrinter toast = RenderD7::BitmapPrinter(400, 70); - RenderD7::Image *toastrendered; - std::string head, msg; - int msgposy = 240; - int delay = 0; - }; -} \ No newline at end of file +namespace RenderD7 { +class Toast : public RenderD7::Ovl { +public: + Toast(std::string head, std::string msg); + void Draw(void) const override; + void Logic() override; + +private: + RenderD7::BitmapPrinter toast = RenderD7::BitmapPrinter(400, 70); + RenderD7::Image *toastrendered; + std::string head, msg; + int msgposy = 240; + int delay = 0; +}; +} // namespace RenderD7 \ No newline at end of file diff --git a/include/renderd7/bmp.hpp b/include/renderd7/bmp.hpp index 2eededd..8014724 100644 --- a/include/renderd7/bmp.hpp +++ b/include/renderd7/bmp.hpp @@ -1,718 +1,749 @@ #pragma once #include -#include -#include #include #include #include +#include +#include using namespace std; #pragma pack(push, 1) - struct BMPFileHeader { - uint16_t file_type{ 0x4D42 }; // File type always BM which is 0x4D42 (stored as hex uint16_t in little endian) - uint32_t file_size{ 0 }; // Size of the file (in bytes) - uint16_t reserved1{ 0 }; // Reserved, always 0 - uint16_t reserved2{ 0 }; // Reserved, always 0 - uint32_t offset_data{ 0 }; // Start position of pixel data (bytes from the beginning of the file) + uint16_t file_type{0x4D42}; // File type always BM which is 0x4D42 (stored as + // hex uint16_t in little endian) + uint32_t file_size{0}; // Size of the file (in bytes) + uint16_t reserved1{0}; // Reserved, always 0 + uint16_t reserved2{0}; // Reserved, always 0 + uint32_t offset_data{ + 0}; // Start position of pixel data (bytes from the beginning of the file) }; struct BMPInfoHeader { - uint32_t size{ 0 }; // Size of this header (in bytes) - int32_t width{ 0 }; // width of bitmap in pixels - int32_t height{ 0 }; // height of bitmap in pixels - // (if positive, bottom-up, with origin in lower left corner) - // (if negative, top-down, with origin in upper left corner) - uint16_t planes{ 1 }; // No. of planes for the target device, this is always 1 - uint16_t bit_count{ 0 }; // No. of bits per pixel - uint32_t compression{ 0 }; // 0 or 3 - uncompressed. THIS PROGRAM CONSIDERS ONLY UNCOMPRESSED BMP images - uint32_t size_image{ 0 }; // 0 - for uncompressed images - int32_t x_pixels_per_meter{ 0 }; - int32_t y_pixels_per_meter{ 0 }; - uint32_t colors_used{ 0 }; // No. color indexes in the color table. Use 0 for the max number of colors allowed by bit_count - uint32_t colors_important{ 0 }; // No. of colors used for displaying the bitmap. If 0 all colors are required + uint32_t size{0}; // Size of this header (in bytes) + int32_t width{0}; // width of bitmap in pixels + int32_t height{ + 0}; // height of bitmap in pixels + // (if positive, bottom-up, with origin in lower left corner) + // (if negative, top-down, with origin in upper left corner) + uint16_t planes{1}; // No. of planes for the target device, this is always 1 + uint16_t bit_count{0}; // No. of bits per pixel + uint32_t compression{0}; // 0 or 3 - uncompressed. THIS PROGRAM CONSIDERS ONLY + // UNCOMPRESSED BMP images + uint32_t size_image{0}; // 0 - for uncompressed images + int32_t x_pixels_per_meter{0}; + int32_t y_pixels_per_meter{0}; + uint32_t colors_used{0}; // No. color indexes in the color table. Use 0 for + // the max number of colors allowed by bit_count + uint32_t colors_important{0}; // No. of colors used for displaying the bitmap. + // If 0 all colors are required }; struct BMPColorHeader { - uint32_t red_mask{ 0x00ff0000 }; // Bit mask for the red channel - uint32_t green_mask{ 0x0000ff00 }; // Bit mask for the green channel - uint32_t blue_mask{ 0x000000ff }; // Bit mask for the blue channel - uint32_t alpha_mask{ 0xff000000 }; // Bit mask for the alpha channel - uint32_t color_space_type{ 0x73524742 }; // Default "sRGB" (0x73524742) - uint32_t unused[16]{ 0 }; // Unused data for sRGB color space + uint32_t red_mask{0x00ff0000}; // Bit mask for the red channel + uint32_t green_mask{0x0000ff00}; // Bit mask for the green channel + uint32_t blue_mask{0x000000ff}; // Bit mask for the blue channel + uint32_t alpha_mask{0xff000000}; // Bit mask for the alpha channel + uint32_t color_space_type{0x73524742}; // Default "sRGB" (0x73524742) + uint32_t unused[16]{0}; // Unused data for sRGB color space }; #pragma pack(pop) struct BMP { - BMPFileHeader file_header; - BMPInfoHeader bmp_info_header; - BMPColorHeader bmp_color_header; - std::vector data; + BMPFileHeader file_header; + BMPInfoHeader bmp_info_header; + BMPColorHeader bmp_color_header; + std::vector data; - - BMP(const char *fname) { - read(fname); - } - - int read(const char *fname) { - std::ifstream inp{ fname, std::ios_base::binary }; - if (inp) { - inp.read((char*)&file_header, sizeof(file_header)); - if(file_header.file_type != 0x4D42) { - - return 50;//throw std::runtime_error("Error! Unrecognized file format."); - } - inp.read((char*)&bmp_info_header, sizeof(bmp_info_header)); + BMP(const char *fname) { read(fname); } - // The BMPColorHeader is used only for transparent images - if(bmp_info_header.bit_count == 32) { - // Check if the file has bit mask color information - if(bmp_info_header.size >= (sizeof(BMPInfoHeader) + sizeof(BMPColorHeader))) { - inp.read((char*)&bmp_color_header, sizeof(bmp_color_header)); - // Check if the pixel data is stored as BGRA and if the color space type is sRGB - check_color_header(bmp_color_header); - } else { - //std::cerr << "Error! The file \"" << fname << "\" does not seem to contain bit mask information\n"; - return 51;//throw std::runtime_error("Error! Unrecognized file format."); - } - } + int read(const char *fname) { + std::ifstream inp{fname, std::ios_base::binary}; + if (inp) { + inp.read((char *)&file_header, sizeof(file_header)); + if (file_header.file_type != 0x4D42) { - // Jump to the pixel data location - inp.seekg(file_header.offset_data, inp.beg); + return 50; // throw std::runtime_error("Error! Unrecognized file + // format."); + } + inp.read((char *)&bmp_info_header, sizeof(bmp_info_header)); - // Adjust the header fields for output. - // Some editors will put extra info in the image file, we only save the headers and the data. - if(bmp_info_header.bit_count == 32) { - bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); - file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); - } else { - bmp_info_header.size = sizeof(BMPInfoHeader); - file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader); - } - file_header.file_size = file_header.offset_data; - - if (bmp_info_header.height < 0) { - return 52;//throw std::runtime_error("The program can treat only BMP images with the origin in the bottom left corner!"); - } - - data.resize(bmp_info_header.width * bmp_info_header.height * bmp_info_header.bit_count / 8); - - // Here we check if we need to take into account row padding - if (bmp_info_header.width % 4 == 0) { - inp.read((char*)data.data(), data.size()); - file_header.file_size += static_cast(data.size()); - } - else { - row_stride = bmp_info_header.width * bmp_info_header.bit_count / 8; - uint32_t new_stride = make_stride_aligned(4); - std::vector padding_row(new_stride - row_stride); - - for (int y = 0; y < bmp_info_header.height; ++y) { - inp.read((char*)(data.data() + row_stride * y), row_stride); - inp.read((char*)padding_row.data(), padding_row.size()); - } - file_header.file_size += static_cast(data.size()) + bmp_info_header.height * static_cast(padding_row.size()); - } - } - else { - return 53;//throw std::runtime_error("Unable to open the input image file "+std::string(fname)); - } - return 0; - } - - int read_mem(std::vector buffer) { - std::stringstream inp; - std::copy(buffer.begin(), buffer.end(),std::ostream_iterator(inp,"\n")); - if (inp) { - inp.read((char*)&file_header, sizeof(file_header)); - if(file_header.file_type != 0x4D42) { - - return 50;//throw std::runtime_error("Error! Unrecognized file format."); - } - inp.read((char*)&bmp_info_header, sizeof(bmp_info_header)); - - // The BMPColorHeader is used only for transparent images - if(bmp_info_header.bit_count == 32) { - // Check if the file has bit mask color information - if(bmp_info_header.size >= (sizeof(BMPInfoHeader) + sizeof(BMPColorHeader))) { - inp.read((char*)&bmp_color_header, sizeof(bmp_color_header)); - // Check if the pixel data is stored as BGRA and if the color space type is sRGB - check_color_header(bmp_color_header); - } else { - //std::cerr << "Error! The file \"" << fname << "\" does not seem to contain bit mask information\n"; - return 51;//throw std::runtime_error("Error! Unrecognized file format."); - } - } - - // Jump to the pixel data location - inp.seekg(file_header.offset_data, inp.beg); - - // Adjust the header fields for output. - // Some editors will put extra info in the image file, we only save the headers and the data. - if(bmp_info_header.bit_count == 32) { - bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); - file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); - } else { - bmp_info_header.size = sizeof(BMPInfoHeader); - file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader); - } - file_header.file_size = file_header.offset_data; - - if (bmp_info_header.height < 0) { - return 52;//throw std::runtime_error("The program can treat only BMP images with the origin in the bottom left corner!"); - } - - data.resize(bmp_info_header.width * bmp_info_header.height * bmp_info_header.bit_count / 8); - - // Here we check if we need to take into account row padding - if (bmp_info_header.width % 4 == 0) { - inp.read((char*)data.data(), data.size()); - file_header.file_size += static_cast(data.size()); - } - else { - row_stride = bmp_info_header.width * bmp_info_header.bit_count / 8; - uint32_t new_stride = make_stride_aligned(4); - std::vector padding_row(new_stride - row_stride); - - for (int y = 0; y < bmp_info_header.height; ++y) { - inp.read((char*)(data.data() + row_stride * y), row_stride); - inp.read((char*)padding_row.data(), padding_row.size()); - } - file_header.file_size += static_cast(data.size()) + bmp_info_header.height * static_cast(padding_row.size()); - } - } - else { - return 53;//throw std::runtime_error("Unable to open the input image file "+std::string(fname)); - } - return 0; - } - - BMP(int32_t width, int32_t height, bool has_alpha = true) { - if (width <= 0 || height <= 0) { - width = 1; - height = 1; - } - - bmp_info_header.width = width; - bmp_info_header.height = height; - if (has_alpha) { - bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); - file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); - - bmp_info_header.bit_count = 32; - bmp_info_header.compression = 3; - row_stride = width * 4; - data.resize(row_stride * height); - file_header.file_size = file_header.offset_data + data.size(); - } - else { - bmp_info_header.size = sizeof(BMPInfoHeader); - file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader); - - bmp_info_header.bit_count = 24; - bmp_info_header.compression = 0; - row_stride = width * 3; - data.resize(row_stride * height); - - uint32_t new_stride = make_stride_aligned(4); - file_header.file_size = file_header.offset_data + static_cast(data.size()) + bmp_info_header.height * (new_stride - row_stride); - } - } - - unsigned write(const char *fname) { - std::ofstream of{ fname, std::ios_base::binary }; - if (of) { - if (bmp_info_header.bit_count == 32) { - write_headers_and_data(of); - } - else if (bmp_info_header.bit_count == 24) { - if (bmp_info_header.width % 4 == 0) { - write_headers_and_data(of); - } - else { - uint32_t new_stride = make_stride_aligned(4); - std::vector padding_row(new_stride - row_stride); - - write_headers(of); - - for (int y = 0; y < bmp_info_header.height; ++y) { - of.write((const char*)(data.data() + row_stride * y), row_stride); - of.write((const char*)padding_row.data(), padding_row.size()); - } - } - } - else { - return 54;//throw std::runtime_error("The program can treat only 24 or 32 bits per pixel BMP files"); - } - } - else { - return 55;//throw std::runtime_error("Unable to open the output image file."); - } - return 0; - - } - - std::vector DATA() { - std::stringstream ss; - if (ss) { - if (bmp_info_header.bit_count == 32) { - write_headers_and_datass(ss); - } - else if (bmp_info_header.bit_count == 24) { - if (bmp_info_header.width % 4 == 0) { - write_headers_and_datass(ss); - } - else { - uint32_t new_stride = make_stride_aligned(4); - std::vector padding_row(new_stride - row_stride); - - write_headersss(ss); - - for (int y = 0; y < bmp_info_header.height; ++y) { - ss.write((const char*)(data.data() + row_stride * y), row_stride); - ss.write((const char*)padding_row.data(), padding_row.size()); - } - } - } - else { - - } - } - else { - - } - std::string test11 = ss.str(); - std::vector test12(test11.begin(), test11.end()); - return test12; - - } - - unsigned fill_region(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint8_t B, uint8_t G, uint8_t R, uint8_t A) { - uint32_t channels = bmp_info_header.bit_count / 8; - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - /*if (x + w > (uint32_t)bmp_info_header.width || y + h > (uint32_t)bmp_info_header.height) { - // - }*/ - //else{ - data[channels * (y * bmp_info_header.width + x) + 0] = B; - data[channels * (y * bmp_info_header.width + x) + 1] = G; - data[channels * (y * bmp_info_header.width + x) + 2] = R; - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - //} - } - } - return 0; - } - - void fill_region_df(uint32_t x1, uint32_t y1, uint32_t w, uint32_t h, uint8_t B, uint8_t G, uint8_t R, uint8_t A) { - - int x0 = x1; - int y0 = this->bmp_info_header.height - y1 - h; - - uint32_t channels = bmp_info_header.bit_count / 8; - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - if ((x + w < (uint32_t)bmp_info_header.width) || this->bmp_info_header.height - y - h > 0) { - - data[channels * (y * bmp_info_header.width + x) + 0] = B; - data[channels * (y * bmp_info_header.width + x) + 1] = G; - data[channels * (y * bmp_info_header.width + x) + 2] = R; - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - } - } - } - } - - void manipulate_region(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint8_t A) { - int choice, choice2, intensity; - cout << "What color do you want to change? " << endl; - cout << "Enter 1 for Blue, 2 for Green, 3 for Red " << endl; - cin >> choice; - cout << "To what color do you want to change it too?" << endl; - cout << "Enter 1 for Blue, 2 for Green, 3 for Red " << endl; - cin >> choice2; - cout << "Enter the intensity of the color. (From 0 to 255) " << endl; - cin >> intensity; - if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) { - return;//throw std::runtime_error("The region does not fit in the image!"); - } - - uint32_t channels = bmp_info_header.bit_count / 8; - if (choice==1 && choice2==1) - { - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - cout << channels*(y*bmp_info_header.width+x) << endl; - //Make blue thing blue - if(data[channels * (y * bmp_info_header.width + x) + 0]>80 && data[channels * (y * bmp_info_header.width + x) + 0]<255) - { - data[channels * (y * bmp_info_header.width + x) + 0] = intensity; - data[channels * (y * bmp_info_header.width + x) + 1] = 0; - data[channels * (y * bmp_info_header.width + x) + 2] = 0; - } - //data[channels * (y * bmp_info_header.width + x) + 0] = B; - //data[channels * (y * bmp_info_header.width + x) + 1] = G; - //data[channels * (y * bmp_info_header.width + x) + 2] = R; - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - } - } - } - if (choice == 1 && choice2==2) - { - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - cout << channels*(y*bmp_info_header.width+x) << endl; - //Make blue thing green - if(data[channels * (y * bmp_info_header.width + x) + 0]>80 && data[channels * (y * bmp_info_header.width + x) + 0]<255) - { - data[channels * (y * bmp_info_header.width + x) + 0] = 0; - data[channels * (y * bmp_info_header.width + x) + 1] = intensity; - data[channels * (y * bmp_info_header.width + x) + 2] = 0; - } - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - } - } - } - if (choice == 1 && choice2==3) - { - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - cout << channels*(y*bmp_info_header.width+x) << endl; - //Make blue thing red - if(data[channels * (y * bmp_info_header.width + x) + 0]>80 && data[channels * (y * bmp_info_header.width + x) + 0]<255) - { - data[channels * (y * bmp_info_header.width + x) + 0] = 0; - data[channels * (y * bmp_info_header.width + x) + 1] = 0; - data[channels * (y * bmp_info_header.width + x) + 2] = intensity; - } - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - } - } - } - if (choice == 2 && choice2==1) - { - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - cout << channels*(y*bmp_info_header.width+x) << endl; - //Make green thing blue - if(data[channels * (y * bmp_info_header.width + x) + 1]>80 && data[channels * (y * bmp_info_header.width + x) + 1]<255) - { - data[channels * (y * bmp_info_header.width + x) + 0] = intensity; - data[channels * (y * bmp_info_header.width + x) + 1] = 0; - data[channels * (y * bmp_info_header.width + x) + 2] = 0; - } - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - } - } - } - if (choice == 2 && choice2==2) - { - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - cout << channels*(y*bmp_info_header.width+x) << endl; - //Make green thing green - if(data[channels * (y * bmp_info_header.width + x) + 1]>80 && data[channels * (y * bmp_info_header.width + x) + 1]<255) - { - data[channels * (y * bmp_info_header.width + x) + 0] = 0; - data[channels * (y * bmp_info_header.width + x) + 1] = intensity; - data[channels * (y * bmp_info_header.width + x) + 2] = 0; - } - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - } - } - } - if (choice == 2 && choice2==3) - { - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - cout << channels*(y*bmp_info_header.width+x) << endl; - //Make green thing red - if(data[channels * (y * bmp_info_header.width + x) + 1]>80 && data[channels * (y * bmp_info_header.width + x) + 1]<255) - { - data[channels * (y * bmp_info_header.width + x) + 0] = 0; - data[channels * (y * bmp_info_header.width + x) + 1] = 0; - data[channels * (y * bmp_info_header.width + x) + 2] = intensity; - } - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - } - } - } - if (choice == 3 && choice2==1) - { - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - cout << channels*(y*bmp_info_header.width+x) << endl; - //Make red thing blue - if(data[channels * (y * bmp_info_header.width + x) + 2]>80 && data[channels * (y * bmp_info_header.width + x) + 2]<255) - { - data[channels * (y * bmp_info_header.width + x) + 0] = intensity; - data[channels * (y * bmp_info_header.width + x) + 1] = 0; - data[channels * (y * bmp_info_header.width + x) + 2] = 0; - } - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - } - } - } - if (choice == 3 && choice2==2) - { - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - cout << channels*(y*bmp_info_header.width+x) << endl; - //Make red thing green - if(data[channels * (y * bmp_info_header.width + x) + 2]>80 && data[channels * (y * bmp_info_header.width + x) + 2]<255) - { - data[channels * (y * bmp_info_header.width + x) + 0] = 0; - data[channels * (y * bmp_info_header.width + x) + 1] = intensity; - data[channels * (y * bmp_info_header.width + x) + 2] = 0; - } - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - } - } - } - if (choice == 3 && choice2==3) - { - for (uint32_t y = y0; y < y0 + h; ++y) { - for (uint32_t x = x0; x < x0 + w; ++x) { - cout << channels*(y*bmp_info_header.width+x) << endl; - //Make red thing blue - if(data[channels * (y * bmp_info_header.width + x) + 2]>80 && data[channels * (y * bmp_info_header.width + x) + 2]<255) - { - data[channels * (y * bmp_info_header.width + x) + 0] = 0; - data[channels * (y * bmp_info_header.width + x) + 1] = 0; - data[channels * (y * bmp_info_header.width + x) + 2] = intensity; - } - if (channels == 4) { - data[channels * (y * bmp_info_header.width + x) + 3] = A; - } - } - } - } - - } - - int OrganizeAverageRed() - { - int ColorRed[bmp_info_header.height][bmp_info_header.width]; - int ColorGreen[bmp_info_header.height][bmp_info_header.width];; - int ColorBlue[bmp_info_header.height][bmp_info_header.width]; - float pixels=bmp_info_header.height*bmp_info_header.width; - float intensity=0; - float sum=0; - uint32_t channels = bmp_info_header.bit_count / 8; - cout << "The Width of the image is " << bmp_info_header.width << endl; - cout << "The height of the image is " << bmp_info_header.height << endl; - for (int y = 0; y < bmp_info_header.height; ++y) { - for (int x = 0; x < bmp_info_header.width; ++x) { - //cout << channels*(y*bmp_info_header.width+x) << endl; - //Read red - ColorBlue[y][x]=data[channels * (y * bmp_info_header.width + x) + 0]; - ColorGreen[y][x]=data[channels * (y * bmp_info_header.width + x) + 1]; - ColorRed[y][x]=data[channels * (y * bmp_info_header.width + x) + 2]; - } - } - for(int y=0; y= + (sizeof(BMPInfoHeader) + sizeof(BMPColorHeader))) { + inp.read((char *)&bmp_color_header, sizeof(bmp_color_header)); + // Check if the pixel data is stored as BGRA and if the color space + // type is sRGB + check_color_header(bmp_color_header); + } else { + // std::cerr << "Error! The file \"" << fname << "\" does not seem to + // contain bit mask information\n"; + return 51; // throw std::runtime_error("Error! Unrecognized file + // format."); } } - - intensity=sum/pixels; - cout << intensity << endl; - return intensity; + + // Jump to the pixel data location + inp.seekg(file_header.offset_data, inp.beg); + + // Adjust the header fields for output. + // Some editors will put extra info in the image file, we only save the + // headers and the data. + if (bmp_info_header.bit_count == 32) { + bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); + file_header.offset_data = sizeof(BMPFileHeader) + + sizeof(BMPInfoHeader) + + sizeof(BMPColorHeader); + } else { + bmp_info_header.size = sizeof(BMPInfoHeader); + file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader); + } + file_header.file_size = file_header.offset_data; + + if (bmp_info_header.height < 0) { + return 52; // throw std::runtime_error("The program can treat only BMP + // images with the origin in the bottom left corner!"); + } + + data.resize(bmp_info_header.width * bmp_info_header.height * + bmp_info_header.bit_count / 8); + + // Here we check if we need to take into account row padding + if (bmp_info_header.width % 4 == 0) { + inp.read((char *)data.data(), data.size()); + file_header.file_size += static_cast(data.size()); + } else { + row_stride = bmp_info_header.width * bmp_info_header.bit_count / 8; + uint32_t new_stride = make_stride_aligned(4); + std::vector padding_row(new_stride - row_stride); + + for (int y = 0; y < bmp_info_header.height; ++y) { + inp.read((char *)(data.data() + row_stride * y), row_stride); + inp.read((char *)padding_row.data(), padding_row.size()); + } + file_header.file_size += + static_cast(data.size()) + + bmp_info_header.height * static_cast(padding_row.size()); + } + } else { + return 53; // throw std::runtime_error("Unable to open the input image + // file "+std::string(fname)); } - - int OrganizeAverageGreen() - { - int ColorRed[bmp_info_header.height][bmp_info_header.width]; - int ColorGreen[bmp_info_header.height][bmp_info_header.width];; - int ColorBlue[bmp_info_header.height][bmp_info_header.width]; - float pixels=bmp_info_header.height*bmp_info_header.width; - float intensity=0; - float sum=0; - uint32_t channels = bmp_info_header.bit_count / 8; - cout << "The Width of the image is " << bmp_info_header.width << endl; - cout << "The height of the image is " << bmp_info_header.height << endl; - for (int y = 0; y < bmp_info_header.height; ++y) { - for (int x = 0; x < bmp_info_header.width; ++x) { - //cout << channels*(y*bmp_info_header.width+x) << endl; - //Read Green - ColorBlue[y][x]=data[channels * (y * bmp_info_header.width + x) + 0]; - ColorGreen[y][x]=data[channels * (y * bmp_info_header.width + x) + 1]; - ColorRed[y][x]=data[channels * (y * bmp_info_header.width + x) + 2]; - } - } - for(int y=0; y buffer) { + std::stringstream inp; + std::copy(buffer.begin(), buffer.end(), + std::ostream_iterator(inp, "\n")); + if (inp) { + inp.read((char *)&file_header, sizeof(file_header)); + if (file_header.file_type != 0x4D42) { + + return 50; // throw std::runtime_error("Error! Unrecognized file + // format."); + } + inp.read((char *)&bmp_info_header, sizeof(bmp_info_header)); + + // The BMPColorHeader is used only for transparent images + if (bmp_info_header.bit_count == 32) { + // Check if the file has bit mask color information + if (bmp_info_header.size >= + (sizeof(BMPInfoHeader) + sizeof(BMPColorHeader))) { + inp.read((char *)&bmp_color_header, sizeof(bmp_color_header)); + // Check if the pixel data is stored as BGRA and if the color space + // type is sRGB + check_color_header(bmp_color_header); + } else { + // std::cerr << "Error! The file \"" << fname << "\" does not seem to + // contain bit mask information\n"; + return 51; // throw std::runtime_error("Error! Unrecognized file + // format."); } } - - intensity=sum/pixels; - cout << intensity << endl; - return intensity; - } - - int OrganizeAverageBlue() - { - int ColorRed[bmp_info_header.height][bmp_info_header.width]; - int ColorGreen[bmp_info_header.height][bmp_info_header.width];; - int ColorBlue[bmp_info_header.height][bmp_info_header.width]; - float pixels=bmp_info_header.height*bmp_info_header.width; - float intensity=0; - float sum=0; - uint32_t channels = bmp_info_header.bit_count / 8; - cout << "The Width of the image is " << bmp_info_header.width << endl; - cout << "The height of the image is " << bmp_info_header.height << endl; - for (int y = 0; y < bmp_info_header.height; ++y) { - for (int x = 0; x < bmp_info_header.width; ++x) { - //cout << channels*(y*bmp_info_header.width+x) << endl; - //Read Blue - ColorBlue[y][x]=data[channels * (y * bmp_info_header.width + x) + 0]; - ColorGreen[y][x]=data[channels * (y * bmp_info_header.width + x) + 1]; - ColorRed[y][x]=data[channels * (y * bmp_info_header.width + x) + 2]; - } - } - for(int y=0; y(data.size()); + } else { + row_stride = bmp_info_header.width * bmp_info_header.bit_count / 8; + uint32_t new_stride = make_stride_aligned(4); + std::vector padding_row(new_stride - row_stride); + + for (int y = 0; y < bmp_info_header.height; ++y) { + inp.read((char *)(data.data() + row_stride * y), row_stride); + inp.read((char *)padding_row.data(), padding_row.size()); + } + file_header.file_size += + static_cast(data.size()) + + bmp_info_header.height * static_cast(padding_row.size()); + } + } else { + return 53; // throw std::runtime_error("Unable to open the input image + // file "+std::string(fname)); + } + return 0; + } + + BMP(int32_t width, int32_t height, bool has_alpha = true) { + if (width <= 0 || height <= 0) { + width = 1; + height = 1; } - unsigned set_pixel(uint32_t x0, uint32_t y0, uint8_t B, uint8_t G, uint8_t R, uint8_t A) { - if (x0 >= (uint32_t)bmp_info_header.width || y0 >= (uint32_t)bmp_info_header.height || x0 < 0 || y0 < 0) { - return 59;//throw std::runtime_error("The point is outside the image boundaries!"); + bmp_info_header.width = width; + bmp_info_header.height = height; + if (has_alpha) { + bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); + file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + + sizeof(BMPColorHeader); + + bmp_info_header.bit_count = 32; + bmp_info_header.compression = 3; + row_stride = width * 4; + data.resize(row_stride * height); + file_header.file_size = file_header.offset_data + data.size(); + } else { + bmp_info_header.size = sizeof(BMPInfoHeader); + file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader); + + bmp_info_header.bit_count = 24; + bmp_info_header.compression = 0; + row_stride = width * 3; + data.resize(row_stride * height); + + uint32_t new_stride = make_stride_aligned(4); + file_header.file_size = + file_header.offset_data + static_cast(data.size()) + + bmp_info_header.height * (new_stride - row_stride); + } + } + + unsigned write(const char *fname) { + std::ofstream of{fname, std::ios_base::binary}; + if (of) { + if (bmp_info_header.bit_count == 32) { + write_headers_and_data(of); + } else if (bmp_info_header.bit_count == 24) { + if (bmp_info_header.width % 4 == 0) { + write_headers_and_data(of); + } else { + uint32_t new_stride = make_stride_aligned(4); + std::vector padding_row(new_stride - row_stride); + + write_headers(of); + + for (int y = 0; y < bmp_info_header.height; ++y) { + of.write((const char *)(data.data() + row_stride * y), row_stride); + of.write((const char *)padding_row.data(), padding_row.size()); + } } - uint32_t channels = bmp_info_header.bit_count / 8; - data[channels * (y0 * bmp_info_header.width + x0) + 0] = B; - data[channels * (y0 * bmp_info_header.width + x0) + 1] = G; - data[channels * (y0 * bmp_info_header.width + x0) + 2] = R; + } else { + return 54; // throw std::runtime_error("The program can treat only 24 or + // 32 bits per pixel BMP files"); + } + } else { + return 55; // throw std::runtime_error("Unable to open the output image + // file."); + } + return 0; + } + + std::vector DATA() { + std::stringstream ss; + if (ss) { + if (bmp_info_header.bit_count == 32) { + write_headers_and_datass(ss); + } else if (bmp_info_header.bit_count == 24) { + if (bmp_info_header.width % 4 == 0) { + write_headers_and_datass(ss); + } else { + uint32_t new_stride = make_stride_aligned(4); + std::vector padding_row(new_stride - row_stride); + + write_headersss(ss); + + for (int y = 0; y < bmp_info_header.height; ++y) { + ss.write((const char *)(data.data() + row_stride * y), row_stride); + ss.write((const char *)padding_row.data(), padding_row.size()); + } + } + } else { + } + } else { + } + std::string test11 = ss.str(); + std::vector test12(test11.begin(), test11.end()); + return test12; + } + + unsigned fill_region(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, + uint8_t B, uint8_t G, uint8_t R, uint8_t A) { + uint32_t channels = bmp_info_header.bit_count / 8; + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + /*if (x + w > (uint32_t)bmp_info_header.width || y + h > + (uint32_t)bmp_info_header.height) { + // + }*/ + // else{ + data[channels * (y * bmp_info_header.width + x) + 0] = B; + data[channels * (y * bmp_info_header.width + x) + 1] = G; + data[channels * (y * bmp_info_header.width + x) + 2] = R; if (channels == 4) { - data[channels * (y0 * bmp_info_header.width + x0) + 3] = A; + data[channels * (y * bmp_info_header.width + x) + 3] = A; } - return 0; + //} + } + } + return 0; + } + + void fill_region_df(uint32_t x1, uint32_t y1, uint32_t w, uint32_t h, + uint8_t B, uint8_t G, uint8_t R, uint8_t A) { + + int x0 = x1; + int y0 = this->bmp_info_header.height - y1 - h; + + uint32_t channels = bmp_info_header.bit_count / 8; + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + if ((x + w < (uint32_t)bmp_info_header.width) || + this->bmp_info_header.height - y - h > 0) { + + data[channels * (y * bmp_info_header.width + x) + 0] = B; + data[channels * (y * bmp_info_header.width + x) + 1] = G; + data[channels * (y * bmp_info_header.width + x) + 2] = R; + if (channels == 4) { + data[channels * (y * bmp_info_header.width + x) + 3] = A; + } + } + } + } + } + + void manipulate_region(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, + uint8_t A) { + int choice, choice2, intensity; + cout << "What color do you want to change? " << endl; + cout << "Enter 1 for Blue, 2 for Green, 3 for Red " << endl; + cin >> choice; + cout << "To what color do you want to change it too?" << endl; + cout << "Enter 1 for Blue, 2 for Green, 3 for Red " << endl; + cin >> choice2; + cout << "Enter the intensity of the color. (From 0 to 255) " << endl; + cin >> intensity; + if (x0 + w > (uint32_t)bmp_info_header.width || + y0 + h > (uint32_t)bmp_info_header.height) { + return; // throw std::runtime_error("The region does not fit in the + // image!"); } - void set_pixel_df(uint32_t x0, uint32_t y0, uint8_t B, uint8_t G, uint8_t R, uint8_t A) { - uint32_t y1 = this->bmp_info_header.height - y0; - if (x0 >= (uint32_t)bmp_info_header.width || y1 <= (uint32_t)bmp_info_header.width || x0 < 0 || y0 > 0) { - return;//throw std::runtime_error("The point is outside the image boundaries!"); + uint32_t channels = bmp_info_header.bit_count / 8; + if (choice == 1 && choice2 == 1) { + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + cout << channels * (y * bmp_info_header.width + x) << endl; + // Make blue thing blue + if (data[channels * (y * bmp_info_header.width + x) + 0] > 80 && + data[channels * (y * bmp_info_header.width + x) + 0] < 255) { + data[channels * (y * bmp_info_header.width + x) + 0] = intensity; + data[channels * (y * bmp_info_header.width + x) + 1] = 0; + data[channels * (y * bmp_info_header.width + x) + 2] = 0; + } + // data[channels * (y * bmp_info_header.width + x) + 0] = B; + // data[channels * (y * bmp_info_header.width + x) + 1] = G; + // data[channels * (y * bmp_info_header.width + x) + 2] = R; + if (channels == 4) { + data[channels * (y * bmp_info_header.width + x) + 3] = A; + } } - - uint32_t channels = bmp_info_header.bit_count / 8; - data[channels * (y0 * bmp_info_header.width + x0) + 0] = B; - data[channels * (y0 * bmp_info_header.width + x0) + 1] = G; - data[channels * (y0 * bmp_info_header.width + x0) + 2] = R; - if (channels == 4) { - data[channels * (y0 * bmp_info_header.width + x0) + 3] = A; + } + } + if (choice == 1 && choice2 == 2) { + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + cout << channels * (y * bmp_info_header.width + x) << endl; + // Make blue thing green + if (data[channels * (y * bmp_info_header.width + x) + 0] > 80 && + data[channels * (y * bmp_info_header.width + x) + 0] < 255) { + data[channels * (y * bmp_info_header.width + x) + 0] = 0; + data[channels * (y * bmp_info_header.width + x) + 1] = intensity; + data[channels * (y * bmp_info_header.width + x) + 2] = 0; + } + if (channels == 4) { + data[channels * (y * bmp_info_header.width + x) + 3] = A; + } } + } + } + if (choice == 1 && choice2 == 3) { + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + cout << channels * (y * bmp_info_header.width + x) << endl; + // Make blue thing red + if (data[channels * (y * bmp_info_header.width + x) + 0] > 80 && + data[channels * (y * bmp_info_header.width + x) + 0] < 255) { + data[channels * (y * bmp_info_header.width + x) + 0] = 0; + data[channels * (y * bmp_info_header.width + x) + 1] = 0; + data[channels * (y * bmp_info_header.width + x) + 2] = intensity; + } + if (channels == 4) { + data[channels * (y * bmp_info_header.width + x) + 3] = A; + } + } + } + } + if (choice == 2 && choice2 == 1) { + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + cout << channels * (y * bmp_info_header.width + x) << endl; + // Make green thing blue + if (data[channels * (y * bmp_info_header.width + x) + 1] > 80 && + data[channels * (y * bmp_info_header.width + x) + 1] < 255) { + data[channels * (y * bmp_info_header.width + x) + 0] = intensity; + data[channels * (y * bmp_info_header.width + x) + 1] = 0; + data[channels * (y * bmp_info_header.width + x) + 2] = 0; + } + if (channels == 4) { + data[channels * (y * bmp_info_header.width + x) + 3] = A; + } + } + } + } + if (choice == 2 && choice2 == 2) { + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + cout << channels * (y * bmp_info_header.width + x) << endl; + // Make green thing green + if (data[channels * (y * bmp_info_header.width + x) + 1] > 80 && + data[channels * (y * bmp_info_header.width + x) + 1] < 255) { + data[channels * (y * bmp_info_header.width + x) + 0] = 0; + data[channels * (y * bmp_info_header.width + x) + 1] = intensity; + data[channels * (y * bmp_info_header.width + x) + 2] = 0; + } + if (channels == 4) { + data[channels * (y * bmp_info_header.width + x) + 3] = A; + } + } + } + } + if (choice == 2 && choice2 == 3) { + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + cout << channels * (y * bmp_info_header.width + x) << endl; + // Make green thing red + if (data[channels * (y * bmp_info_header.width + x) + 1] > 80 && + data[channels * (y * bmp_info_header.width + x) + 1] < 255) { + data[channels * (y * bmp_info_header.width + x) + 0] = 0; + data[channels * (y * bmp_info_header.width + x) + 1] = 0; + data[channels * (y * bmp_info_header.width + x) + 2] = intensity; + } + if (channels == 4) { + data[channels * (y * bmp_info_header.width + x) + 3] = A; + } + } + } + } + if (choice == 3 && choice2 == 1) { + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + cout << channels * (y * bmp_info_header.width + x) << endl; + // Make red thing blue + if (data[channels * (y * bmp_info_header.width + x) + 2] > 80 && + data[channels * (y * bmp_info_header.width + x) + 2] < 255) { + data[channels * (y * bmp_info_header.width + x) + 0] = intensity; + data[channels * (y * bmp_info_header.width + x) + 1] = 0; + data[channels * (y * bmp_info_header.width + x) + 2] = 0; + } + if (channels == 4) { + data[channels * (y * bmp_info_header.width + x) + 3] = A; + } + } + } + } + if (choice == 3 && choice2 == 2) { + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + cout << channels * (y * bmp_info_header.width + x) << endl; + // Make red thing green + if (data[channels * (y * bmp_info_header.width + x) + 2] > 80 && + data[channels * (y * bmp_info_header.width + x) + 2] < 255) { + data[channels * (y * bmp_info_header.width + x) + 0] = 0; + data[channels * (y * bmp_info_header.width + x) + 1] = intensity; + data[channels * (y * bmp_info_header.width + x) + 2] = 0; + } + if (channels == 4) { + data[channels * (y * bmp_info_header.width + x) + 3] = A; + } + } + } + } + if (choice == 3 && choice2 == 3) { + for (uint32_t y = y0; y < y0 + h; ++y) { + for (uint32_t x = x0; x < x0 + w; ++x) { + cout << channels * (y * bmp_info_header.width + x) << endl; + // Make red thing blue + if (data[channels * (y * bmp_info_header.width + x) + 2] > 80 && + data[channels * (y * bmp_info_header.width + x) + 2] < 255) { + data[channels * (y * bmp_info_header.width + x) + 0] = 0; + data[channels * (y * bmp_info_header.width + x) + 1] = 0; + data[channels * (y * bmp_info_header.width + x) + 2] = intensity; + } + if (channels == 4) { + data[channels * (y * bmp_info_header.width + x) + 3] = A; + } + } + } + } + } + + int OrganizeAverageRed() { + int ColorRed[bmp_info_header.height][bmp_info_header.width]; + int ColorGreen[bmp_info_header.height][bmp_info_header.width]; + ; + int ColorBlue[bmp_info_header.height][bmp_info_header.width]; + float pixels = bmp_info_header.height * bmp_info_header.width; + float intensity = 0; + float sum = 0; + uint32_t channels = bmp_info_header.bit_count / 8; + cout << "The Width of the image is " << bmp_info_header.width << endl; + cout << "The height of the image is " << bmp_info_header.height << endl; + for (int y = 0; y < bmp_info_header.height; ++y) { + for (int x = 0; x < bmp_info_header.width; ++x) { + // cout << channels*(y*bmp_info_header.width+x) << endl; + // Read red + ColorBlue[y][x] = data[channels * (y * bmp_info_header.width + x) + 0]; + ColorGreen[y][x] = data[channels * (y * bmp_info_header.width + x) + 1]; + ColorRed[y][x] = data[channels * (y * bmp_info_header.width + x) + 2]; + } + } + for (int y = 0; y < bmp_info_header.height; y++) { + for (int x = 0; x < bmp_info_header.width; x++) { + sum = ColorRed[y][x] + sum - + ((ColorBlue[y][x]) / 2 + (ColorGreen[y][x]) / 2); + } } - unsigned draw_rectangle(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, - uint8_t B, uint8_t G, uint8_t R, uint8_t A, uint8_t line_w) { - if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) { - return 59;//throw std::runtime_error("The rectangle does not fit in the image!"); - } + intensity = sum / pixels; + cout << intensity << endl; + return intensity; + } - fill_region(x0, y0, w, line_w, B, G, R, A); // top line - fill_region(x0, (y0 + h - line_w), w, line_w, B, G, R, A); // bottom line - fill_region((x0 + w - line_w), (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // right line - fill_region(x0, (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // left line - return 0; + int OrganizeAverageGreen() { + int ColorRed[bmp_info_header.height][bmp_info_header.width]; + int ColorGreen[bmp_info_header.height][bmp_info_header.width]; + ; + int ColorBlue[bmp_info_header.height][bmp_info_header.width]; + float pixels = bmp_info_header.height * bmp_info_header.width; + float intensity = 0; + float sum = 0; + uint32_t channels = bmp_info_header.bit_count / 8; + cout << "The Width of the image is " << bmp_info_header.width << endl; + cout << "The height of the image is " << bmp_info_header.height << endl; + for (int y = 0; y < bmp_info_header.height; ++y) { + for (int x = 0; x < bmp_info_header.width; ++x) { + // cout << channels*(y*bmp_info_header.width+x) << endl; + // Read Green + ColorBlue[y][x] = data[channels * (y * bmp_info_header.width + x) + 0]; + ColorGreen[y][x] = data[channels * (y * bmp_info_header.width + x) + 1]; + ColorRed[y][x] = data[channels * (y * bmp_info_header.width + x) + 2]; + } + } + for (int y = 0; y < bmp_info_header.height; y++) { + for (int x = 0; x < bmp_info_header.width; x++) { + sum = ColorGreen[y][x] + sum - + ((ColorBlue[y][x]) / 2 + (ColorRed[y][x]) / 2); + } } - void draw_rectangle_df(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, - uint8_t B, uint8_t G, uint8_t R, uint8_t A, uint8_t line_w) { - if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) { - return;//throw std::runtime_error("The rectangle does not fit in the image!"); - } + intensity = sum / pixels; + cout << intensity << endl; + return intensity; + } - fill_region_df(x0, y0, w, line_w, B, G, R, A); // top line - fill_region_df(x0, (y0 + h - line_w), w, line_w, B, G, R, A); // bottom line - fill_region_df((x0 + w - line_w), (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // right line - fill_region_df(x0, (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // left line + int OrganizeAverageBlue() { + int ColorRed[bmp_info_header.height][bmp_info_header.width]; + int ColorGreen[bmp_info_header.height][bmp_info_header.width]; + ; + int ColorBlue[bmp_info_header.height][bmp_info_header.width]; + float pixels = bmp_info_header.height * bmp_info_header.width; + float intensity = 0; + float sum = 0; + uint32_t channels = bmp_info_header.bit_count / 8; + cout << "The Width of the image is " << bmp_info_header.width << endl; + cout << "The height of the image is " << bmp_info_header.height << endl; + for (int y = 0; y < bmp_info_header.height; ++y) { + for (int x = 0; x < bmp_info_header.width; ++x) { + // cout << channels*(y*bmp_info_header.width+x) << endl; + // Read Blue + ColorBlue[y][x] = data[channels * (y * bmp_info_header.width + x) + 0]; + ColorGreen[y][x] = data[channels * (y * bmp_info_header.width + x) + 1]; + ColorRed[y][x] = data[channels * (y * bmp_info_header.width + x) + 2]; + } } + for (int y = 0; y < bmp_info_header.height; y++) { + for (int x = 0; x < bmp_info_header.width; x++) { + sum = ColorBlue[y][x] + sum - + ((ColorGreen[y][x]) / 2 + (ColorRed[y][x]) / 2); + } + } + + intensity = sum / pixels; + cout << intensity << endl; + return intensity; + } + + unsigned set_pixel(uint32_t x0, uint32_t y0, uint8_t B, uint8_t G, uint8_t R, + uint8_t A) { + if (x0 >= (uint32_t)bmp_info_header.width || + y0 >= (uint32_t)bmp_info_header.height || x0 < 0 || y0 < 0) { + return 59; // throw std::runtime_error("The point is outside the image + // boundaries!"); + } + uint32_t channels = bmp_info_header.bit_count / 8; + data[channels * (y0 * bmp_info_header.width + x0) + 0] = B; + data[channels * (y0 * bmp_info_header.width + x0) + 1] = G; + data[channels * (y0 * bmp_info_header.width + x0) + 2] = R; + if (channels == 4) { + data[channels * (y0 * bmp_info_header.width + x0) + 3] = A; + } + return 0; + } + + void set_pixel_df(uint32_t x0, uint32_t y0, uint8_t B, uint8_t G, uint8_t R, + uint8_t A) { + uint32_t y1 = this->bmp_info_header.height - y0; + if (x0 >= (uint32_t)bmp_info_header.width || + y1 <= (uint32_t)bmp_info_header.width || x0 < 0 || y0 > 0) { + return; // throw std::runtime_error("The point is outside the image + // boundaries!"); + } + + uint32_t channels = bmp_info_header.bit_count / 8; + data[channels * (y0 * bmp_info_header.width + x0) + 0] = B; + data[channels * (y0 * bmp_info_header.width + x0) + 1] = G; + data[channels * (y0 * bmp_info_header.width + x0) + 2] = R; + if (channels == 4) { + data[channels * (y0 * bmp_info_header.width + x0) + 3] = A; + } + } + + unsigned draw_rectangle(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, + uint8_t B, uint8_t G, uint8_t R, uint8_t A, + uint8_t line_w) { + if (x0 + w > (uint32_t)bmp_info_header.width || + y0 + h > (uint32_t)bmp_info_header.height) { + return 59; // throw std::runtime_error("The rectangle does not fit in the + // image!"); + } + + fill_region(x0, y0, w, line_w, B, G, R, A); // top line + fill_region(x0, (y0 + h - line_w), w, line_w, B, G, R, A); // bottom line + fill_region((x0 + w - line_w), (y0 + line_w), line_w, (h - (2 * line_w)), B, + G, R, A); // right line + fill_region(x0, (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, + A); // left line + return 0; + } + + void draw_rectangle_df(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, + uint8_t B, uint8_t G, uint8_t R, uint8_t A, + uint8_t line_w) { + if (x0 + w > (uint32_t)bmp_info_header.width || + y0 + h > (uint32_t)bmp_info_header.height) { + return; // throw std::runtime_error("The rectangle does not fit in the + // image!"); + } + + fill_region_df(x0, y0, w, line_w, B, G, R, A); // top line + fill_region_df(x0, (y0 + h - line_w), w, line_w, B, G, R, A); // bottom line + fill_region_df((x0 + w - line_w), (y0 + line_w), line_w, (h - (2 * line_w)), + B, G, R, A); // right line + fill_region_df(x0, (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, + A); // left line + } private: - uint32_t row_stride{ 0 }; + uint32_t row_stride{0}; - void write_headers(std::ofstream &of) { - of.write((const char*)&file_header, sizeof(file_header)); - of.write((const char*)&bmp_info_header, sizeof(bmp_info_header)); - if(bmp_info_header.bit_count == 32) { - of.write((const char*)&bmp_color_header, sizeof(bmp_color_header)); - } + void write_headers(std::ofstream &of) { + of.write((const char *)&file_header, sizeof(file_header)); + of.write((const char *)&bmp_info_header, sizeof(bmp_info_header)); + if (bmp_info_header.bit_count == 32) { + of.write((const char *)&bmp_color_header, sizeof(bmp_color_header)); } + } - void write_headers_and_data(std::ofstream &of) { - write_headers(of); - of.write((const char*)data.data(), data.size()); - } + void write_headers_and_data(std::ofstream &of) { + write_headers(of); + of.write((const char *)data.data(), data.size()); + } - void write_headersss(std::stringstream &of) { - of.write((const char*)&file_header, sizeof(file_header)); - of.write((const char*)&bmp_info_header, sizeof(bmp_info_header)); - if(bmp_info_header.bit_count == 32) { - of.write((const char*)&bmp_color_header, sizeof(bmp_color_header)); - } + void write_headersss(std::stringstream &of) { + of.write((const char *)&file_header, sizeof(file_header)); + of.write((const char *)&bmp_info_header, sizeof(bmp_info_header)); + if (bmp_info_header.bit_count == 32) { + of.write((const char *)&bmp_color_header, sizeof(bmp_color_header)); } + } - void write_headers_and_datass(std::stringstream &of) { - write_headersss(of); - of.write((const char*)data.data(), data.size()); - } + void write_headers_and_datass(std::stringstream &of) { + write_headersss(of); + of.write((const char *)data.data(), data.size()); + } - // Add 1 to the row_stride until it is divisible with align_stride - uint32_t make_stride_aligned(uint32_t align_stride) { - uint32_t new_stride = row_stride; - while (new_stride % align_stride != 0) { - new_stride++; - } - return new_stride; + // Add 1 to the row_stride until it is divisible with align_stride + uint32_t make_stride_aligned(uint32_t align_stride) { + uint32_t new_stride = row_stride; + while (new_stride % align_stride != 0) { + new_stride++; } + return new_stride; + } - // Check if the pixel data is stored as BGRA and if the color space type is sRGB - void check_color_header(BMPColorHeader &bmp_color_header) { - BMPColorHeader expected_color_header; - if(expected_color_header.red_mask != bmp_color_header.red_mask || - expected_color_header.blue_mask != bmp_color_header.blue_mask || - expected_color_header.green_mask != bmp_color_header.green_mask || - expected_color_header.alpha_mask != bmp_color_header.alpha_mask) { - return;//throw std::runtime_error("Unexpected color mask format! The program expects the pixel data to be in the BGRA format"); - } - if(expected_color_header.color_space_type != bmp_color_header.color_space_type) { - return;//throw std::runtime_error("Unexpected color space type! The program expects sRGB values"); - } + // Check if the pixel data is stored as BGRA and if the color space type is + // sRGB + void check_color_header(BMPColorHeader &bmp_color_header) { + BMPColorHeader expected_color_header; + if (expected_color_header.red_mask != bmp_color_header.red_mask || + expected_color_header.blue_mask != bmp_color_header.blue_mask || + expected_color_header.green_mask != bmp_color_header.green_mask || + expected_color_header.alpha_mask != bmp_color_header.alpha_mask) { + return; // throw std::runtime_error("Unexpected color mask format! The + // program expects the pixel data to be in the BGRA format"); } + if (expected_color_header.color_space_type != + bmp_color_header.color_space_type) { + return; // throw std::runtime_error("Unexpected color space type! The + // program expects sRGB values"); + } + } }; \ No newline at end of file diff --git a/include/renderd7/bmpconverter.hpp b/include/renderd7/bmpconverter.hpp index d549035..c770795 100644 --- a/include/renderd7/bmpconverter.hpp +++ b/include/renderd7/bmpconverter.hpp @@ -3,12 +3,14 @@ #include -namespace BitmapConverter{ -//returns 0 if all went ok, non-0 if error -//output image is always given in RGBA (with alpha channel), even if it's a BMP without alpha channel -unsigned decodeBMP(std::vector& image, unsigned& w, unsigned& h, const std::vector& bmp); +namespace BitmapConverter { +// returns 0 if all went ok, non-0 if error +// output image is always given in RGBA (with alpha channel), even if it's a BMP +// without alpha channel +unsigned decodeBMP(std::vector &image, unsigned &w, unsigned &h, + const std::vector &bmp); std::vector ConvertFile(std::string filename); std::vector ConvertData(std::vector data); -} \ No newline at end of file +} // namespace BitmapConverter \ No newline at end of file diff --git a/include/renderd7/debugfont.h b/include/renderd7/debugfont.h index b494f83..39ba043 100644 --- a/include/renderd7/debugfont.h +++ b/include/renderd7/debugfont.h @@ -8,134 +8,177 @@ Visit http://www.devkitpro.org #define _debugfont_h_ //--------------------------------------------------------------------------------- static const unsigned char debugfont[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, - 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, - 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x3c, 0x3c, 0x18, 0xff, 0xe7, 0x18, 0x3c, 0x00, - 0x10, 0x38, 0x7c, 0xfe, 0xee, 0x10, 0x38, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, - 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, - 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, - 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x08, 0x0c, 0x0a, 0x0a, 0x08, 0x78, 0xf0, 0x00, - 0x18, 0x14, 0x1a, 0x16, 0x72, 0xe2, 0x0e, 0x1c, 0x10, 0x54, 0x38, 0xee, 0x38, 0x54, 0x10, 0x00, - 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, - 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, - 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x00, 0x1c, 0x22, 0x38, 0x44, 0x44, 0x38, 0x88, 0x70, - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x7e, - 0x18, 0x3c, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x5a, 0x3c, 0x18, 0x00, - 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x42, 0xff, 0x42, 0x24, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, - 0x6c, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, - 0x10, 0x7c, 0xd0, 0x7c, 0x16, 0xfc, 0x10, 0x00, 0x00, 0x66, 0xac, 0xd8, 0x36, 0x6a, 0xcc, 0x00, - 0x38, 0x4c, 0x38, 0x78, 0xce, 0xcc, 0x7a, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, - 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00, - 0x7c, 0xce, 0xde, 0xf6, 0xe6, 0xe6, 0x7c, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x7e, 0x00, - 0x7c, 0xc6, 0x06, 0x1c, 0x70, 0xc6, 0xfe, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, - 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfe, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, - 0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00, 0xfe, 0xc6, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, - 0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, - 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, - 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, - 0x7c, 0x82, 0x9e, 0xa6, 0x9e, 0x80, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, - 0xfc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, - 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xce, 0xc6, 0x7e, 0x00, - 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, - 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, - 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x82, 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, - 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, - 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x06, - 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0xc6, 0xc0, 0x7c, 0x06, 0xc6, 0x7c, 0x00, - 0x7e, 0x5a, 0x5a, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, - 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x82, 0x00, - 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00, - 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, - 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, - 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x00, - 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, - 0x1c, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x78, - 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, - 0x00, 0x0c, 0x00, 0x1c, 0x0c, 0x0c, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, - 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xd6, 0xd6, 0xd6, 0x00, - 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, - 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, - 0x00, 0x00, 0xde, 0x76, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x7c, 0x06, 0x7c, 0x00, - 0x10, 0x30, 0xfc, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, - 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, - 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x0e, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0e, 0x00, - 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xe0, 0x00, - 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, - 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x70, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, - 0x0e, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x7c, 0x82, 0x38, 0x0c, 0x7c, 0xcc, 0x76, 0x00, - 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, - 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0xc0, 0x7c, 0x18, 0x70, - 0x7c, 0x82, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, - 0xe0, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, - 0x7c, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, - 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x38, 0x38, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, - 0x0e, 0x10, 0xfe, 0x60, 0x78, 0x60, 0xfe, 0x00, 0x00, 0x00, 0x7c, 0x12, 0x7e, 0xd0, 0x7e, 0x00, - 0x7e, 0xc8, 0xc8, 0xfe, 0xc8, 0xc8, 0xce, 0x00, 0x7c, 0x82, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, - 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0xe0, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, - 0x7c, 0x82, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, - 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, - 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x18, 0x7c, 0xd6, 0xd0, 0xd6, 0x7c, 0x18, 0x00, - 0x38, 0x6c, 0x60, 0xf0, 0x60, 0xf2, 0xdc, 0x00, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x00, - 0xf8, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0x06, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, - 0x0e, 0x10, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x0e, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, - 0x0e, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x0e, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, - 0x66, 0x98, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x98, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00, - 0x38, 0x0c, 0x3c, 0x34, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, - 0x30, 0x00, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc0, 0xc8, 0xd0, 0xfe, 0x46, 0x8c, 0x1e, 0x00, - 0xc0, 0xc8, 0xd0, 0xec, 0x5c, 0xbe, 0x0c, 0x00, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x00, - 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, - 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, - 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, - 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, - 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x74, 0xcc, 0xc8, 0xdc, 0x76, 0x00, 0x78, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xdc, 0x40, - 0xfe, 0x62, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x02, 0x7e, 0xec, 0x6c, 0x6c, 0x48, 0x00, - 0xfe, 0x62, 0x30, 0x18, 0x30, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x7e, 0xd0, 0xc8, 0xc8, 0x70, 0x00, - 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xf8, 0x80, 0x00, 0x00, 0x7e, 0xd8, 0x18, 0x18, 0x10, 0x00, - 0x38, 0x10, 0x7c, 0xd6, 0xd6, 0x7c, 0x10, 0x38, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, - 0x7c, 0xc6, 0xc6, 0xc6, 0x6c, 0x28, 0xee, 0x00, 0x3c, 0x22, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0x66, 0x99, 0x99, 0x66, 0x00, 0x00, 0x00, 0x06, 0x7c, 0x9e, 0xf2, 0x7c, 0xc0, 0x00, - 0x00, 0x00, 0x7c, 0xc0, 0xf8, 0xc0, 0x7c, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, - 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00, - 0x30, 0x18, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x00, - 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, - 0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, - 0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x00, - 0xd8, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0xc0, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, + 0xbd, 0x99, 0x81, 0x7e, 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, + 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x10, 0x38, 0x7c, 0xfe, + 0x7c, 0x38, 0x10, 0x00, 0x3c, 0x3c, 0x18, 0xff, 0xe7, 0x18, 0x3c, 0x00, + 0x10, 0x38, 0x7c, 0xfe, 0xee, 0x10, 0x38, 0x00, 0x00, 0x00, 0x18, 0x3c, + 0x3c, 0x18, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, + 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0xff, 0xc3, 0x99, 0xbd, + 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, + 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x08, 0x0c, 0x0a, 0x0a, + 0x08, 0x78, 0xf0, 0x00, 0x18, 0x14, 0x1a, 0x16, 0x72, 0xe2, 0x0e, 0x1c, + 0x10, 0x54, 0x38, 0xee, 0x38, 0x54, 0x10, 0x00, 0x80, 0xe0, 0xf8, 0xfe, + 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, + 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x00, 0x66, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x00, + 0x1c, 0x22, 0x38, 0x44, 0x44, 0x38, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x7e, + 0x18, 0x3c, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, + 0x5a, 0x3c, 0x18, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, + 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x42, 0xff, 0x42, 0x24, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, + 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, 0x6c, 0x24, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, + 0x10, 0x7c, 0xd0, 0x7c, 0x16, 0xfc, 0x10, 0x00, 0x00, 0x66, 0xac, 0xd8, + 0x36, 0x6a, 0xcc, 0x00, 0x38, 0x4c, 0x38, 0x78, 0xce, 0xcc, 0x7a, 0x00, + 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, + 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00, + 0x7c, 0xce, 0xde, 0xf6, 0xe6, 0xe6, 0x7c, 0x00, 0x18, 0x38, 0x78, 0x18, + 0x18, 0x18, 0x7e, 0x00, 0x7c, 0xc6, 0x06, 0x1c, 0x70, 0xc6, 0xfe, 0x00, + 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x1c, 0x3c, 0x6c, 0xcc, + 0xfe, 0x0c, 0x1e, 0x00, 0xfe, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, + 0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00, 0xfe, 0xc6, 0x0c, 0x18, + 0x30, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00, + 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, + 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x7e, 0x00, + 0x00, 0x7e, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, + 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, 0x7c, 0x82, 0x9e, 0xa6, + 0x9e, 0x80, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, + 0xc0, 0xc6, 0x7c, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0xfe, 0x62, 0x68, 0x78, + 0x68, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xce, 0xc6, 0x7e, 0x00, + 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x3c, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x3c, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, + 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0xf0, 0x60, 0x60, 0x60, + 0x62, 0x66, 0xfe, 0x00, 0x82, 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, + 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0x7c, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x06, 0xfc, 0x66, 0x66, 0x7c, + 0x66, 0x66, 0xe6, 0x00, 0x7c, 0xc6, 0xc0, 0x7c, 0x06, 0xc6, 0x7c, 0x00, + 0x7e, 0x5a, 0x5a, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, + 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x82, 0x00, 0xc6, 0x6c, 0x38, 0x38, + 0x38, 0x6c, 0xc6, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00, + 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x78, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, + 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0x10, 0x38, 0x6c, 0xc6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, + 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x00, 0x1c, 0x0c, 0x0c, 0x7c, + 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, + 0x1c, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x76, 0xcc, + 0xcc, 0x7c, 0x0c, 0x78, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, + 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x0c, 0x00, 0x1c, + 0x0c, 0x0c, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, + 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0xcc, 0xfe, + 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xdc, 0x66, + 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, + 0x00, 0x00, 0xde, 0x76, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, + 0x7c, 0x06, 0x7c, 0x00, 0x10, 0x30, 0xfc, 0x30, 0x30, 0x34, 0x18, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0xc6, 0xc6, + 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, + 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, + 0xcc, 0x7c, 0x0c, 0xf8, 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, + 0x0e, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0e, 0x00, 0x18, 0x18, 0x18, 0x00, + 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xe0, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, + 0xc6, 0xc6, 0xfe, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x70, + 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x0e, 0x10, 0x7c, 0xc6, + 0xfe, 0xc0, 0x7c, 0x00, 0x7c, 0x82, 0x38, 0x0c, 0x7c, 0xcc, 0x76, 0x00, + 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0x78, 0x0c, + 0x7c, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x7c, 0xc0, 0xc0, 0x7c, 0x18, 0x70, 0x7c, 0x82, 0x7c, 0xc6, + 0xfe, 0xc0, 0x7c, 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, + 0xe0, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x66, 0x00, 0x38, 0x18, + 0x18, 0x18, 0x3c, 0x00, 0x7c, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, + 0xe0, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xc6, 0x00, 0x7c, 0xc6, + 0xfe, 0xc6, 0xc6, 0x00, 0x38, 0x38, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, + 0x0e, 0x10, 0xfe, 0x60, 0x78, 0x60, 0xfe, 0x00, 0x00, 0x00, 0x7c, 0x12, + 0x7e, 0xd0, 0x7e, 0x00, 0x7e, 0xc8, 0xc8, 0xfe, 0xc8, 0xc8, 0xce, 0x00, + 0x7c, 0x82, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0xc6, 0x00, 0x7c, 0xc6, + 0xc6, 0xc6, 0x7c, 0x00, 0xe0, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, + 0x7c, 0x82, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0xcc, 0xcc, + 0xcc, 0xcc, 0x76, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0xc6, 0x00, 0xc6, 0xc6, + 0xc6, 0xc6, 0x7c, 0x00, 0x18, 0x7c, 0xd6, 0xd0, 0xd6, 0x7c, 0x18, 0x00, + 0x38, 0x6c, 0x60, 0xf0, 0x60, 0xf2, 0xdc, 0x00, 0x66, 0x3c, 0x18, 0x7e, + 0x18, 0x7e, 0x18, 0x00, 0xf8, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0x06, + 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, 0x0e, 0x10, 0x78, 0x0c, + 0x7c, 0xcc, 0x76, 0x00, 0x0e, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, + 0x0e, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x0e, 0x10, 0xcc, 0xcc, + 0xcc, 0xcc, 0x76, 0x00, 0x66, 0x98, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, + 0x66, 0x98, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00, 0x38, 0x0c, 0x3c, 0x34, + 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, + 0x30, 0x00, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, + 0xc0, 0xc8, 0xd0, 0xfe, 0x46, 0x8c, 0x1e, 0x00, 0xc0, 0xc8, 0xd0, 0xec, + 0x5c, 0xbe, 0x0c, 0x00, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x00, + 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, + 0x6c, 0xd8, 0x00, 0x00, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0xdb, 0x77, 0xdb, 0xee, + 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, + 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x00, 0x00, 0xf8, 0x18, + 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, + 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x18, 0x18, 0xf8, 0x18, + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, + 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x3f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xcc, 0xc8, 0xdc, 0x76, 0x00, + 0x78, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xdc, 0x40, 0xfe, 0x62, 0x60, 0x60, + 0x60, 0x60, 0xf0, 0x00, 0x00, 0x02, 0x7e, 0xec, 0x6c, 0x6c, 0x48, 0x00, + 0xfe, 0x62, 0x30, 0x18, 0x30, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x7e, 0xd0, + 0xc8, 0xc8, 0x70, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xf8, 0x80, + 0x00, 0x00, 0x7e, 0xd8, 0x18, 0x18, 0x10, 0x00, 0x38, 0x10, 0x7c, 0xd6, + 0xd6, 0x7c, 0x10, 0x38, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, + 0x7c, 0xc6, 0xc6, 0xc6, 0x6c, 0x28, 0xee, 0x00, 0x3c, 0x22, 0x18, 0x7c, + 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x66, 0x99, 0x99, 0x66, 0x00, 0x00, + 0x00, 0x06, 0x7c, 0x9e, 0xf2, 0x7c, 0xc0, 0x00, 0x00, 0x00, 0x7c, 0xc0, + 0xf8, 0xc0, 0x7c, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, + 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, + 0x18, 0x00, 0x7e, 0x00, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x00, + 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x00, 0x0e, 0x1b, 0x1b, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, + 0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x00, + 0xd8, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0xc0, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const int debugfont_size = sizeof(debugfont); diff --git a/include/renderd7/ini.hpp b/include/renderd7/ini.hpp index fa1d606..acd8e67 100644 --- a/include/renderd7/ini.hpp +++ b/include/renderd7/ini.hpp @@ -1,679 +1,545 @@ #ifndef INI_INI_H_ #define INI_INI_H_ -#include -#include #include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include -namespace INI -{ - namespace INIStringUtil - { - const char* const whitespaceDelimiters = " \t\n\r\f\v"; - inline void trim(std::string& str) - { - str.erase(str.find_last_not_of(whitespaceDelimiters) + 1); - str.erase(0, str.find_first_not_of(whitespaceDelimiters)); - } -#ifndef INI_CASE_SENSITIVE - inline void toLower(std::string& str) - { - std::transform(str.begin(), str.end(), str.begin(), [](const char c) { - return static_cast(std::tolower(c)); - }); - } -#endif - inline void replace(std::string& str, std::string const& a, std::string const& b) - { - if (!a.empty()) - { - std::size_t pos = 0; - while ((pos = str.find(a, pos)) != std::string::npos) - { - str.replace(pos, a.size(), b); - pos += b.size(); - } - } - } -#ifdef _WIN32 - const char* const endl = "\r\n"; -#else - const char* const endl = "\n"; -#endif - }; - - template - class INIMap - { - private: - using T_DataIndexMap = std::unordered_map; - using T_DataItem = std::pair; - using T_DataContainer = std::vector; - using T_MultiArgs = typename std::vector>; - - T_DataIndexMap dataIndexMap; - T_DataContainer data; - - inline std::size_t setEmpty(std::string& key) - { - std::size_t index = data.size(); - dataIndexMap[key] = index; - data.emplace_back(key, T()); - return index; - } - - public: - using const_iterator = typename T_DataContainer::const_iterator; - - INIMap() { } - - INIMap(INIMap const& other) - { - std::size_t data_size = other.data.size(); - for (std::size_t i = 0; i < data_size; ++i) - { - auto const& key = other.data[i].first; - auto const& obj = other.data[i].second; - data.emplace_back(key, obj); - } - dataIndexMap = T_DataIndexMap(other.dataIndexMap); - } - - T& operator[](std::string key) - { - INIStringUtil::trim(key); -#ifndef INI_CASE_SENSITIVE - INIStringUtil::toLower(key); -#endif - auto it = dataIndexMap.find(key); - bool hasIt = (it != dataIndexMap.end()); - std::size_t index = (hasIt) ? it->second : setEmpty(key); - return data[index].second; - } - T get(std::string key) const - { - INIStringUtil::trim(key); -#ifndef INI_CASE_SENSITIVE - INIStringUtil::toLower(key); -#endif - auto it = dataIndexMap.find(key); - if (it == dataIndexMap.end()) - { - return T(); - } - return T(data[it->second].second); - } - bool has(std::string key) const - { - INIStringUtil::trim(key); -#ifndef INI_CASE_SENSITIVE - INIStringUtil::toLower(key); -#endif - return (dataIndexMap.count(key) == 1); - } - void set(std::string key, T obj) - { - INIStringUtil::trim(key); -#ifndef INI_CASE_SENSITIVE - INIStringUtil::toLower(key); -#endif - auto it = dataIndexMap.find(key); - if (it != dataIndexMap.end()) - { - data[it->second].second = obj; - } - else - { - dataIndexMap[key] = data.size(); - data.emplace_back(key, obj); - } - } - void set(T_MultiArgs const& multiArgs) - { - for (auto const& it : multiArgs) - { - auto const& key = it.first; - auto const& obj = it.second; - set(key, obj); - } - } - bool remove(std::string key) - { - INIStringUtil::trim(key); -#ifndef INI_CASE_SENSITIVE - INIStringUtil::toLower(key); -#endif - auto it = dataIndexMap.find(key); - if (it != dataIndexMap.end()) - { - std::size_t index = it->second; - data.erase(data.begin() + index); - dataIndexMap.erase(it); - for (auto& it2 : dataIndexMap) - { - auto& vi = it2.second; - if (vi > index) - { - vi--; - } - } - return true; - } - return false; - } - void clear() - { - data.clear(); - dataIndexMap.clear(); - } - std::size_t size() const - { - return data.size(); - } - const_iterator begin() const { return data.begin(); } - const_iterator end() const { return data.end(); } - }; - - using INIStructure = INIMap>; - - namespace INIParser - { - using T_ParseValues = std::pair; - - enum class PDataType : char - { - PDATA_NONE, - PDATA_COMMENT, - PDATA_SECTION, - PDATA_KEYVALUE, - PDATA_UNKNOWN - }; - - inline PDataType parseLine(std::string line, T_ParseValues& parseData) - { - parseData.first.clear(); - parseData.second.clear(); - INIStringUtil::trim(line); - if (line.empty()) - { - return PDataType::PDATA_NONE; - } - char firstCharacter = line[0]; - if (firstCharacter == ';') - { - return PDataType::PDATA_COMMENT; - } - if (firstCharacter == '[') - { - auto commentAt = line.find_first_of(';'); - if (commentAt != std::string::npos) - { - line = line.substr(0, commentAt); - } - auto closingBracketAt = line.find_last_of(']'); - if (closingBracketAt != std::string::npos) - { - auto section = line.substr(1, closingBracketAt - 1); - INIStringUtil::trim(section); - parseData.first = section; - return PDataType::PDATA_SECTION; - } - } - auto lineNorm = line; - INIStringUtil::replace(lineNorm, "\\=", " "); - auto equalsAt = lineNorm.find_first_of('='); - if (equalsAt != std::string::npos) - { - auto key = line.substr(0, equalsAt); - INIStringUtil::trim(key); - INIStringUtil::replace(key, "\\=", "="); - auto value = line.substr(equalsAt + 1); - INIStringUtil::trim(value); - parseData.first = key; - parseData.second = value; - return PDataType::PDATA_KEYVALUE; - } - return PDataType::PDATA_UNKNOWN; - } - }; - - class INIReader - { - public: - using T_LineData = std::vector; - using T_LineDataPtr = std::shared_ptr; - - private: - std::ifstream fileReadStream; - T_LineDataPtr lineData; - - T_LineData readFile() - { - std::string fileContents; - fileReadStream.seekg(0, std::ios::end); - fileContents.resize(fileReadStream.tellg()); - fileReadStream.seekg(0, std::ios::beg); - std::size_t fileSize = fileContents.size(); - fileReadStream.read(&fileContents[0], fileSize); - fileReadStream.close(); - T_LineData output; - if (fileSize == 0) - { - return output; - } - std::string buffer; - buffer.reserve(50); - for (std::size_t i = 0; i < fileSize; ++i) - { - char& c = fileContents[i]; - if (c == '\n') - { - output.emplace_back(buffer); - buffer.clear(); - continue; - } - if (c != '\0' && c != '\r') - { - buffer += c; - } - } - output.emplace_back(buffer); - return output; - } - - public: - INIReader(std::string const& filename, bool keepLineData = false) - { - fileReadStream.open(filename, std::ios::in | std::ios::binary); - if (keepLineData) - { - lineData = std::make_shared(); - } - } - ~INIReader() { } - - bool operator>>(INIStructure& data) - { - if (!fileReadStream.is_open()) - { - return false; - } - T_LineData fileLines = readFile(); - std::string section; - bool inSection = false; - INIParser::T_ParseValues parseData; - for (auto const& line : fileLines) - { - auto parseResult = INIParser::parseLine(line, parseData); - if (parseResult == INIParser::PDataType::PDATA_SECTION) - { - inSection = true; - data[section = parseData.first]; - } - else if (inSection && parseResult == INIParser::PDataType::PDATA_KEYVALUE) - { - auto const& key = parseData.first; - auto const& value = parseData.second; - data[section][key] = value; - } - if (lineData && parseResult != INIParser::PDataType::PDATA_UNKNOWN) - { - if (parseResult == INIParser::PDataType::PDATA_KEYVALUE && !inSection) - { - continue; - } - lineData->emplace_back(line); - } - } - return true; - } - T_LineDataPtr getLines() - { - return lineData; - } - }; - - class INIGenerator - { - private: - std::ofstream fileWriteStream; - - public: - bool prettyPrint = false; - - INIGenerator(std::string const& filename) - { - fileWriteStream.open(filename, std::ios::out | std::ios::binary); - } - ~INIGenerator() { } - - bool operator<<(INIStructure const& data) - { - if (!fileWriteStream.is_open()) - { - return false; - } - if (!data.size()) - { - return true; - } - auto it = data.begin(); - for (;;) - { - auto const& section = it->first; - auto const& collection = it->second; - fileWriteStream - << "[" - << section - << "]"; - if (collection.size()) - { - fileWriteStream << INIStringUtil::endl; - auto it2 = collection.begin(); - for (;;) - { - auto key = it2->first; - INIStringUtil::replace(key, "=", "\\="); - auto value = it2->second; - INIStringUtil::trim(value); - fileWriteStream - << key - << ((prettyPrint) ? " = " : "=") - << value; - if (++it2 == collection.end()) - { - break; - } - fileWriteStream << INIStringUtil::endl; - } - } - if (++it == data.end()) - { - break; - } - fileWriteStream << INIStringUtil::endl; - if (prettyPrint) - { - fileWriteStream << INIStringUtil::endl; - } - } - return true; - } - }; - - class INIWriter - { - private: - using T_LineData = std::vector; - using T_LineDataPtr = std::shared_ptr; - - std::string filename; - - T_LineData getLazyOutput(T_LineDataPtr const& lineData, INIStructure& data, INIStructure& original) - { - T_LineData output; - INIParser::T_ParseValues parseData; - std::string sectionCurrent; - bool parsingSection = false; - bool continueToNextSection = false; - bool discardNextEmpty = false; - bool writeNewKeys = false; - std::size_t lastKeyLine = 0; - for (auto line = lineData->begin(); line != lineData->end(); ++line) - { - if (!writeNewKeys) - { - auto parseResult = INIParser::parseLine(*line, parseData); - if (parseResult == INIParser::PDataType::PDATA_SECTION) - { - if (parsingSection) - { - writeNewKeys = true; - parsingSection = false; - --line; - continue; - } - sectionCurrent = parseData.first; - if (data.has(sectionCurrent)) - { - parsingSection = true; - continueToNextSection = false; - discardNextEmpty = false; - output.emplace_back(*line); - lastKeyLine = output.size(); - } - else - { - continueToNextSection = true; - discardNextEmpty = true; - continue; - } - } - else if (parseResult == INIParser::PDataType::PDATA_KEYVALUE) - { - if (continueToNextSection) - { - continue; - } - if (data.has(sectionCurrent)) - { - auto& collection = data[sectionCurrent]; - auto const& key = parseData.first; - auto const& value = parseData.second; - if (collection.has(key)) - { - auto outputValue = collection[key]; - if (value == outputValue) - { - output.emplace_back(*line); - } - else - { - INIStringUtil::trim(outputValue); - auto lineNorm = *line; - INIStringUtil::replace(lineNorm, "\\=", " "); - auto equalsAt = lineNorm.find_first_of('='); - auto valueAt = lineNorm.find_first_not_of( - INIStringUtil::whitespaceDelimiters, - equalsAt + 1 - ); - std::string outputLine = line->substr(0, valueAt); - if (prettyPrint && equalsAt + 1 == valueAt) - { - outputLine += " "; - } - outputLine += outputValue; - output.emplace_back(outputLine); - } - lastKeyLine = output.size(); - } - } - } - else - { - if (discardNextEmpty && line->empty()) - { - discardNextEmpty = false; - } - else if (parseResult != INIParser::PDataType::PDATA_UNKNOWN) - { - output.emplace_back(*line); - } - } - } - if (writeNewKeys || std::next(line) == lineData->end()) - { - T_LineData linesToAdd; - if (data.has(sectionCurrent) && original.has(sectionCurrent)) - { - auto const& collection = data[sectionCurrent]; - auto const& collectionOriginal = original[sectionCurrent]; - for (auto const& it : collection) - { - auto key = it.first; - if (collectionOriginal.has(key)) - { - continue; - } - auto value = it.second; - INIStringUtil::replace(key, "=", "\\="); - INIStringUtil::trim(value); - linesToAdd.emplace_back( - key + ((prettyPrint) ? " = " : "=") + value - ); - } - } - if (!linesToAdd.empty()) - { - output.insert( - output.begin() + lastKeyLine, - linesToAdd.begin(), - linesToAdd.end() - ); - } - if (writeNewKeys) - { - writeNewKeys = false; - --line; - } - } - } - for (auto const& it : data) - { - auto const& section = it.first; - if (original.has(section)) - { - continue; - } - if (prettyPrint && output.size() > 0 && !output.back().empty()) - { - output.emplace_back(); - } - output.emplace_back("[" + section + "]"); - auto const& collection = it.second; - for (auto const& it2 : collection) - { - auto key = it2.first; - auto value = it2.second; - INIStringUtil::replace(key, "=", "\\="); - INIStringUtil::trim(value); - output.emplace_back( - key + ((prettyPrint) ? " = " : "=") + value - ); - } - } - return output; - } - - public: - bool prettyPrint = false; - - INIWriter(std::string const& filename) - : filename(filename) - { - } - ~INIWriter() { } - - bool operator<<(INIStructure& data) - { - struct stat buf; - bool fileExists = (stat(filename.c_str(), &buf) == 0); - if (!fileExists) - { - INIGenerator generator(filename); - generator.prettyPrint = prettyPrint; - return generator << data; - } - INIStructure originalData; - T_LineDataPtr lineData; - bool readSuccess = false; - { - INIReader reader(filename, true); - if ((readSuccess = reader >> originalData)) - { - lineData = reader.getLines(); - } - } - if (!readSuccess) - { - return false; - } - T_LineData output = getLazyOutput(lineData, data, originalData); - std::ofstream fileWriteStream(filename, std::ios::out | std::ios::binary); - if (fileWriteStream.is_open()) - { - if (output.size()) - { - auto line = output.begin(); - for (;;) - { - fileWriteStream << *line; - if (++line == output.end()) - { - break; - } - fileWriteStream << INIStringUtil::endl; - } - } - return true; - } - return false; - } - }; - - class INIFile - { - private: - std::string filename; - - public: - INIFile(std::string const& filename) - : filename(filename) - { } - - ~INIFile() { } - - bool read(INIStructure& data) const - { - if (data.size()) - { - data.clear(); - } - if (filename.empty()) - { - return false; - } - INIReader reader(filename); - return reader >> data; - } - bool generate(INIStructure const& data, bool pretty = false) const - { - if (filename.empty()) - { - return false; - } - INIGenerator generator(filename); - generator.prettyPrint = pretty; - return generator << data; - } - bool write(INIStructure& data, bool pretty = false) const - { - if (filename.empty()) - { - return false; - } - INIWriter writer(filename); - writer.prettyPrint = pretty; - return writer << data; - } - }; +namespace INI { +namespace INIStringUtil { +const char *const whitespaceDelimiters = " \t\n\r\f\v"; +inline void trim(std::string &str) { + str.erase(str.find_last_not_of(whitespaceDelimiters) + 1); + str.erase(0, str.find_first_not_of(whitespaceDelimiters)); } +#ifndef INI_CASE_SENSITIVE +inline void toLower(std::string &str) { + std::transform(str.begin(), str.end(), str.begin(), [](const char c) { + return static_cast(std::tolower(c)); + }); +} +#endif +inline void replace(std::string &str, std::string const &a, + std::string const &b) { + if (!a.empty()) { + std::size_t pos = 0; + while ((pos = str.find(a, pos)) != std::string::npos) { + str.replace(pos, a.size(), b); + pos += b.size(); + } + } +} +#ifdef _WIN32 +const char *const endl = "\r\n"; +#else +const char *const endl = "\n"; +#endif +}; // namespace INIStringUtil + +template class INIMap { +private: + using T_DataIndexMap = std::unordered_map; + using T_DataItem = std::pair; + using T_DataContainer = std::vector; + using T_MultiArgs = typename std::vector>; + + T_DataIndexMap dataIndexMap; + T_DataContainer data; + + inline std::size_t setEmpty(std::string &key) { + std::size_t index = data.size(); + dataIndexMap[key] = index; + data.emplace_back(key, T()); + return index; + } + +public: + using const_iterator = typename T_DataContainer::const_iterator; + + INIMap() {} + + INIMap(INIMap const &other) { + std::size_t data_size = other.data.size(); + for (std::size_t i = 0; i < data_size; ++i) { + auto const &key = other.data[i].first; + auto const &obj = other.data[i].second; + data.emplace_back(key, obj); + } + dataIndexMap = T_DataIndexMap(other.dataIndexMap); + } + + T &operator[](std::string key) { + INIStringUtil::trim(key); +#ifndef INI_CASE_SENSITIVE + INIStringUtil::toLower(key); +#endif + auto it = dataIndexMap.find(key); + bool hasIt = (it != dataIndexMap.end()); + std::size_t index = (hasIt) ? it->second : setEmpty(key); + return data[index].second; + } + T get(std::string key) const { + INIStringUtil::trim(key); +#ifndef INI_CASE_SENSITIVE + INIStringUtil::toLower(key); +#endif + auto it = dataIndexMap.find(key); + if (it == dataIndexMap.end()) { + return T(); + } + return T(data[it->second].second); + } + bool has(std::string key) const { + INIStringUtil::trim(key); +#ifndef INI_CASE_SENSITIVE + INIStringUtil::toLower(key); +#endif + return (dataIndexMap.count(key) == 1); + } + void set(std::string key, T obj) { + INIStringUtil::trim(key); +#ifndef INI_CASE_SENSITIVE + INIStringUtil::toLower(key); +#endif + auto it = dataIndexMap.find(key); + if (it != dataIndexMap.end()) { + data[it->second].second = obj; + } else { + dataIndexMap[key] = data.size(); + data.emplace_back(key, obj); + } + } + void set(T_MultiArgs const &multiArgs) { + for (auto const &it : multiArgs) { + auto const &key = it.first; + auto const &obj = it.second; + set(key, obj); + } + } + bool remove(std::string key) { + INIStringUtil::trim(key); +#ifndef INI_CASE_SENSITIVE + INIStringUtil::toLower(key); +#endif + auto it = dataIndexMap.find(key); + if (it != dataIndexMap.end()) { + std::size_t index = it->second; + data.erase(data.begin() + index); + dataIndexMap.erase(it); + for (auto &it2 : dataIndexMap) { + auto &vi = it2.second; + if (vi > index) { + vi--; + } + } + return true; + } + return false; + } + void clear() { + data.clear(); + dataIndexMap.clear(); + } + std::size_t size() const { return data.size(); } + const_iterator begin() const { return data.begin(); } + const_iterator end() const { return data.end(); } +}; + +using INIStructure = INIMap>; + +namespace INIParser { +using T_ParseValues = std::pair; + +enum class PDataType : char { + PDATA_NONE, + PDATA_COMMENT, + PDATA_SECTION, + PDATA_KEYVALUE, + PDATA_UNKNOWN +}; + +inline PDataType parseLine(std::string line, T_ParseValues &parseData) { + parseData.first.clear(); + parseData.second.clear(); + INIStringUtil::trim(line); + if (line.empty()) { + return PDataType::PDATA_NONE; + } + char firstCharacter = line[0]; + if (firstCharacter == ';') { + return PDataType::PDATA_COMMENT; + } + if (firstCharacter == '[') { + auto commentAt = line.find_first_of(';'); + if (commentAt != std::string::npos) { + line = line.substr(0, commentAt); + } + auto closingBracketAt = line.find_last_of(']'); + if (closingBracketAt != std::string::npos) { + auto section = line.substr(1, closingBracketAt - 1); + INIStringUtil::trim(section); + parseData.first = section; + return PDataType::PDATA_SECTION; + } + } + auto lineNorm = line; + INIStringUtil::replace(lineNorm, "\\=", " "); + auto equalsAt = lineNorm.find_first_of('='); + if (equalsAt != std::string::npos) { + auto key = line.substr(0, equalsAt); + INIStringUtil::trim(key); + INIStringUtil::replace(key, "\\=", "="); + auto value = line.substr(equalsAt + 1); + INIStringUtil::trim(value); + parseData.first = key; + parseData.second = value; + return PDataType::PDATA_KEYVALUE; + } + return PDataType::PDATA_UNKNOWN; +} +}; // namespace INIParser + +class INIReader { +public: + using T_LineData = std::vector; + using T_LineDataPtr = std::shared_ptr; + +private: + std::ifstream fileReadStream; + T_LineDataPtr lineData; + + T_LineData readFile() { + std::string fileContents; + fileReadStream.seekg(0, std::ios::end); + fileContents.resize(fileReadStream.tellg()); + fileReadStream.seekg(0, std::ios::beg); + std::size_t fileSize = fileContents.size(); + fileReadStream.read(&fileContents[0], fileSize); + fileReadStream.close(); + T_LineData output; + if (fileSize == 0) { + return output; + } + std::string buffer; + buffer.reserve(50); + for (std::size_t i = 0; i < fileSize; ++i) { + char &c = fileContents[i]; + if (c == '\n') { + output.emplace_back(buffer); + buffer.clear(); + continue; + } + if (c != '\0' && c != '\r') { + buffer += c; + } + } + output.emplace_back(buffer); + return output; + } + +public: + INIReader(std::string const &filename, bool keepLineData = false) { + fileReadStream.open(filename, std::ios::in | std::ios::binary); + if (keepLineData) { + lineData = std::make_shared(); + } + } + ~INIReader() {} + + bool operator>>(INIStructure &data) { + if (!fileReadStream.is_open()) { + return false; + } + T_LineData fileLines = readFile(); + std::string section; + bool inSection = false; + INIParser::T_ParseValues parseData; + for (auto const &line : fileLines) { + auto parseResult = INIParser::parseLine(line, parseData); + if (parseResult == INIParser::PDataType::PDATA_SECTION) { + inSection = true; + data[section = parseData.first]; + } else if (inSection && + parseResult == INIParser::PDataType::PDATA_KEYVALUE) { + auto const &key = parseData.first; + auto const &value = parseData.second; + data[section][key] = value; + } + if (lineData && parseResult != INIParser::PDataType::PDATA_UNKNOWN) { + if (parseResult == INIParser::PDataType::PDATA_KEYVALUE && !inSection) { + continue; + } + lineData->emplace_back(line); + } + } + return true; + } + T_LineDataPtr getLines() { return lineData; } +}; + +class INIGenerator { +private: + std::ofstream fileWriteStream; + +public: + bool prettyPrint = false; + + INIGenerator(std::string const &filename) { + fileWriteStream.open(filename, std::ios::out | std::ios::binary); + } + ~INIGenerator() {} + + bool operator<<(INIStructure const &data) { + if (!fileWriteStream.is_open()) { + return false; + } + if (!data.size()) { + return true; + } + auto it = data.begin(); + for (;;) { + auto const §ion = it->first; + auto const &collection = it->second; + fileWriteStream << "[" << section << "]"; + if (collection.size()) { + fileWriteStream << INIStringUtil::endl; + auto it2 = collection.begin(); + for (;;) { + auto key = it2->first; + INIStringUtil::replace(key, "=", "\\="); + auto value = it2->second; + INIStringUtil::trim(value); + fileWriteStream << key << ((prettyPrint) ? " = " : "=") << value; + if (++it2 == collection.end()) { + break; + } + fileWriteStream << INIStringUtil::endl; + } + } + if (++it == data.end()) { + break; + } + fileWriteStream << INIStringUtil::endl; + if (prettyPrint) { + fileWriteStream << INIStringUtil::endl; + } + } + return true; + } +}; + +class INIWriter { +private: + using T_LineData = std::vector; + using T_LineDataPtr = std::shared_ptr; + + std::string filename; + + T_LineData getLazyOutput(T_LineDataPtr const &lineData, INIStructure &data, + INIStructure &original) { + T_LineData output; + INIParser::T_ParseValues parseData; + std::string sectionCurrent; + bool parsingSection = false; + bool continueToNextSection = false; + bool discardNextEmpty = false; + bool writeNewKeys = false; + std::size_t lastKeyLine = 0; + for (auto line = lineData->begin(); line != lineData->end(); ++line) { + if (!writeNewKeys) { + auto parseResult = INIParser::parseLine(*line, parseData); + if (parseResult == INIParser::PDataType::PDATA_SECTION) { + if (parsingSection) { + writeNewKeys = true; + parsingSection = false; + --line; + continue; + } + sectionCurrent = parseData.first; + if (data.has(sectionCurrent)) { + parsingSection = true; + continueToNextSection = false; + discardNextEmpty = false; + output.emplace_back(*line); + lastKeyLine = output.size(); + } else { + continueToNextSection = true; + discardNextEmpty = true; + continue; + } + } else if (parseResult == INIParser::PDataType::PDATA_KEYVALUE) { + if (continueToNextSection) { + continue; + } + if (data.has(sectionCurrent)) { + auto &collection = data[sectionCurrent]; + auto const &key = parseData.first; + auto const &value = parseData.second; + if (collection.has(key)) { + auto outputValue = collection[key]; + if (value == outputValue) { + output.emplace_back(*line); + } else { + INIStringUtil::trim(outputValue); + auto lineNorm = *line; + INIStringUtil::replace(lineNorm, "\\=", " "); + auto equalsAt = lineNorm.find_first_of('='); + auto valueAt = lineNorm.find_first_not_of( + INIStringUtil::whitespaceDelimiters, equalsAt + 1); + std::string outputLine = line->substr(0, valueAt); + if (prettyPrint && equalsAt + 1 == valueAt) { + outputLine += " "; + } + outputLine += outputValue; + output.emplace_back(outputLine); + } + lastKeyLine = output.size(); + } + } + } else { + if (discardNextEmpty && line->empty()) { + discardNextEmpty = false; + } else if (parseResult != INIParser::PDataType::PDATA_UNKNOWN) { + output.emplace_back(*line); + } + } + } + if (writeNewKeys || std::next(line) == lineData->end()) { + T_LineData linesToAdd; + if (data.has(sectionCurrent) && original.has(sectionCurrent)) { + auto const &collection = data[sectionCurrent]; + auto const &collectionOriginal = original[sectionCurrent]; + for (auto const &it : collection) { + auto key = it.first; + if (collectionOriginal.has(key)) { + continue; + } + auto value = it.second; + INIStringUtil::replace(key, "=", "\\="); + INIStringUtil::trim(value); + linesToAdd.emplace_back(key + ((prettyPrint) ? " = " : "=") + + value); + } + } + if (!linesToAdd.empty()) { + output.insert(output.begin() + lastKeyLine, linesToAdd.begin(), + linesToAdd.end()); + } + if (writeNewKeys) { + writeNewKeys = false; + --line; + } + } + } + for (auto const &it : data) { + auto const §ion = it.first; + if (original.has(section)) { + continue; + } + if (prettyPrint && output.size() > 0 && !output.back().empty()) { + output.emplace_back(); + } + output.emplace_back("[" + section + "]"); + auto const &collection = it.second; + for (auto const &it2 : collection) { + auto key = it2.first; + auto value = it2.second; + INIStringUtil::replace(key, "=", "\\="); + INIStringUtil::trim(value); + output.emplace_back(key + ((prettyPrint) ? " = " : "=") + value); + } + } + return output; + } + +public: + bool prettyPrint = false; + + INIWriter(std::string const &filename) : filename(filename) {} + ~INIWriter() {} + + bool operator<<(INIStructure &data) { + struct stat buf; + bool fileExists = (stat(filename.c_str(), &buf) == 0); + if (!fileExists) { + INIGenerator generator(filename); + generator.prettyPrint = prettyPrint; + return generator << data; + } + INIStructure originalData; + T_LineDataPtr lineData; + bool readSuccess = false; + { + INIReader reader(filename, true); + if ((readSuccess = reader >> originalData)) { + lineData = reader.getLines(); + } + } + if (!readSuccess) { + return false; + } + T_LineData output = getLazyOutput(lineData, data, originalData); + std::ofstream fileWriteStream(filename, std::ios::out | std::ios::binary); + if (fileWriteStream.is_open()) { + if (output.size()) { + auto line = output.begin(); + for (;;) { + fileWriteStream << *line; + if (++line == output.end()) { + break; + } + fileWriteStream << INIStringUtil::endl; + } + } + return true; + } + return false; + } +}; + +class INIFile { +private: + std::string filename; + +public: + INIFile(std::string const &filename) : filename(filename) {} + + ~INIFile() {} + + bool read(INIStructure &data) const { + if (data.size()) { + data.clear(); + } + if (filename.empty()) { + return false; + } + INIReader reader(filename); + return reader >> data; + } + bool generate(INIStructure const &data, bool pretty = false) const { + if (filename.empty()) { + return false; + } + INIGenerator generator(filename); + generator.prettyPrint = pretty; + return generator << data; + } + bool write(INIStructure &data, bool pretty = false) const { + if (filename.empty()) { + return false; + } + INIWriter writer(filename); + writer.prettyPrint = pretty; + return writer << data; + } +}; +} // namespace INI #endif diff --git a/include/renderd7/lang.hpp b/include/renderd7/lang.hpp index 9bca5cb..f114ff9 100644 --- a/include/renderd7/lang.hpp +++ b/include/renderd7/lang.hpp @@ -1,16 +1,15 @@ #pragma once -#include #include +#include /// RenderD7::Lang -namespace RenderD7::Lang -{ - /// Get the 3ds System Language - std::string getSys(); - /// Get a translated string - /// \param key The Key so the code can find your string - std::string get(const std::string &key); - /// Load the lang file from dir structure en/app.json for sample - /// \param lang the folder name en, fr, de ... . I prefer geSys() - void load(const std::string &lang); -} /// RenderD7::Lang +namespace RenderD7::Lang { +/// Get the 3ds System Language +std::string getSys(); +/// Get a translated string +/// \param key The Key so the code can find your string +std::string get(const std::string &key); +/// Load the lang file from dir structure en/app.json for sample +/// \param lang the folder name en, fr, de ... . I prefer geSys() +void load(const std::string &lang); +} // namespace RenderD7::Lang diff --git a/include/renderd7/log.hpp b/include/renderd7/log.hpp index 7209311..e43c5e1 100644 --- a/include/renderd7/log.hpp +++ b/include/renderd7/log.hpp @@ -6,25 +6,25 @@ #include /** Log Class */ -class Log -{ - public: - /** Construct */ - Log(); - /** Deconstruct */ - ~Log(); - /// Init the log file - /// \param filename name for the file - void Init(const char *filename); - /// Write Text to logfile - /// \param debug_text your text - void Write(std::string debug_text); - /// Get the date - std::string logDate(void); - /// Format to logstyle - /// \param fmt_str the formatted style - std::string format(const std::string& fmt_str, ...); - private: - /// \param filename the name of the logfile - std::string filename; +class Log { +public: + /** Construct */ + Log(); + /** Deconstruct */ + ~Log(); + /// Init the log file + /// \param filename name for the file + void Init(const char *filename); + /// Write Text to logfile + /// \param debug_text your text + void Write(std::string debug_text); + /// Get the date + std::string logDate(void); + /// Format to logstyle + /// \param fmt_str the formatted style + std::string format(const std::string &fmt_str, ...); + +private: + /// \param filename the name of the logfile + std::string filename; }; diff --git a/include/renderd7/parameter.hpp b/include/renderd7/parameter.hpp index 8b2cd73..4040d89 100644 --- a/include/renderd7/parameter.hpp +++ b/include/renderd7/parameter.hpp @@ -1,112 +1,118 @@ #pragma once #include -namespace RenderD7{ - class Parameter - { - private: - using id = size_t; +namespace RenderD7 { +class Parameter { +private: + using id = size_t; - template - struct type { static void id() { } }; + template struct type { + static void id() {} + }; - template - static id type_id() { return reinterpret_cast(&type::id); } + template static id type_id() { + return reinterpret_cast(&type::id); + } - template - using decay = typename std::decay::type; + template using decay = typename std::decay::type; - template - using none = typename std::enable_if::value>::type; + template + using none = + typename std::enable_if::value>::type; - struct base - { - virtual ~base() { } - virtual bool is(id) const = 0; - virtual base *copy() const = 0; - } *p = nullptr; + struct base { + virtual ~base() {} + virtual bool is(id) const = 0; + virtual base *copy() const = 0; + } *p = nullptr; - template - struct data : base, std::tuple - { - using std::tuple::tuple; + template struct data : base, std::tuple { + using std::tuple::tuple; - T &get() & { return std::get<0>(*this); } - T const &get() const& { return std::get<0>(*this); } + T &get() & { return std::get<0>(*this); } + T const &get() const & { return std::get<0>(*this); } - bool is(id i) const override { return i == type_id(); } - base *copy() const override { return new data{get()}; } - }; + bool is(id i) const override { return i == type_id(); } + base *copy() const override { return new data{get()}; } + }; - template - T &stat() { return static_cast&>(*p).get(); } + template T &stat() { return static_cast &>(*p).get(); } - template - T const &stat() const { return static_cast const&>(*p).get(); } + template T const &stat() const { + return static_cast const &>(*p).get(); + } - template - T &dyn() { return dynamic_cast&>(*p).get(); } + template T &dyn() { return dynamic_cast &>(*p).get(); } - template - T const &dyn() const { return dynamic_cast const&>(*p).get(); } + template T const &dyn() const { + return dynamic_cast const &>(*p).get(); + } - public: - /** - * @brief Default constructor - */ - Parameter() { } +public: + /** + * @brief Default constructor + */ + Parameter() {} - /** - * @brief Destructs the Parameter - */ - ~Parameter() { delete p; } + /** + * @brief Destructs the Parameter + */ + ~Parameter() { delete p; } - /** - * @brief Copy constructor - * @param s The Parameter to copy - */ - Parameter(Parameter &&s) : p{s.p} { s.p = nullptr; } + /** + * @brief Copy constructor + * @param s The Parameter to copy + */ + Parameter(Parameter &&s) : p{s.p} { s.p = nullptr; } - /** - * @brief Const copy constructor - * @param s The Parameter to copy - */ - Parameter(Parameter const &s) : p{s.p->copy()} { } + /** + * @brief Const copy constructor + * @param s The Parameter to copy + */ + Parameter(Parameter const &s) : p{s.p->copy()} {} - /** - * @brief Initializes the Parameter with the given value - * @param x The value to initialize the Parameter with - */ - template, typename = none> - Parameter(T &&x) : p{new data{std::forward(x)}} { } + /** + * @brief Initializes the Parameter with the given value + * @param x The value to initialize the Parameter with + */ + template , typename = none> + Parameter(T &&x) : p{new data{std::forward(x)}} {} - /** - * @brief Overloads the assignment operator - * @param s The value to set the Parameter to - */ - Parameter &operator=(Parameter s) { swap(*this, s); return *this; } + /** + * @brief Overloads the assignment operator + * @param s The value to set the Parameter to + */ + Parameter &operator=(Parameter s) { + swap(*this, s); + return *this; + } - friend void swap(Parameter &s, Parameter &r) { std::swap(s.p, r.p); } + friend void swap(Parameter &s, Parameter &r) { std::swap(s.p, r.p); } - /** - * @brief Clears the Parameter - */ - void clear() { delete p; p = nullptr; } + /** + * @brief Clears the Parameter + */ + void clear() { + delete p; + p = nullptr; + } - /** - * @brief Checks whether the Parameter is the given type - * @tparam T The type to check - * @return Whether the Parameter has the given type or not - */ - template - bool is() const { return p ? p->is(type_id()) : false; } + /** + * @brief Checks whether the Parameter is the given type + * @tparam T The type to check + * @return Whether the Parameter has the given type or not + */ + template bool is() const { + return p ? p->is(type_id()) : false; + } - /** - * @brief Returns the value of the Parameter - * @tparam T The type of the Parameter - * @return The value of the Parameter - * @warning If the type of the Parameter doesn't match the type of it's stored value, it will result in undefined behaviour. - */ - template T &get() & { return stat(); } - }; -} + /** + * @brief Returns the value of the Parameter + * @tparam T The type of the Parameter + * @return The value of the Parameter + * @warning If the type of the Parameter doesn't match the type of it's stored + * value, it will result in undefined behaviour. + */ + template T &get() & { return stat(); } +}; +} // namespace RenderD7 diff --git a/include/renderd7/renderd7.hpp b/include/renderd7/renderd7.hpp index 5c90abe..d053a1b 100644 --- a/include/renderd7/renderd7.hpp +++ b/include/renderd7/renderd7.hpp @@ -1,54 +1,63 @@ #pragma once #include <3ds.h> +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include + #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include #include +#include +#include +#include #include #include -#include -#include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -extern "C" -{ - #include + +extern "C" { +#include } #define RENDERD7VSTRING "0.8.0" -#define CHANGELOG "0.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: Add the New Overlay Handler. Its Just in code and does nothing yet. \n0.7.0: Made Big Progress In the MT Ovl but it still crashes On a Scnd C3D_FrameEnd(). Implement 800px but doesn't work that good. \n0.6.2: Fix Crash when exiting trouth Home Menu. \n0.6.10: rewrite Threadsystem, Improve framerate\n0.6.02: Fix Code in lang.hpp\nadd Draw Text Left Function.\nadd changelog\n0.6.01: add Threading system." +#define CHANGELOG \ + "0.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: " \ + "Add the New Overlay Handler. Its Just in code and does nothing yet. " \ + "\n0.7.0: Made Big Progress In the MT Ovl but it still crashes On a Scnd " \ + "C3D_FrameEnd(). Implement 800px but doesn't work that good. \n0.6.2: Fix " \ + "Crash when exiting trouth Home Menu. \n0.6.10: rewrite Threadsystem, " \ + "Improve framerate\n0.6.02: Fix Code in lang.hpp\nadd Draw Text Left " \ + "Function.\nadd changelog\n0.6.01: add Threading system." #define DEFAULT_CENTER 0.5f /*extern C3D_RenderTarget* Top; @@ -63,220 +72,211 @@ extern touchPosition d7_touch; extern std::string dspststus; /// RenderD7 -namespace RenderD7 +namespace RenderD7 { +float GetDeltaTime(); +enum kbd { SWKBD, BKBD }; +enum kbd_type { NUMPAD, STANDARD }; +struct TObject { + int x; // Position X + int y; // Position Y + int w; // Button Width + int h; // Button Height + std::string text = ""; // Text + float correctx = 0; // Correct X Position + float correcty = 0; // Correct Y Position + float txtsize = 0.7f; // Set Text Size +}; + +class Scene { +public: + static std::stack> scenes; + virtual ~Scene() {} + virtual void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) = 0; + virtual void Draw() const = 0; + // virtual void Ovl() const = 0; + static void Load(std::unique_ptr scene, bool fade = false); + static void Back(); + static void doDraw(); + static void doLogic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch); + // static void HandleOvl(); +}; + +class RSettings : public RenderD7::Scene { +private: + enum RState { RSETTINGS, RINFO }; + RenderD7::RSettings::RState m_state = RenderD7::RSettings::RState::RSETTINGS; + + std::string rd7srstate = "false"; + std::string csvstate = "false"; + std::string mtovlstate = "false"; + std::string fpsstate = "60"; + std::string mtscreenstate = "Top"; + std::string mttxtcolstate = "#ffffff"; + std::string mtcola = "255"; + std::string mttxtcola = "255"; + + std::vector buttons = { + {20, 35, 120, 35, "RD7SR", -11, 10}, + {20, 85, 120, 35, "MT_CSV", -15, 9}, + {20, 135, 120, 35, "MT_OVL", -19, 10}, + {20, 185, 120, 35, "FPS", 6, 10}, + {180, 35, 120, 35, "MTSCREEN", -29, 10}, + {180, 85, 120, 35, "DSPERR", -13, 10}, + {180, 135, 120, 35, "INFO", 2, 10}, + {180, 185, 120, 35, "", -13, 10}}; + +public: + RSettings(); + void Draw(void) const override; + ~RSettings(); + void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) override; +}; + +void LoadSettings(); + +class DSP_NF : public RenderD7::Ovl { +public: + DSP_NF(); + void Draw(void) const override; + void Logic() override; + +private: + int msgposy = 240; + int delay = 0; +}; + +int GetRandomInt(int b, int e); +void DrawMetrikOvl(); +bool DrawImageFromSheet(RenderD7::Sheet *sheet, size_t index, float x, float y, + float scaleX = 1.0, float scaleY = 1.0); +namespace Error { +void DisplayError(std::string toptext, std::string errortext, int timesec = 3); +void DisplayFatalError(std::string toptext, std::string errortext); +} // namespace Error +namespace Init { +Result Main(std::string app_name = "RD7Game"); +Result Reload(); +void Graphics(); +void NdspFirm(bool useit = false); +} // namespace Init +namespace Exit { +void Main(); +void NdspFirm(); +void Graphics(); +} // namespace Exit +namespace Msg { +void Display(std::string titletxt, std::string subtext, + C3D_RenderTarget *target); +void DisplayWithProgress(std::string titletext, std::string subtext, + float current, float total, u32 prgbarcolor); +} // namespace Msg + +namespace Convert { +inline float StringtoFloat(std::string inp) { return std::atof(inp.c_str()); } +inline int StringtoInt(std::string inp) { return std::atoi(inp.c_str()); } +inline bool FloatToBool(float inp) { + if (inp == 1) + return true; + else + return false; +} +} // namespace Convert + +struct DirContent { + std::string name; + std::string path; + bool isDir; +}; + +namespace FS { +bool FileExist(const std::string &path); +} + +bool IsNdspInit(); +void SetupLog(void); +std::string GetFramerate(); +bool MainLoop(); +void ExitApp(); + +void ClearTextBufs(void); + +std::string Kbd(int lenght, SwkbdType tp); + +void FrameEnd(); +void ToggleRD7SR(); +bool IsRD7SR(); + +struct TLBtn { + int x; // Position X + int y; // Position Y + int w; // Button Width + int h; // Button Height +}; + +struct ScrollList1 { + std::string Text = ""; +}; + +struct ScrollList2 { + float x; + float y; + float w; + float h; + std::string Text = ""; +}; +/*enum ListType { - float GetDeltaTime(); - enum kbd{ - SWKBD, - BKBD - }; - enum kbd_type - { - NUMPAD, - STANDARD - }; - struct TObject - { - int x; //Position X - int y; //Position Y - int w; //Button Width - int h; //Button Height - std::string text = ""; //Text - float correctx = 0; //Correct X Position - float correcty = 0; //Correct Y Position - float txtsize = 0.7f; //Set Text Size - }; + ONE, + TWO +};*/ +void DrawList1(RenderD7::ScrollList1 &l, float txtsize, C3D_RenderTarget *t); +void DrawTObjects(std::vector tobjects, u32 color, + u32 txtcolor, int selection = -1, + u32 selbgcolor = RenderD7::Color::Hex("#2D98AF"), + u32 selcolor = RenderD7::Color::Hex("#000000")); +void DrawSTObject(std::vector tobject, int tobjectindex, + u32 color, u32 txtcolor); +bool touchTObj(touchPosition touch, RenderD7::TObject button); +bool touchTLBtn(touchPosition touch, RenderD7::TLBtn button); +void DrawTLBtns(std::vector btns, u32 color, + int selection = -1, + u32 selbgcolor = RenderD7::Color::Hex("#2D98AF"), + u32 selcolor = RenderD7::Color::Hex("#000000")); - class Scene { - public: - static std::stack> scenes; - virtual ~Scene() {} - virtual void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) = 0; - virtual void Draw() const = 0; - //virtual void Ovl() const = 0; - static void Load(std::unique_ptr scene, bool fade = false); - static void Back(); - static void doDraw(); - static void doLogic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch); - //static void HandleOvl(); - }; +struct Checkbox { + float x, y, s; + bool is_chexked = false; + u32 outcol, incol, chcol; +}; +void DrawCheckbox(Checkbox box); - class RSettings : public RenderD7::Scene - { - private: - enum RState { - RSETTINGS, - RINFO - }; - RenderD7::RSettings::RState m_state = RenderD7::RSettings::RState::RSETTINGS; +class Console { +public: + Console(); + Console(int x, int y, int w, int h, u8 a = 255); + Console(int x, int y, int w, int h, RenderD7::Color::rgba col); + Console(int x, int y, int w, int h, std::string name, + RenderD7::Color::rgba col = {255, 255, 255, 255}, + RenderD7::Color::rgba barcol = {0, 0, 0, 255}, + RenderD7::Color::rgba outlinecol = {222, 222, 222, 255}); + void On(C3D_RenderTarget *t_cscreen); + bool Update(); + ~Console(); - std::string rd7srstate = "false"; - std::string csvstate = "false"; - std::string mtovlstate = "false"; - std::string fpsstate = "60"; - std::string mtscreenstate = "Top"; - std::string mttxtcolstate = "#ffffff"; - std::string mtcola = "255"; - std::string mttxtcola = "255"; +private: + std::vector m_lines; + int x, y, w, h; + std::string m_name = ""; + C3D_RenderTarget *cscreen; + bool m_nconsole = false; + bool m_mconsole = false; + RenderD7::Color::rgba color = {255, 255, 255, 255}; + RenderD7::Color::rgba outlinecol = {222, 222, 222, 255}; + RenderD7::Color::rgba barcolor = {0, 0, 0, 255}; +}; - - std::vector buttons = - { - {20, 35, 120, 35, "RD7SR", -11, 10}, - {20, 85, 120, 35, "MT_CSV", -15, 9}, - {20, 135, 120, 35, "MT_OVL", -19, 10}, - {20, 185, 120, 35, "FPS", 6, 10}, - {180, 35, 120, 35, "MTSCREEN", -29, 10}, - {180, 85, 120, 35, "DSPERR", -13, 10}, - {180, 135, 120, 35, "INFO", 2, 10}, - {180, 185, 120, 35, "", -13, 10} - }; - public: - RSettings(); - void Draw(void) const override; - ~RSettings(); - void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) override; - }; +void GetDirContentsExt(std::vector &dircontent, + const std::vector &extensions); +void GetDirContents(std::vector &dircontent); - void LoadSettings(); - - class DSP_NF : public RenderD7::Ovl - { - public: - DSP_NF(); - void Draw(void) const override; - void Logic() override; - private: - int msgposy = 240; - int delay = 0; - }; - - - int GetRandomInt(int b, int e); - void DrawMetrikOvl(); - bool DrawImageFromSheet(RenderD7::Sheet* sheet, size_t index, float x, float y, float scaleX = 1.0, float scaleY = 1.0); - namespace Error - { - void DisplayError(std::string toptext, std::string errortext, int timesec = 3); - void DisplayFatalError(std::string toptext, std::string errortext); - } - namespace Init - { - Result Main(std::string app_name = "RD7Game"); - Result Reload(); - void Graphics(); - void NdspFirm(bool useit = false); - } - namespace Exit - { - void Main(); - void NdspFirm(); - void Graphics(); - } - namespace Msg - { - void Display(std::string titletxt, std::string subtext, C3D_RenderTarget *target); - void DisplayWithProgress(std::string titletext, std::string subtext, float current, float total, u32 prgbarcolor); - } - - namespace Convert - { - inline float StringtoFloat(std::string inp){return std::atof(inp.c_str());} - inline int StringtoInt(std::string inp){return std::atoi(inp.c_str());} - inline bool FloatToBool(float inp){if(inp == 1)return true; else return false;} - } - - struct DirContent - { - std::string name; - std::string path; - bool isDir; - }; - - namespace FS - { - bool FileExist(const std::string& path); - } - - bool IsNdspInit(); - void SetupLog(void); - std::string GetFramerate(); - bool MainLoop(); - void ExitApp(); - - void ClearTextBufs(void); - - std::string Kbd(int lenght, SwkbdType tp); - - void FrameEnd(); - void ToggleRD7SR(); - bool IsRD7SR(); - - - struct TLBtn - { - int x; //Position X - int y; //Position Y - int w; //Button Width - int h; //Button Height - }; - - struct ScrollList1 - { - std::string Text = ""; - }; - - struct ScrollList2 - { - float x; - float y; - float w; - float h; - std::string Text = ""; - }; - /*enum ListType - { - ONE, - TWO - };*/ - void DrawList1(RenderD7::ScrollList1 &l, float txtsize, C3D_RenderTarget *t); - void DrawTObjects(std::vector tobjects, u32 color, u32 txtcolor, int selection = -1, u32 selbgcolor = RenderD7::Color::Hex("#2D98AF"), u32 selcolor = RenderD7::Color::Hex("#000000")); - void DrawSTObject(std::vector tobject, int tobjectindex, u32 color, u32 txtcolor); - bool touchTObj(touchPosition touch, RenderD7::TObject button); - bool touchTLBtn(touchPosition touch, RenderD7::TLBtn button); - void DrawTLBtns(std::vector btns, u32 color, int selection = -1, u32 selbgcolor = RenderD7::Color::Hex("#2D98AF"), u32 selcolor = RenderD7::Color::Hex("#000000")); - - struct Checkbox - { - float x, y, s; - bool is_chexked = false; - u32 outcol, incol, chcol; - }; - void DrawCheckbox(Checkbox box); - - class Console - { - public: - Console(); - Console(int x, int y, int w, int h, u8 a = 255); - Console(int x, int y, int w, int h, RenderD7::Color::rgba col); - Console(int x, int y, int w, int h, std::string name, RenderD7::Color::rgba col = {255, 255, 255, 255}, RenderD7::Color::rgba barcol = {0, 0, 0, 255}, RenderD7::Color::rgba outlinecol = {222, 222, 222, 255}); - void On(C3D_RenderTarget *t_cscreen); - bool Update(); - ~Console(); - private: - std::vector m_lines; - int x, y, w, h; - std::string m_name = ""; - C3D_RenderTarget *cscreen; - bool m_nconsole = false; - bool m_mconsole = false; - RenderD7::Color::rgba color = {255, 255, 255, 255}; - RenderD7::Color::rgba outlinecol = {222, 222, 222, 255}; - RenderD7::Color::rgba barcolor = {0, 0, 0, 255}; - }; - - void GetDirContentsExt(std::vector &dircontent, const std::vector &extensions); - void GetDirContents(std::vector &dircontent); - -} /// RenderD7 +} // namespace RenderD7 diff --git a/include/renderd7/sound.hpp b/include/renderd7/sound.hpp index 31e623a..1cf852b 100644 --- a/include/renderd7/sound.hpp +++ b/include/renderd7/sound.hpp @@ -6,23 +6,22 @@ /** Sound Class */ class sound { public: - /// \brief Construct new Soundeffect - /// \param path Path to the .wav file - /// \param channel the channel 1-23 - /// \param toloop true:loop the sound, false: don't loop - sound(const std::string& path, int channel = 1, bool toloop = false); - /** deconstruct the sound */ - ~sound(); - /** play the sound */ - void play(); - /** stop the sound */ - void stop(); + /// \brief Construct new Soundeffect + /// \param path Path to the .wav file + /// \param channel the channel 1-23 + /// \param toloop true:loop the sound, false: don't loop + sound(const std::string &path, int channel = 1, bool toloop = false); + /** deconstruct the sound */ + ~sound(); + /** play the sound */ + void play(); + /** stop the sound */ + void stop(); private: - /// \param dataSize the Size of the filedata - u32 dataSize; - ndspWaveBuf waveBuf; - u8* data = NULL; - int chnl; + /// \param dataSize the Size of the filedata + u32 dataSize; + ndspWaveBuf waveBuf; + u8 *data = NULL; + int chnl; }; - diff --git a/include/renderd7/stringtool.hpp b/include/renderd7/stringtool.hpp index 9f81fc8..961a62d 100644 --- a/include/renderd7/stringtool.hpp +++ b/include/renderd7/stringtool.hpp @@ -1,44 +1,40 @@ #pragma once -#include -#include #include +#include +#include -namespace RenderD7 -{ - inline bool NameIsEndingWith(const std::string &name, const std::vector &extensions) - { - if (name.substr(0, 2) == "._") return false; +namespace RenderD7 { +inline bool NameIsEndingWith(const std::string &name, + const std::vector &extensions) { + if (name.substr(0, 2) == "._") + return false; - if (name.size() == 0) return false; + if (name.size() == 0) + return false; - if (extensions.size() == 0) return true; + if (extensions.size() == 0) + return true; - for(int i = 0; i < (int)extensions.size(); i++) { - const std::string ext = extensions.at(i); - if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0) return true; - } - - return false; + for (int i = 0; i < (int)extensions.size(); i++) { + const std::string ext = extensions.at(i); + if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0) + return true; } + + return false; } -template -T GetFileName(T const & path, T const & delims = "/\\") -{ +} // namespace RenderD7 +template T GetFileName(T const &path, T const &delims = "/\\") { return path.substr(path.find_last_of(delims) + 1); } -template -T remove_ext(T const & filename) -{ +template T remove_ext(T const &filename) { typename T::size_type const p(filename.find_last_of('.')); return p > 0 && p != T::npos ? filename.substr(0, p) : filename; } -template< typename T > -std::string Int_To_Hex( T i ) -{ +template std::string Int_To_Hex(T i) { std::stringstream stream; - stream << "0x" - << std::setfill ('0') << std::setw(sizeof(T)*2) - << std::hex << i; + stream << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex + << i; return stream.str(); } \ No newline at end of file diff --git a/include/renderd7/thread.hpp b/include/renderd7/thread.hpp index 195d262..ffb79da 100644 --- a/include/renderd7/thread.hpp +++ b/include/renderd7/thread.hpp @@ -2,118 +2,135 @@ #include <3ds.h> #include #include -#include #include +#include using CTRU_Thread = Thread; #define THREAD_STACK_SIZE 0x1000 namespace RenderD7 { - namespace Threads - { - inline bool threadrunning = false; +namespace Threads { +inline bool threadrunning = false; - struct Thread - { - Handle handle; - void (*ep)(void); - bool finished; - void* stacktop; - }; +struct Thread { + Handle handle; + void (*ep)(void); + bool finished; + void *stacktop; +}; - bool Create(); - bool Join(); - void Exit(); - } - class Thread { - public: - /** - * @brief Default constructor - * @note This should only be called when calling m3d::Thread::initialize() before calling m3d::Thread::start() - */ - Thread(); - - /** - * @brief Constructs the thread - * @param t_function The thread function - * @param t_parameter The parameter to pass to the function - * @param t_autostart Whether the thread should start instantly - * @param t_detached Whether the thread starts detached or not - * @param t_stackSize The stacksize allocated for the thread in bytes (rounded to multiples of 8 bytes) - * @note t_function needs to be of type `void` and take one (and only one) parameter of type m3d::Parameter - * @warning If the thread priority is lower than the priority of the calling thread, the thread will never get executed. Use m3d::Thread::getCurrentPriority() to get the priority of the current thread - */ - Thread(std::function t_function, RenderD7::Parameter t_parameter = nullptr, bool t_autostart = false, bool t_detached = false, unsigned long long int t_stackSize = 4 * 1024); +bool Create(); +bool Join(); +void Exit(); +} // namespace Threads +class Thread { +public: + /** + * @brief Default constructor + * @note This should only be called when calling m3d::Thread::initialize() + * before calling m3d::Thread::start() + */ + Thread(); - /** - * @brief Destructs the thread - */ - virtual ~Thread(); + /** + * @brief Constructs the thread + * @param t_function The thread function + * @param t_parameter The parameter to pass to the function + * @param t_autostart Whether the thread should start instantly + * @param t_detached Whether the thread starts detached or not + * @param t_stackSize The stacksize allocated for the thread in bytes (rounded + * to multiples of 8 bytes) + * @note t_function needs to be of type `void` and take one (and only one) + * parameter of type m3d::Parameter + * @warning If the thread priority is lower than the priority of the calling + * thread, the thread will never get executed. Use + * m3d::Thread::getCurrentPriority() to get the priority of the current thread + */ + Thread(std::function t_function, + RenderD7::Parameter t_parameter = nullptr, bool t_autostart = false, + bool t_detached = false, + unsigned long long int t_stackSize = 4 * 1024); - /** - * @brief Initializes the thread - * @param t_function The thread function - * @param t_parameter The parameter to pass to the function - * @param t_autostart Whether the thread should start instantly - * @param t_detached Whether the thread starts detached or not - * @param t_stackSize The stacksize allocated for the thread in bytes (rounded to multiples of 8 bytes) - * @note t_function needs to be of type `void` and take one (and only one) parameter of type m3d::Parameter - * @warning If the thread priority is lower than the priority of the calling thread, the thread will never get executed. Use m3d::Thread::getCurrentPriority() to get the priority of the current thread - */ - void initialize(std::function t_function, RenderD7::Parameter t_parameter = nullptr, bool t_autostart = false, bool t_detached = false, unsigned long long int t_stackSize = 4 * 1024); + /** + * @brief Destructs the thread + */ + virtual ~Thread(); - /** - * @brief Sets the size of the stack that gets allocated for the next thread that get's started - * @param t_stackSize The allocated space in bytes (rounded to multiples of 8 bytes) - */ - void setStackSize(unsigned long long int t_stackSize); + /** + * @brief Initializes the thread + * @param t_function The thread function + * @param t_parameter The parameter to pass to the function + * @param t_autostart Whether the thread should start instantly + * @param t_detached Whether the thread starts detached or not + * @param t_stackSize The stacksize allocated for the thread in bytes (rounded + * to multiples of 8 bytes) + * @note t_function needs to be of type `void` and take one (and only one) + * parameter of type m3d::Parameter + * @warning If the thread priority is lower than the priority of the calling + * thread, the thread will never get executed. Use + * m3d::Thread::getCurrentPriority() to get the priority of the current thread + */ + void initialize(std::function t_function, + RenderD7::Parameter t_parameter = nullptr, + bool t_autostart = false, bool t_detached = false, + unsigned long long int t_stackSize = 4 * 1024); - /** - * @brief Starts the thread. To restart it, call Thread::join() before - * @param t_detached Whether the thread should start detached or not - */ - void start(bool t_detached = false); + /** + * @brief Sets the size of the stack that gets allocated for the next thread + * that get's started + * @param t_stackSize The allocated space in bytes (rounded to multiples of 8 + * bytes) + */ + void setStackSize(unsigned long long int t_stackSize); - /** - * @brief Detaches the thread - */ - void kill(); + /** + * @brief Starts the thread. To restart it, call Thread::join() before + * @param t_detached Whether the thread should start detached or not + */ + void start(bool t_detached = false); - /** - * @brief Waits for the thread to finish - * @param t_timeout The timeout in nanoseconds. Leave it for no timeout - */ - void join(long long unsigned int t_timeout = U64_MAX); + /** + * @brief Detaches the thread + */ + void kill(); - bool isRunning(); + /** + * @brief Waits for the thread to finish + * @param t_timeout The timeout in nanoseconds. Leave it for no timeout + */ + void join(long long unsigned int t_timeout = U64_MAX); - /** - * @brief Puts the thread to sleep - * - * This is needed if you have multiple threads running at the same time. It doesn't affect the execution-time of the thread, it just makes it possible for the other threads to get their chance to shine. - */ - static void sleep(); + bool isRunning(); - /** - * @brief Sleeps for the given time - * @param t_milliseconds The time to sleep in milliseconds - */ - static void sleep(int t_milliseconds); + /** + * @brief Puts the thread to sleep + * + * This is needed if you have multiple threads running at the same time. It + * doesn't affect the execution-time of the thread, it just makes it possible + * for the other threads to get their chance to shine. + */ + static void sleep(); - private: - struct ThreadData { - RenderD7::Parameter m_parameter; - std::function m_function; - std::atomic* m_running; - }; + /** + * @brief Sleeps for the given time + * @param t_milliseconds The time to sleep in milliseconds + */ + static void sleep(int t_milliseconds); - static void threadFunction(void* t_arg); - /* data */ - int m_priority, m_stackSize; - bool m_started; - std::atomic m_running; - RenderD7::Thread::ThreadData m_data; - CTRU_Thread m_thread; - }; -} +private: + struct ThreadData { + RenderD7::Parameter m_parameter; + std::function m_function; + std::atomic *m_running; + }; + + static void threadFunction(void *t_arg); + /* data */ + int m_priority, m_stackSize; + bool m_started; + std::atomic m_running; + RenderD7::Thread::ThreadData m_data; + CTRU_Thread m_thread; +}; +} // namespace RenderD7 diff --git a/include/renderd7/tween.hpp b/include/renderd7/tween.hpp index bdf6fdf..1efaf70 100644 --- a/include/renderd7/tween.hpp +++ b/include/renderd7/tween.hpp @@ -1,17 +1,18 @@ #include -namespace rnd7{ - enum class TweenType : int {Position = 1, Color, Alpha}; +namespace rnd7 { +enum class TweenType : int { Position = 1, Color, Alpha }; - enum class TweenLoop : int {None = 1, Loop = 2,}; +enum class TweenLoop : int { + None = 1, + Loop = 2, +}; - enum class TweenDirection : int {Current, Forward, Backward}; +enum class TweenDirection : int { Current, Forward, Backward }; - enum class TweenState : int {Playing = 1, Stopped}; - class Tween - { - public: - Tween(float from, float to, float duration, TweenLoop loop, TweenState state); - - }; -} +enum class TweenState : int { Playing = 1, Stopped }; +class Tween { +public: + Tween(float from, float to, float duration, TweenLoop loop, TweenState state); +}; +} // namespace rnd7 diff --git a/source/BitmapPrinter.cpp b/source/BitmapPrinter.cpp index bdcc35b..b060694 100644 --- a/source/BitmapPrinter.cpp +++ b/source/BitmapPrinter.cpp @@ -6,459 +6,460 @@ extern bool shouldbe_disabled; extern std::string csvpc; -RenderD7::BitmapPrinter::BitmapPrinter(int w, int h) -{ - BMP newmap(w, h, true); - bitmap = newmap; - //renderframe.LoadPFromBuffer(BitmapConverter::ConvertData(bitmap.DATA())); - blank = newmap; +RenderD7::BitmapPrinter::BitmapPrinter(int w, int h) { + BMP newmap(w, h, true); + bitmap = newmap; + // renderframe.LoadPFromBuffer(BitmapConverter::ConvertData(bitmap.DATA())); + blank = newmap; } -RenderD7::BitmapPrinter::~BitmapPrinter() -{ - if(this->renderframe.loadet) this->renderframe.Unload(); +RenderD7::BitmapPrinter::~BitmapPrinter() { + if (this->renderframe.loadet) + this->renderframe.Unload(); } -bool RenderD7::BitmapPrinter::DecodeFile(std::string file) -{ - unsigned error = bitmap.read(file.c_str()); - - if (error) - { - RenderD7::AddOvl(std::make_unique("BitmapPrinter", "Error Code: " + std::to_string(error))); - return false; - } +bool RenderD7::BitmapPrinter::DecodeFile(std::string file) { + unsigned error = bitmap.read(file.c_str()); - return true; + if (error) { + RenderD7::AddOvl(std::make_unique( + "BitmapPrinter", "Error Code: " + std::to_string(error))); + return false; + } + + return true; } -void RenderD7::BitmapPrinter::DrawPixel(int x, int y, u8 b, u8 g, u8 r, u8 a) -{ - unsigned error = bitmap.set_pixel(x, bitmap.bmp_info_header.height - y, b, g, r, a); - if (error) - { - RenderD7::AddOvl(std::make_unique("BitmapPrinter->Pixel", "Error Code: " + std::to_string(error))); - } +void RenderD7::BitmapPrinter::DrawPixel(int x, int y, u8 b, u8 g, u8 r, u8 a) { + unsigned error = + bitmap.set_pixel(x, bitmap.bmp_info_header.height - y, b, g, r, a); + if (error) { + RenderD7::AddOvl(std::make_unique( + "BitmapPrinter->Pixel", "Error Code: " + std::to_string(error))); + } } -void RenderD7::BitmapPrinter::DrawRect(int x, int y, int w, int h, u8 line_w, u8 b, u8 g, u8 r, u8 a) -{ - unsigned error = bitmap.draw_rectangle(x, bitmap.bmp_info_header.height - y - h, w, h, b, g, r, a, line_w); - if (error) - { - RenderD7::AddOvl(std::make_unique("BitmapPrinter->Rect", "Error Code: " + std::to_string(error))); - } +void RenderD7::BitmapPrinter::DrawRect(int x, int y, int w, int h, u8 line_w, + u8 b, u8 g, u8 r, u8 a) { + unsigned error = bitmap.draw_rectangle( + x, bitmap.bmp_info_header.height - y - h, w, h, b, g, r, a, line_w); + if (error) { + RenderD7::AddOvl(std::make_unique( + "BitmapPrinter->Rect", "Error Code: " + std::to_string(error))); + } } -void RenderD7::BitmapPrinter::DrawRectFilled(int x, int y, int w, int h, u8 b, u8 g, u8 r, u8 a) -{ - unsigned error = bitmap.fill_region(x, bitmap.bmp_info_header.height - h - y, w, h, b, g, r, a); - if (error) - { - RenderD7::AddOvl(std::make_unique("BitmapPrinter->RectF", "Error Code: " + std::to_string(error))); - } +void RenderD7::BitmapPrinter::DrawRectFilled(int x, int y, int w, int h, u8 b, + u8 g, u8 r, u8 a) { + unsigned error = bitmap.fill_region(x, bitmap.bmp_info_header.height - h - y, + w, h, b, g, r, a); + if (error) { + RenderD7::AddOvl(std::make_unique( + "BitmapPrinter->RectF", "Error Code: " + std::to_string(error))); + } } -void RenderD7::BitmapPrinter::SaveBmp(std::string name) -{ - if(!RenderD7::NameIsEndingWith(name, {"bmp"})) - { - name += ".bmp"; +void RenderD7::BitmapPrinter::SaveBmp(std::string name) { + if (!RenderD7::NameIsEndingWith(name, {"bmp"})) { + name += ".bmp"; + } + bitmap.write(name.c_str()); +} +void RenderD7::BitmapPrinter::SavePng(std::string name) { + if (!RenderD7::NameIsEndingWith(name, {"png"})) { + name += ".png"; + } + std::vector ImageBuffer; + ImageBuffer = BitmapConverter::ConvertData(bitmap.DATA()); + lodepng::save_file(ImageBuffer, name); +} + +void RenderD7::BitmapPrinter::CreateScreen(C3D_RenderTarget *target) { + isscreen = true; + targetr = target; + if (target == Top) { + bitmap = BMP(400, 240, true); + blank = BMP(400, 240, true); + } + if (target == TopRight) { + bitmap = BMP(400, 240, true); + blank = BMP(400, 240, true); + } + if (target == Bottom) { + bitmap = BMP(320, 240, true); + blank = BMP(320, 240, true); + } + renderframe.LoadPFromBuffer(BitmapConverter::ConvertData(bitmap.DATA())); +} +bool RenderD7::BitmapPrinter::DrawScreenDirectF(int framerate) { + bool updtt = false; + if (isscreen) { + if (frame == (60 / framerate)) { + RenderD7::OnScreen(targetr); + if (renderframe.loadet) + renderframe.Unload(); + this->Decode(decc); + frame = 0; + updtt = true; } - bitmap.write(name.c_str()); + + if (renderframe.loadet) + renderframe.Draw(0, 0); + frame++; + } + return updtt; } -void RenderD7::BitmapPrinter::SavePng(std::string name) -{ - if(!RenderD7::NameIsEndingWith(name, {"png"})) - { - name += ".png"; + +bool RenderD7::BitmapPrinter::DrawScreenDirect() { + bool updtt = false; + if (isscreen) { + RenderD7::OnScreen(targetr); + if (renderframe.loadet) + renderframe.Unload(); + this->Decode(decc); + updtt = true; + if (renderframe.loadet) + renderframe.Draw(0, 0); + } + return updtt; +} + +RenderD7::Image RenderD7::BitmapPrinter::GetImage() { + RenderD7::Image img; + img.LoadFromBitmap(bitmap); + return img; +} + +void RenderD7::BitmapPrinter::UsePreMap(BMP map) { bitmap = map; } +void RenderD7::BitmapPrinter::UsePrePrintMap(BitmapPrinter printmap) { + bitmap = printmap.GetBitmap(); +} + +void RenderD7::BitmapPrinter::Clear(u8 b, u8 g, u8 r, u8 a) { + bitmap.fill_region(0, 0, bitmap.bmp_info_header.width, + bitmap.bmp_info_header.height, b, g, r, a); +} +void RenderD7::BitmapPrinter::ClearBlank() { bitmap = blank; } + +void RenderD7::BitmapPrinter::DrawScreenF(int framerate) { + if (isscreen) { + if (frame == (60 / framerate)) { + RenderD7::OnScreen(targetr); + frame = 0; } - std::vector ImageBuffer; - ImageBuffer = BitmapConverter::ConvertData(bitmap.DATA()); - lodepng::save_file(ImageBuffer, name); -} -void RenderD7::BitmapPrinter::CreateScreen(C3D_RenderTarget *target) -{ - isscreen = true; - targetr = target; - if (target == Top) - { - bitmap = BMP(400, 240, true); - blank = BMP(400, 240, true); - } - if (target == TopRight) - { - bitmap = BMP(400, 240, true); - blank = BMP(400, 240, true); - } - if (target == Bottom) - { - bitmap = BMP(320, 240, true); - blank = BMP(320, 240, true); - } - renderframe.LoadPFromBuffer(BitmapConverter::ConvertData(bitmap.DATA())); - + if (renderframe.loadet) + renderframe.Draw(0, 0); + frame++; + } } -bool RenderD7::BitmapPrinter::DrawScreenDirectF(int framerate) -{ - bool updtt = false; - if (isscreen) - { - if(frame == (60/framerate)){ - RenderD7::OnScreen(targetr); - if(renderframe.loadet) renderframe.Unload(); - this->Decode(decc); - frame = 0; - updtt = true; - } - - if(renderframe.loadet) renderframe.Draw(0, 0); - frame++; - } - return updtt; +void RenderD7::BitmapPrinter::DrawScreen() { + if (isscreen) { + RenderD7::OnScreen(targetr); + if (renderframe.loadet) + renderframe.Draw(0, 0); + } } - -bool RenderD7::BitmapPrinter::DrawScreenDirect() -{ - bool updtt = false; - if (isscreen) - { - RenderD7::OnScreen(targetr); - if(renderframe.loadet) renderframe.Unload(); - this->Decode(decc); - updtt = true; - if(renderframe.loadet) renderframe.Draw(0, 0); - } - return updtt; +bool RenderD7::BitmapPrinter::UpdateScreenF(int framerate) { + bool updtt = false; + if (isscreen) { + if (frame == (60 / framerate)) { + if (renderframe.loadet) + renderframe.Unload(); + // renderframe.LoadFromBitmap(bitmap); + this->Decode(decc); + frame = 0; + updtt = true; + } + frame++; + } + return updtt; } - -RenderD7::Image RenderD7::BitmapPrinter::GetImage() -{ - RenderD7::Image img; - img.LoadFromBitmap(bitmap); - return img; -} - -void RenderD7::BitmapPrinter::UsePreMap(BMP map) -{ - bitmap = map; -} -void RenderD7::BitmapPrinter::UsePrePrintMap(BitmapPrinter printmap) -{ - bitmap = printmap.GetBitmap(); -} - -void RenderD7::BitmapPrinter::Clear(u8 b, u8 g, u8 r, u8 a) -{ - bitmap.fill_region(0, 0, bitmap.bmp_info_header.width, bitmap.bmp_info_header.height, b, g, r, a); -} -void RenderD7::BitmapPrinter::ClearBlank() -{ - bitmap = blank; -} - -void RenderD7::BitmapPrinter::DrawScreenF(int framerate) -{ - if (isscreen) - { - if(frame == (60/framerate)){ - RenderD7::OnScreen(targetr); - frame = 0; - } - - if(renderframe.loadet) renderframe.Draw(0, 0); - frame++; - } -} -void RenderD7::BitmapPrinter::DrawScreen() -{ - if (isscreen) - { - RenderD7::OnScreen(targetr); - if(renderframe.loadet) renderframe.Draw(0, 0); - } -} -bool RenderD7::BitmapPrinter::UpdateScreenF(int framerate) -{ - bool updtt = false; - if (isscreen) - { - if(frame == (60/framerate)){ - if(renderframe.loadet) renderframe.Unload(); - //renderframe.LoadFromBitmap(bitmap); - this->Decode(decc); - frame = 0; - updtt = true; - } - frame++; - } - return updtt; -} -bool RenderD7::BitmapPrinter::UpdateScreen() -{ - bool updtt = false; - if (isscreen) - { - if(renderframe.loadet) renderframe.Unload(); - this->Decode(decc); - updtt = true; - } - return updtt; +bool RenderD7::BitmapPrinter::UpdateScreen() { + bool updtt = false; + if (isscreen) { + if (renderframe.loadet) + renderframe.Unload(); + this->Decode(decc); + updtt = true; + } + return updtt; } #define TICKS_PER_MSEC 268111.856 -void RenderD7::BitmapPrinter::Benchmark() -{ - if(setupbenchmark) - { - frametime = 0; - renderedframes = 0; - timer = 0; - setupbenchmark = false; - lastTime = svcGetSystemTick(); - } - if(benchmark) - { - if(timer >= 60) - { - std::string renderedf = std::to_string(renderedframes); - std::string avgdtt = std::to_string(mhdtt); - float alldtt = 0; - for (size_t i = 1; i < hdttt.size(); i++) - { - alldtt += hdttt[i]; - } - float alldtt2 = 0; - for (size_t i = 0; i < hdttt2.size(); i++) - { - alldtt2 += hdttt2[i]; - } - float alldtt3 = 0; - for (size_t i = 0; i < hdttt3.size(); i++) - { - alldtt3 += hdttt3[i]; - } - int allfps = 0; - for (size_t f = 1; f < fpscountc.size(); f++) - { - allfps += fpscountc[f]; - } - - - std::string avgcpu = std::to_string((alldtt/(float)hdttt.size()-1)); - std::string avgcpu2 = std::to_string(((alldtt2/(float)hdttt2.size())*1000)); - std::string avgcpu3 = std::to_string(((alldtt3/(float)hdttt3.size())*1000)); - std::string avgfps = std::to_string((allfps/(int)fpscountc.size()-1)); +void RenderD7::BitmapPrinter::Benchmark() { + if (setupbenchmark) { + frametime = 0; + renderedframes = 0; + timer = 0; + setupbenchmark = false; + lastTime = svcGetSystemTick(); + } + if (benchmark) { + if (timer >= 60) { + std::string renderedf = std::to_string(renderedframes); + std::string avgdtt = std::to_string(mhdtt); + float alldtt = 0; + for (size_t i = 1; i < hdttt.size(); i++) { + alldtt += hdttt[i]; + } + float alldtt2 = 0; + for (size_t i = 0; i < hdttt2.size(); i++) { + alldtt2 += hdttt2[i]; + } + float alldtt3 = 0; + for (size_t i = 0; i < hdttt3.size(); i++) { + alldtt3 += hdttt3[i]; + } + int allfps = 0; + for (size_t f = 1; f < fpscountc.size(); f++) { + allfps += fpscountc[f]; + } - std::string resultt = "TestMode: " + std::to_string(testfpsd) + "fps" + "\nRendered Frames: " + renderedf + "\nMax Cpu Time: " + avgdtt + "\nAvg Cpu Time: " + avgcpu + "\nAvg Fps: " + avgfps + "\nAvg EncodeTime: " + avgcpu2 + "ms/f\nAvg DecodeTime: " + avgcpu3 + "ms\n"; - this->ClearBlank(); - this->DrawRectFilled(0, 0, this->bitmap.bmp_info_header.width, this->bitmap.bmp_info_header.height, 0, 0, 0, 255); - this->DrawDebugText(0, 0, 0, RenderD7::Color::Hex("#ffffff"), resultt); - std::string outname = csvpc + "/benchmark_" + RenderD7::GetTimeStr() + ".png"; - this->SavePng(outname); - RenderD7::AddOvl(std::make_unique("Benchmark", "Saved to: \n" + outname)); - benchmark = false; - } - uint64_t currentTime = svcGetSystemTick(); - dtt = ((float)(currentTime / (float)TICKS_PER_MSEC) - (float)(lastTime / (float)TICKS_PER_MSEC)) / 1000.f; - lastTime = currentTime; - lastTime = currentTime; - frameCounter++; - fpsClock += dtt; - if (fpsClock >= 1.f) { - fps = frameCounter; - frameCounter = 0; - fpsClock = 0.f; - } - uint64_t lastTime2 = svcGetSystemTick(); - this->ClearBlank(); - this->DrawRectFilled(0, 0, this->bitmap.bmp_info_header.width, this->bitmap.bmp_info_header.width, 255, 255, 255, 255); - this->DrawRect(5, 5, this->bitmap.bmp_info_header.width - 10, this->bitmap.bmp_info_header.height - 10, 5, 0, 0, 0, 0); - //this->DrawDebugText(20, 20, 0, RenderD7::Color::Hex("#ffffff"), "Fps: " + std::to_string(fps)); - this->DrawDebugText(0, 0, 0.5f, RenderD7::Color::Hex("#ff0000"), "Time: " + std::to_string(timer)); - this->DrawDebugText(0, 10, 0.5f, RenderD7::Color::Hex("#ff0000"), "Fps: " + std::to_string(fps)); - this->DrawDebugText(0, 20, 0.5f, RenderD7::Color::Hex("#ff0000"), "dt: " + std::to_string(dtt)); - this->DrawDebugText(0, 30, 0.5f, RenderD7::Color::Hex("#ff0000"), "MaxEncodeTime: " + std::to_string(mdtt2*1000) + "ms/f"); - this->DrawDebugText(0, 40, 0.5f, RenderD7::Color::Hex("#ff0000"), "MaxDecodeTime: " + std::to_string(mdtt3*1000) + "ms"); - uint64_t currentTime2 = svcGetSystemTick(); - dtt2 = ((float)(currentTime2 / (float)TICKS_PER_MSEC) - (float)(lastTime2 / (float)TICKS_PER_MSEC)) / 1000.f; - hdttt2.push_back(dtt2); - lastTime2 = svcGetSystemTick(); - bool updgg = this->UpdateScreenF(testfps); - currentTime2 = svcGetSystemTick(); - dtt3 = ((float)(currentTime2 / (float)TICKS_PER_MSEC) - (float)(lastTime2 / (float)TICKS_PER_MSEC)) / 1000.f; - if(updgg) hdttt3.push_back(dtt3); - if (!shouldbe_disabled) this->DrawScreen(); - renderedframes++; - if(mdtt2 < dtt2) - { - mdtt2 = dtt2; - } - if(mdtt3 < dtt3 && updgg) - { - mdtt3 = dtt3; - } - timer+= 1*dtt; - float hdtt = C3D_GetProcessingTime(); - hdttt.push_back(hdtt); - fpscountc.push_back(fps); - if(mhdtt < hdtt) - { - mhdtt = C3D_GetProcessingTime(); - } - /*if (!shouldbe_disabled) - { - RenderD7::OnScreen(Bottom); - RenderD7::DrawText(0, 0, 0.5f, RenderD7::Color::Hex("#ff0000"), "Time: " + std::to_string(timer)); - RenderD7::DrawText(0, 20, 0.5f, RenderD7::Color::Hex("#ff0000"), "Fps: " + std::to_string(fps)); - RenderD7::DrawText(0, 40, 0.5f, RenderD7::Color::Hex("#ff0000"), "dt: " + std::to_string(dtt)); - RenderD7::DrawText(0, 60, 0.5f, RenderD7::Color::Hex("#ff0000"), "MaxRenderTime: " + std::to_string(mdtt2*1000) + "ms/f"); - RenderD7::DrawText(0, 80, 0.5f, RenderD7::Color::Hex("#ff0000"), "MaxConvertTime: " + std::to_string(mdtt3*1000) + "ms"); + std::string avgcpu = std::to_string((alldtt / (float)hdttt.size() - 1)); + std::string avgcpu2 = + std::to_string(((alldtt2 / (float)hdttt2.size()) * 1000)); + std::string avgcpu3 = + std::to_string(((alldtt3 / (float)hdttt3.size()) * 1000)); + std::string avgfps = std::to_string((allfps / (int)fpscountc.size() - 1)); - }*/ - } + std::string resultt = + "TestMode: " + std::to_string(testfpsd) + "fps" + + "\nRendered Frames: " + renderedf + "\nMax Cpu Time: " + avgdtt + + "\nAvg Cpu Time: " + avgcpu + "\nAvg Fps: " + avgfps + + "\nAvg EncodeTime: " + avgcpu2 + "ms/f\nAvg DecodeTime: " + avgcpu3 + + "ms\n"; + this->ClearBlank(); + this->DrawRectFilled(0, 0, this->bitmap.bmp_info_header.width, + this->bitmap.bmp_info_header.height, 0, 0, 0, 255); + this->DrawDebugText(0, 0, 0, RenderD7::Color::Hex("#ffffff"), resultt); + std::string outname = + csvpc + "/benchmark_" + RenderD7::GetTimeStr() + ".png"; + this->SavePng(outname); + RenderD7::AddOvl(std::make_unique( + "Benchmark", "Saved to: \n" + outname)); + benchmark = false; + } + uint64_t currentTime = svcGetSystemTick(); + dtt = ((float)(currentTime / (float)TICKS_PER_MSEC) - + (float)(lastTime / (float)TICKS_PER_MSEC)) / + 1000.f; + lastTime = currentTime; + lastTime = currentTime; + frameCounter++; + fpsClock += dtt; + if (fpsClock >= 1.f) { + fps = frameCounter; + frameCounter = 0; + fpsClock = 0.f; + } + uint64_t lastTime2 = svcGetSystemTick(); + this->ClearBlank(); + this->DrawRectFilled(0, 0, this->bitmap.bmp_info_header.width, + this->bitmap.bmp_info_header.width, 255, 255, 255, + 255); + this->DrawRect(5, 5, this->bitmap.bmp_info_header.width - 10, + this->bitmap.bmp_info_header.height - 10, 5, 0, 0, 0, 0); + // this->DrawDebugText(20, 20, 0, RenderD7::Color::Hex("#ffffff"), "Fps: " + + // std::to_string(fps)); + this->DrawDebugText(0, 0, 0.5f, RenderD7::Color::Hex("#ff0000"), + "Time: " + std::to_string(timer)); + this->DrawDebugText(0, 10, 0.5f, RenderD7::Color::Hex("#ff0000"), + "Fps: " + std::to_string(fps)); + this->DrawDebugText(0, 20, 0.5f, RenderD7::Color::Hex("#ff0000"), + "dt: " + std::to_string(dtt)); + this->DrawDebugText(0, 30, 0.5f, RenderD7::Color::Hex("#ff0000"), + "MaxEncodeTime: " + std::to_string(mdtt2 * 1000) + + "ms/f"); + this->DrawDebugText(0, 40, 0.5f, RenderD7::Color::Hex("#ff0000"), + "MaxDecodeTime: " + std::to_string(mdtt3 * 1000) + + "ms"); + uint64_t currentTime2 = svcGetSystemTick(); + dtt2 = ((float)(currentTime2 / (float)TICKS_PER_MSEC) - + (float)(lastTime2 / (float)TICKS_PER_MSEC)) / + 1000.f; + hdttt2.push_back(dtt2); + lastTime2 = svcGetSystemTick(); + bool updgg = this->UpdateScreenF(testfps); + currentTime2 = svcGetSystemTick(); + dtt3 = ((float)(currentTime2 / (float)TICKS_PER_MSEC) - + (float)(lastTime2 / (float)TICKS_PER_MSEC)) / + 1000.f; + if (updgg) + hdttt3.push_back(dtt3); + if (!shouldbe_disabled) + this->DrawScreen(); + renderedframes++; + if (mdtt2 < dtt2) { + mdtt2 = dtt2; + } + if (mdtt3 < dtt3 && updgg) { + mdtt3 = dtt3; + } + timer += 1 * dtt; + float hdtt = C3D_GetProcessingTime(); + hdttt.push_back(hdtt); + fpscountc.push_back(fps); + if (mhdtt < hdtt) { + mhdtt = C3D_GetProcessingTime(); + } + /*if (!shouldbe_disabled) + { + RenderD7::OnScreen(Bottom); + RenderD7::DrawText(0, 0, 0.5f, RenderD7::Color::Hex("#ff0000"), + "Time: " + std::to_string(timer)); RenderD7::DrawText(0, 20, 0.5f, + RenderD7::Color::Hex("#ff0000"), "Fps: " + std::to_string(fps)); + RenderD7::DrawText(0, 40, 0.5f, RenderD7::Color::Hex("#ff0000"), + "dt: " + std::to_string(dtt)); RenderD7::DrawText(0, 60, 0.5f, + RenderD7::Color::Hex("#ff0000"), "MaxRenderTime: " + + std::to_string(mdtt2*1000) + "ms/f"); RenderD7::DrawText(0, 80, 0.5f, + RenderD7::Color::Hex("#ff0000"), "MaxConvertTime: " + + std::to_string(mdtt3*1000) + "ms"); + + }*/ + } } -void RenderD7::BitmapPrinter::SetupBenchmark(int framerate) -{ - benchmark = true; - setupbenchmark = true; - this->testfps = framerate; - this->testfpsd = framerate; +void RenderD7::BitmapPrinter::SetupBenchmark(int framerate) { + benchmark = true; + setupbenchmark = true; + this->testfps = framerate; + this->testfpsd = framerate; } #include -void RenderD7::BitmapPrinter::DrawDebugChar(u32 posX, u32 posY, int t_size, u32 color, char character) -{ - bool isscale = (t_size > 1) ? true : false; - for(u32 y = 0; y < 8; y++) - { - char charPos = debugfont[character * 8 + y]; +void RenderD7::BitmapPrinter::DrawDebugChar(u32 posX, u32 posY, int t_size, + u32 color, char character) { + bool isscale = (t_size > 1) ? true : false; + for (u32 y = 0; y < 8; y++) { + char charPos = debugfont[character * 8 + y]; - for(u32 x = 0; x < 8; x++) - if(((charPos >> (7 - x)) & 1) == 1) - { - if (!isscale) DrawPixel((int)posX + x + 1, (int)posY + y + 1, UNPACK_BGRA(color)); - if (isscale) DrawRectFilled(((int)posX) + (x*t_size) + 1, ((int)posY) + (y*t_size) + 1, t_size, t_size, UNPACK_BGRA(color)); - } - } + for (u32 x = 0; x < 8; x++) + if (((charPos >> (7 - x)) & 1) == 1) { + if (!isscale) + DrawPixel((int)posX + x + 1, (int)posY + y + 1, UNPACK_BGRA(color)); + if (isscale) + DrawRectFilled(((int)posX) + (x * t_size) + 1, + ((int)posY) + (y * t_size) + 1, t_size, t_size, + UNPACK_BGRA(color)); + } + } } -void RenderD7::BitmapPrinter::DrawChar(int posX, int posY, float t_size, u32 color, char character, RenderD7::NFontApi font) -{ - for(int y = 0; y < font.GetGlyphHeight(character); y++) - { - for(int x = 0; x < font.GetGlyphWidth(character); x++) - { - DrawPixel(posX + x + 1, posY + y + 1, 255, 255, 255, font.GetGlyphBitmap(character)[((y * font.GetGlyphWidth(character) + x) * 1)]); - if(((font.GetGlyphBitmap(character)[font.GetGlyphHeight(character) + y] >> (font.GetGlyphWidth(character - 1) - x)) & 1) == 1) - { - - } - - } +void RenderD7::BitmapPrinter::DrawChar(int posX, int posY, float t_size, + u32 color, char character, + RenderD7::NFontApi font) { + for (int y = 0; y < font.GetGlyphHeight(character); y++) { + for (int x = 0; x < font.GetGlyphWidth(character); x++) { + DrawPixel(posX + x + 1, posY + y + 1, 255, 255, 255, + font.GetGlyphBitmap( + character)[((y * font.GetGlyphWidth(character) + x) * 1)]); + if (((font.GetGlyphBitmap( + character)[font.GetGlyphHeight(character) + y] >> + (font.GetGlyphWidth(character - 1) - x)) & + 1) == 1) { + } } - //for(int y = 0; y < font.GetGlyphHeight(character) * font.GetGlyphWidth(character); y++) - //{ - // DrawPixel(posX + x + 1, posY + y + 1, UNPACK_BGRA(color)); - //} - + } + // for(int y = 0; y < font.GetGlyphHeight(character) * + // font.GetGlyphWidth(character); y++) + //{ + // DrawPixel(posX + x + 1, posY + y + 1, UNPACK_BGRA(color)); + //} } #define SPACING_Y 10 #define SPACING_X 8 -void RenderD7::BitmapPrinter::DrawDebugText(int x, int y, int t_size, u32 color, std::string text) -{ - if (t_size < 1) - { - t_size = 1; - } - - for(u32 i = 0, line_i = 0; i < strlen(text.c_str()); i++) - switch(text[i]) - { - case '\n': - y += (SPACING_Y*t_size); - line_i = 0; - break; +void RenderD7::BitmapPrinter::DrawDebugText(int x, int y, int t_size, u32 color, + std::string text) { + if (t_size < 1) { + t_size = 1; + } - case '\t': - line_i += 2; - break; + for (u32 i = 0, line_i = 0; i < strlen(text.c_str()); i++) + switch (text[i]) { + case '\n': + y += (SPACING_Y * t_size); + line_i = 0; + break; - default: - //Make sure we never get out of the screen - if(line_i >= (((u32)this->bitmap.bmp_info_header.width) - (u32)x) / (SPACING_X*t_size)) - { - y += (SPACING_Y*t_size); - line_i = 1; //Little offset so we know the same text continues - if(text[i] == ' ') break; //Spaces at the start look weird - } + case '\t': + line_i += 2; + break; - this->DrawDebugChar((u32)x + line_i * (SPACING_X*t_size), (u32)y, t_size, color, text[i]); + default: + // Make sure we never get out of the screen + if (line_i >= (((u32)this->bitmap.bmp_info_header.width) - (u32)x) / + (SPACING_X * t_size)) { + y += (SPACING_Y * t_size); + line_i = 1; // Little offset so we know the same text continues + if (text[i] == ' ') + break; // Spaces at the start look weird + } - line_i++; - break; - } + this->DrawDebugChar((u32)x + line_i * (SPACING_X * t_size), (u32)y, + t_size, color, text[i]); + + line_i++; + break; + } } -void RenderD7::BitmapPrinter::DrawText(int x, int y, float t_size, u32 color, std::string text, RenderD7::NFontApi font) -{ - if (t_size < 1) - { - t_size = 1; - } - - for(u32 i = 0, line_i = 0; i < strlen(text.c_str()); i++) - switch(text[i]) - { - case '\n': - y += (font.GetLineHeight()); - line_i = 0; - break; +void RenderD7::BitmapPrinter::DrawText(int x, int y, float t_size, u32 color, + std::string text, + RenderD7::NFontApi font) { + if (t_size < 1) { + t_size = 1; + } - case '\t': - line_i += 2; - break; + for (u32 i = 0, line_i = 0; i < strlen(text.c_str()); i++) + switch (text[i]) { + case '\n': + y += (font.GetLineHeight()); + line_i = 0; + break; - default: - //Make sure we never get out of the screen - if(line_i >= (((u32)this->bitmap.bmp_info_header.width) - (u32)x) / (u32)(font.GetGlyphWidth(text[i]))) - { - y += (SPACING_Y*t_size); - line_i = 1; //Little offset so we know the same text continues - if(text[i] == ' ') break; //Spaces at the start look weird - } + case '\t': + line_i += 2; + break; - this->DrawChar(x + line_i * (font.GetGlyphWidth(text[i])), y, t_size, color, text[i], font); + default: + // Make sure we never get out of the screen + if (line_i >= (((u32)this->bitmap.bmp_info_header.width) - (u32)x) / + (u32)(font.GetGlyphWidth(text[i]))) { + y += (SPACING_Y * t_size); + line_i = 1; // Little offset so we know the same text continues + if (text[i] == ' ') + break; // Spaces at the start look weird + } - line_i++; - break; - } + this->DrawChar(x + line_i * (font.GetGlyphWidth(text[i])), y, t_size, + color, text[i], font); + line_i++; + break; + } } -bool RenderD7::BitmapPrinter::Decode(Decoder deccc) -{ - bool res = false; +bool RenderD7::BitmapPrinter::Decode(Decoder deccc) { + bool res = false; - switch (deccc) - { - case Decoder::BITMAP2PNG2C3D: - renderframe.LoadPFromBuffer(BitmapConverter::ConvertData(this->bitmap.DATA())); - res = true; - break; - case Decoder::BITMAP2C3D: - renderframe.LoadFromBitmap(this->bitmap); - res = true; - break; - - default: - res = false; - break; - } - return res; + switch (deccc) { + case Decoder::BITMAP2PNG2C3D: + renderframe.LoadPFromBuffer( + BitmapConverter::ConvertData(this->bitmap.DATA())); + res = true; + break; + case Decoder::BITMAP2C3D: + renderframe.LoadFromBitmap(this->bitmap); + res = true; + break; + + default: + res = false; + break; + } + return res; } diff --git a/source/Color.cpp b/source/Color.cpp index ac37908..7d9299f 100644 --- a/source/Color.cpp +++ b/source/Color.cpp @@ -1,22 +1,24 @@ #include -#define RGBA8(r, g, b, a) ((((r) & 0xFF) << 0) | (((g) & 0xFF) << 8) | (((b) & 0xFF) << 16) | (((a) & 0xFF) << 24)) +#define RGBA8(r, g, b, a) \ + ((((r)&0xFF) << 0) | (((g)&0xFF) << 8) | (((b)&0xFF) << 16) | \ + (((a)&0xFF) << 24)) -uint32_t RenderD7::Color::Hex(const std::string color, uint8_t a) -{ - if (color.length() < 7 || std::regex_search(color.substr(1), std::regex("[^0-9A-Fa-f]"))) { // invalid color. - return RenderD7::Color::Hex("#000000", 0); - } - int r = std::stoi(color.substr(1, 2), nullptr, 16); - int g = std::stoi(color.substr(3, 2), nullptr, 16); - int b = std::stoi(color.substr(5, 2), nullptr, 16); - return RGBA8(r, g, b, a); +uint32_t RenderD7::Color::Hex(const std::string color, uint8_t a) { + if (color.length() < 7 || + std::regex_search(color.substr(1), + std::regex("[^0-9A-Fa-f]"))) { // invalid color. + return RenderD7::Color::Hex("#000000", 0); + } + int r = std::stoi(color.substr(1, 2), nullptr, 16); + int g = std::stoi(color.substr(3, 2), nullptr, 16); + int b = std::stoi(color.substr(5, 2), nullptr, 16); + return RGBA8(r, g, b, a); } -std::string RenderD7::Color::RGB2Hex(int r, int g, int b) -{ - std::stringstream ss; - ss << "#"; - ss << std::hex << (r << 16 | g << 8 | b ); - return ss.str(); +std::string RenderD7::Color::RGB2Hex(int r, int g, int b) { + std::stringstream ss; + ss << "#"; + ss << std::hex << (r << 16 | g << 8 | b); + return ss.str(); } \ No newline at end of file diff --git a/source/Draw.cpp b/source/Draw.cpp index e60aec7..3067435 100644 --- a/source/Draw.cpp +++ b/source/Draw.cpp @@ -4,174 +4,213 @@ extern C2D_TextBuf TextBuf; extern C2D_Font Font; extern bool currentScreen; -bool RenderD7::Draw::Rect(float x, float y, float w, float h, u32 color) -{ - return C2D_DrawRectSolid(x, y, 0.5f, w, h, color); +bool RenderD7::Draw::Rect(float x, float y, float w, float h, u32 color) { + return C2D_DrawRectSolid(x, y, 0.5f, w, h, color); } -bool RenderD7::Draw::Px(float x, float y, u32 color) -{ - return C2D_DrawRectSolid(x, y, 0.5f, 1, 1, color); +bool RenderD7::Draw::Px(float x, float y, u32 color) { + return C2D_DrawRectSolid(x, y, 0.5f, 1, 1, color); } -void RenderD7::Draw::TextCentered(float x, float y, float size, u32 color, std::string Text, int maxWidth, int maxHeight, C2D_Font fnt) { - float lineHeight, widthScale; +void RenderD7::Draw::TextCentered(float x, float y, float size, u32 color, + std::string Text, int maxWidth, int maxHeight, + C2D_Font fnt) { + float lineHeight, widthScale; - // Check for the lineHeight. - if (fnt != nullptr) { - lineHeight = RenderD7::Draw::GetTextHeight(size, " ", fnt); - } else { - lineHeight = RenderD7::Draw::GetTextHeight(size, " "); - } + // Check for the lineHeight. + if (fnt != nullptr) { + lineHeight = RenderD7::Draw::GetTextHeight(size, " ", fnt); + } else { + lineHeight = RenderD7::Draw::GetTextHeight(size, " "); + } - int line = 0; - while(Text.find('\n') != Text.npos) { - if (maxWidth == 0) { - // Do the widthScale. - if (fnt != nullptr) { - widthScale = RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt); - } else { - widthScale = RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n'))); - } - } else { - // Do the widthScale 2. - if (fnt != nullptr) { - widthScale = std::min((float)maxWidth, RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt)); - } else { - widthScale = std::min((float)maxWidth, RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')))); - } - } - if (fnt != nullptr) { - RenderD7::Draw::Text((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight, fnt); - } else { - RenderD7::Draw::Text((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight); - } + int line = 0; + while (Text.find('\n') != Text.npos) { + if (maxWidth == 0) { + // Do the widthScale. + if (fnt != nullptr) { + widthScale = RenderD7::Draw::GetTextWidth( + size, Text.substr(0, Text.find('\n')), fnt); + } else { + widthScale = + RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n'))); + } + } else { + // Do the widthScale 2. + if (fnt != nullptr) { + widthScale = std::min((float)maxWidth, + RenderD7::Draw::GetTextWidth( + size, Text.substr(0, Text.find('\n')), fnt)); + } else { + widthScale = std::min((float)maxWidth, + RenderD7::Draw::GetTextWidth( + size, Text.substr(0, Text.find('\n')))); + } + } + if (fnt != nullptr) { + RenderD7::Draw::Text((currentScreen ? 200 : 160) + x - (widthScale / 2), + y + (lineHeight * line), size, color, + Text.substr(0, Text.find('\n')), maxWidth, maxHeight, + fnt); + } else { + RenderD7::Draw::Text((currentScreen ? 200 : 160) + x - (widthScale / 2), + y + (lineHeight * line), size, color, + Text.substr(0, Text.find('\n')), maxWidth, + maxHeight); + } - Text = Text.substr(Text.find('\n')+1); - line++; - } + Text = Text.substr(Text.find('\n') + 1); + line++; + } - if (maxWidth == 0) { - // Do the next WidthScale. - if (fnt != nullptr) { - widthScale = RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt); - } else { - widthScale = RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n'))); - } - } else { - // And again. - if (fnt != nullptr) { - widthScale = std::min((float)maxWidth, RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt)); - } else { - widthScale = std::min((float)maxWidth, RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')))); - } - } - if (fnt != nullptr) { - RenderD7::Draw::Text((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight, fnt); - } else { - RenderD7::Draw::Text((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight); - } + if (maxWidth == 0) { + // Do the next WidthScale. + if (fnt != nullptr) { + widthScale = RenderD7::Draw::GetTextWidth( + size, Text.substr(0, Text.find('\n')), fnt); + } else { + widthScale = + RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n'))); + } + } else { + // And again. + if (fnt != nullptr) { + widthScale = std::min((float)maxWidth, + RenderD7::Draw::GetTextWidth( + size, Text.substr(0, Text.find('\n')), fnt)); + } else { + widthScale = std::min( + (float)maxWidth, + RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')))); + } + } + if (fnt != nullptr) { + RenderD7::Draw::Text((currentScreen ? 200 : 160) + x - (widthScale / 2), + y + (lineHeight * line), size, color, + Text.substr(0, Text.find('\n')), maxWidth, maxHeight, + fnt); + } else { + RenderD7::Draw::Text((currentScreen ? 200 : 160) + x - (widthScale / 2), + y + (lineHeight * line), size, color, + Text.substr(0, Text.find('\n')), maxWidth, maxHeight); + } } // Draw String or Text. -void RenderD7::Draw::Text(float x, float y, float size, u32 color, std::string Text, int maxWidth, int maxHeight, C2D_Font fnt) { - C2D_Text c2d_text; +void RenderD7::Draw::Text(float x, float y, float size, u32 color, + std::string Text, int maxWidth, int maxHeight, + C2D_Font fnt) { + C2D_Text c2d_text; - if (fnt != nullptr) { - C2D_TextFontParse(&c2d_text, fnt, TextBuf, Text.c_str()); - } else { - C2D_TextFontParse(&c2d_text, Font, TextBuf, Text.c_str()); - } + if (fnt != nullptr) { + C2D_TextFontParse(&c2d_text, fnt, TextBuf, Text.c_str()); + } else { + C2D_TextFontParse(&c2d_text, Font, TextBuf, Text.c_str()); + } - C2D_TextOptimize(&c2d_text); + C2D_TextOptimize(&c2d_text); - float heightScale; - if (maxHeight == 0) { - heightScale = size; - } else { - if (fnt != nullptr) { - heightScale = std::min(size, size*(maxHeight/RenderD7::Draw::GetTextHeight(size, Text, fnt))); - } else { - heightScale = std::min(size, size*(maxHeight/RenderD7::Draw::GetTextHeight(size, Text))); - } - } + float heightScale; + if (maxHeight == 0) { + heightScale = size; + } else { + if (fnt != nullptr) { + heightScale = std::min( + size, + size * (maxHeight / RenderD7::Draw::GetTextHeight(size, Text, fnt))); + } else { + heightScale = std::min( + size, size * (maxHeight / RenderD7::Draw::GetTextHeight(size, Text))); + } + } - if (maxWidth == 0) { - C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, size, heightScale, color); - } else { - if (fnt != nullptr) { - C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, std::min(size, size*(maxWidth/RenderD7::Draw::GetTextWidth(size, Text, fnt))), heightScale, color); - } else { - C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, std::min(size, size*(maxWidth/RenderD7::Draw::GetTextWidth(size, Text))), heightScale, color); - } - } + if (maxWidth == 0) { + C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, size, heightScale, + color); + } else { + if (fnt != nullptr) { + C2D_DrawText( + &c2d_text, C2D_WithColor, x, y, 0.5f, + std::min(size, size * (maxWidth / RenderD7::Draw::GetTextWidth( + size, Text, fnt))), + heightScale, color); + } else { + C2D_DrawText( + &c2d_text, C2D_WithColor, x, y, 0.5f, + std::min(size, size * (maxWidth / + RenderD7::Draw::GetTextWidth(size, Text))), + heightScale, color); + } + } } -void RenderD7::Draw::TextRight(float x, float y, float size, u32 color, std::string Text, int maxWidth, int maxHeight, C2D_Font fnt) -{ - RenderD7::Draw::Text(x - RenderD7::Draw::GetTextWidth(size, Text, fnt), y, size, color, Text, maxWidth, maxHeight, fnt); +void RenderD7::Draw::TextRight(float x, float y, float size, u32 color, + std::string Text, int maxWidth, int maxHeight, + C2D_Font fnt) { + RenderD7::Draw::Text(x - RenderD7::Draw::GetTextWidth(size, Text, fnt), y, + size, color, Text, maxWidth, maxHeight, fnt); } // Get String or Text Width. float RenderD7::Draw::GetTextWidth(float size, std::string Text, C2D_Font fnt) { - float width = 0; - if (fnt != nullptr) { - GetTextSize(size, &width, NULL, Text, fnt); - } else { - GetTextSize(size, &width, NULL, Text); - } - return width; + float width = 0; + if (fnt != nullptr) { + GetTextSize(size, &width, NULL, Text, fnt); + } else { + GetTextSize(size, &width, NULL, Text); + } + return width; } // Get String or Text Size. -void RenderD7::Draw::GetTextSize(float size, float *width, float *height, std::string Text, C2D_Font fnt) { - C2D_Text c2d_text; - if (fnt != nullptr) { - C2D_TextFontParse(&c2d_text, fnt, TextBuf, Text.c_str()); - } else { - C2D_TextFontParse(&c2d_text, Font, TextBuf, Text.c_str()); - } - C2D_TextGetDimensions(&c2d_text, size, size, width, height); +void RenderD7::Draw::GetTextSize(float size, float *width, float *height, + std::string Text, C2D_Font fnt) { + C2D_Text c2d_text; + if (fnt != nullptr) { + C2D_TextFontParse(&c2d_text, fnt, TextBuf, Text.c_str()); + } else { + C2D_TextFontParse(&c2d_text, Font, TextBuf, Text.c_str()); + } + C2D_TextGetDimensions(&c2d_text, size, size, width, height); } - // Get String or Text Height. -float RenderD7::Draw::GetTextHeight(float size, std::string Text, C2D_Font fnt) { - float height = 0; - if (fnt != nullptr) { - GetTextSize(size, NULL, &height, Text.c_str(), fnt); - } else { - GetTextSize(size, NULL, &height, Text.c_str()); - } - return height; +float RenderD7::Draw::GetTextHeight(float size, std::string Text, + C2D_Font fnt) { + float height = 0; + if (fnt != nullptr) { + GetTextSize(size, NULL, &height, Text.c_str(), fnt); + } else { + GetTextSize(size, NULL, &height, Text.c_str()); + } + return height; } -Result RenderD7::Draw::LoadFont(C2D_Font &fnt, const char* Path) { - fnt = C2D_FontLoad(Path); // Only load if found. - return 0; +Result RenderD7::Draw::LoadFont(C2D_Font &fnt, const char *Path) { + fnt = C2D_FontLoad(Path); // Only load if found. + return 0; } // Unload a Font. Result RenderD7::Draw::UnloadFont(C2D_Font &fnt) { - if (fnt != nullptr) { - C2D_FontFree(fnt); // Make sure to only unload if not nullptr. - } - return 0; + if (fnt != nullptr) { + C2D_FontFree(fnt); // Make sure to only unload if not nullptr. + } + return 0; } -bool RenderD7::Draw::Circle(float x, float y, float radius, u32 color) -{ - return C2D_DrawCircleSolid(x, y, 0.5f, radius, color); +bool RenderD7::Draw::Circle(float x, float y, float radius, u32 color) { + return C2D_DrawCircleSolid(x, y, 0.5f, radius, color); } -bool RenderD7::Draw::Image(C2D_Image img, float x, float y, float scaleX, float scaleY) -{ - return C2D_DrawImageAt(img, x, y, 0.5f, nullptr, scaleX, scaleY); +bool RenderD7::Draw::Image(C2D_Image img, float x, float y, float scaleX, + float scaleY) { + return C2D_DrawImageAt(img, x, y, 0.5f, nullptr, scaleX, scaleY); } -bool RenderD7::Draw::NFRect(float p1x, float p1y, float w, float h, u32 color, float scale) -{ - C2D_DrawLine(p1x, p1y, color,w, p1y, color, scale, 1); - C2D_DrawLine(w, p1y, color,w, h, color, scale, 1); - C2D_DrawLine(w, h, color,p1x, h, color, scale, 1); - C2D_DrawLine(p1x, h, color,p1x, p1y, color, scale, 1); - return true; +bool RenderD7::Draw::NFRect(float p1x, float p1y, float w, float h, u32 color, + float scale) { + C2D_DrawLine(p1x, p1y, color, w, p1y, color, scale, 1); + C2D_DrawLine(w, p1y, color, w, h, color, scale, 1); + C2D_DrawLine(w, h, color, p1x, h, color, scale, 1); + C2D_DrawLine(p1x, h, color, p1x, p1y, color, scale, 1); + return true; } \ No newline at end of file diff --git a/source/FileSystem.cpp b/source/FileSystem.cpp index 2680925..2b0193c 100644 --- a/source/FileSystem.cpp +++ b/source/FileSystem.cpp @@ -1,324 +1,344 @@ -#include #include <3ds.h> #include -//Debugging +#include +// Debugging #include #include #include -const char* RenderD7::FileSystem::GetPhysfsError() -{ - return PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()); +const char *RenderD7::FileSystem::GetPhysfsError() { + return PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()); } -std::string RenderD7::FileSystem::Normalize(const std::string& input) -{ - std::string out; - bool seenSep = false, isSep = false; +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] == '/'); + for (size_t i = 0; i < input.size(); ++i) { + isSep = (input[i] == '/'); - if (!isSep || !seenSep) - out += input[i]; + if (!isSep || !seenSep) + out += input[i]; - seenSep = isSep; - } + seenSep = isSep; + } - return out; + return out; } -void RenderD7::FileSystem::Initialize() -{ - RenderD7::FileSystem::savePath = ""; +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; } -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::SetSource(const char* source) -{ - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; +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 searchPath = source; - if (!PHYSFS_mount(searchPath.c_str(), NULL, 1)) - RenderD7::AddOvl(std::make_unique("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; + std::string old = RenderD7::FileSystem::savePath; - return true; + 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; } -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 RenderD7::FileSystem::GetSaveDirectory() { + return RenderD7::FileSystem::Normalize( + RenderD7::FileSystem::GetUserDirectory() + "/save"); +} - std::string old = RenderD7::FileSystem::savePath; +bool RenderD7::FileSystem::SetupWriteDirectory() { + if (!PHYSFS_isInit()) + RenderD7::AddOvl(std::make_unique( + "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); + return false; - RenderD7::FileSystem::savePath = RenderD7::FileSystem::Normalize(RenderD7::FileSystem::GetUserDirectory() + "/save/" + name); - printf("Save Path set to %s\n", savePath.c_str()); + if (RenderD7::FileSystem::savePath.empty()) + RenderD7::AddOvl( + std::make_unique("PHYSFS-Error", "Path is Empty")); + return false; - if (!old.empty()) - PHYSFS_unmount(old.c_str()); + std::string tmpWritePath = RenderD7::FileSystem::savePath; + std::string tmpDirectoryPath = RenderD7::FileSystem::savePath; - int success = PHYSFS_mount(savePath.c_str(), NULL, append); - printf("Save Path mounted %d\n", success); + 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; + } - return true; + 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::GetSaveDirectory() -{ - return RenderD7::FileSystem::Normalize(RenderD7::FileSystem::GetUserDirectory() + "/save"); +std::string RenderD7::FileSystem::GetUserDirectory() { + return RenderD7::FileSystem::Normalize( + PHYSFS_getPrefDir("npi-d7", "renderd7")); } -bool RenderD7::FileSystem::SetupWriteDirectory() -{ - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; +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; - if (RenderD7::FileSystem::savePath.empty()) - RenderD7::AddOvl(std::make_unique("PHYSFS-Error", "Path is Empty")); - return false; + PHYSFS_Stat stat = {}; - std::string tmpWritePath = RenderD7::FileSystem::savePath; - std::string tmpDirectoryPath = RenderD7::FileSystem::savePath; + if (!PHYSFS_stat(filename, &stat)) + RenderD7::AddOvl(std::make_unique( + "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); + return false; - if (RenderD7::FileSystem::savePath.find(RenderD7::FileSystem::GetUserDirectory()) == 0) - { - tmpWritePath = RenderD7::FileSystem::GetUserDirectory(); - tmpDirectoryPath = savePath.substr(RenderD7::FileSystem::GetUserDirectory().length()); + info.mod_time = + std::min(stat.modtime, RenderD7::FileSystem::MAX_STAMP); + info.size = std::min(stat.filesize, RenderD7::FileSystem::MAX_STAMP); - /* strip leading '/' characters from the path we want to create */ - size_t startPosition = tmpDirectoryPath.find_first_not_of('/'); + 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; - 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; + return true; } -std::string RenderD7::FileSystem::GetUserDirectory() -{ - return RenderD7::FileSystem::Normalize(PHYSFS_getPrefDir("npi-d7", "renderd7")); +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::GetInfo(const char* filename, RenderD7::FileSystem::Info& info) -{ - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; +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; - PHYSFS_Stat stat = {}; + if (!PHYSFS_isInit()) + RenderD7::AddOvl(std::make_unique( + "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); + return false; - if (!PHYSFS_stat(filename, &stat)) - RenderD7::AddOvl(std::make_unique("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; + if (file.handle) + RenderD7::FileSystem::CloseFile(file); - info.mod_time = std::min(stat.modtime, RenderD7::FileSystem::MAX_STAMP); - info.size = std::min(stat.filesize, RenderD7::FileSystem::MAX_STAMP); + 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 (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; + 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; + } - return true; + 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; } -void RenderD7::FileSystem::GetDirectoryItems(const char* path, std::vector& items) -{ - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return; +bool RenderD7::FileSystem::CloseFile(File &file) { + if (file.handle == nullptr || !PHYSFS_close(file.handle)) + return false; - char** results = PHYSFS_enumerateFiles(path); + file.handle = nullptr; - 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); + return true; } -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; +bool RenderD7::FileSystem::CreateDirectory(const char *name) { + if (!PHYSFS_isInit()) + 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 (PHYSFS_getWriteDir() == nullptr && + !RenderD7::FileSystem::SetupWriteDirectory()) + RenderD7::AddOvl(std::make_unique( + "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); + return false; - if (file.handle) - RenderD7::FileSystem::CloseFile(file); + if (!PHYSFS_mkdir(name)) + RenderD7::AddOvl(std::make_unique( + "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); + return false; - 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; + return true; } -bool RenderD7::FileSystem::CloseFile(File& file) -{ - if (file.handle == nullptr || !PHYSFS_close(file.handle)) - return false; +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; + } - file.handle = nullptr; + 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 true; + return PHYSFS_readBytes(file.handle, destination, (PHYSFS_uint64)size); } -bool RenderD7::FileSystem::CreateDirectory(const char* name) -{ - if (!PHYSFS_isInit()) - RenderD7::AddOvl(std::make_unique("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; +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; + } - if (PHYSFS_getWriteDir() == nullptr && !RenderD7::FileSystem::SetupWriteDirectory()) - RenderD7::AddOvl(std::make_unique("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; + int64_t written = PHYSFS_writeBytes(file.handle, data, (PHYSFS_uint64)size); - if (!PHYSFS_mkdir(name)) - RenderD7::AddOvl(std::make_unique("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); - return false; + if (written != size) { + 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; + return true; } \ No newline at end of file diff --git a/source/Image.cpp b/source/Image.cpp index 7decbfd..bef9c00 100644 --- a/source/Image.cpp +++ b/source/Image.cpp @@ -4,252 +4,257 @@ extern bool usedbgmsg; static u32 GetNextPowerOf2(u32 v) { - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return (v >= 64 ? v : 64); + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + return (v >= 64 ? v : 64); } -static bool C3DTexToC2DImage(C2D_Image *texture, u32 width, u32 height, u8 *buf) { - if (width >= 1024 || height >= 1024) - return false; - - C3D_Tex *tex = new C3D_Tex[sizeof(C3D_Tex)]; - Tex3DS_SubTexture *subtex = new Tex3DS_SubTexture[sizeof(Tex3DS_SubTexture)]; - subtex->width = static_cast(width); - subtex->height = static_cast(height); - // RGBA -> ABGR - for (u32 row = 0; row < subtex->width; row++) { - for (u32 col = 0; col < subtex->height; col++) { - u32 z = (row + col * subtex->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(subtex->width); - u32 h_pow2 = GetNextPowerOf2(subtex->height); - subtex->left = 0.f; - subtex->top = 1.f; - subtex->right = (subtex->width /static_cast(w_pow2)); - subtex->bottom = (1.0 - (subtex->height / static_cast(h_pow2))); - C3D_TexInit(tex, static_cast(w_pow2), static_cast(h_pow2), GPU_RGBA8); - C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST); - - std::memset(tex->data, 0, tex->size); - - for (u32 x = 0; x < subtex->width; x++) { - for (u32 y = 0; y < subtex->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))) * 4; - u32 src_pos = (y * subtex->width + x) * 4; - std::memcpy(&(static_cast(tex->data))[dst_pos], &(static_cast(buf))[src_pos], 4); - } - } - - C3D_TexFlush(tex); - tex->border = RenderD7::Color::Hex("#000000", 0); - C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER); - if (tex && subtex) { - texture->tex = tex; - texture->subtex = subtex; - return true; - } +static bool C3DTexToC2DImage(C2D_Image *texture, u32 width, u32 height, + u8 *buf) { + if (width >= 1024 || height >= 1024) return false; + + C3D_Tex *tex = new C3D_Tex[sizeof(C3D_Tex)]; + Tex3DS_SubTexture *subtex = new Tex3DS_SubTexture[sizeof(Tex3DS_SubTexture)]; + subtex->width = static_cast(width); + subtex->height = static_cast(height); + // RGBA -> ABGR + for (u32 row = 0; row < subtex->width; row++) { + for (u32 col = 0; col < subtex->height; col++) { + u32 z = (row + col * subtex->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(subtex->width); + u32 h_pow2 = GetNextPowerOf2(subtex->height); + subtex->left = 0.f; + subtex->top = 1.f; + subtex->right = (subtex->width / static_cast(w_pow2)); + subtex->bottom = (1.0 - (subtex->height / static_cast(h_pow2))); + C3D_TexInit(tex, static_cast(w_pow2), static_cast(h_pow2), + GPU_RGBA8); + C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST); + + std::memset(tex->data, 0, tex->size); + + for (u32 x = 0; x < subtex->width; x++) { + for (u32 y = 0; y < subtex->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))) * + 4; + u32 src_pos = (y * subtex->width + x) * 4; + std::memcpy(&(static_cast(tex->data))[dst_pos], + &(static_cast(buf))[src_pos], 4); + } + } + + C3D_TexFlush(tex); + tex->border = RenderD7::Color::Hex("#000000", 0); + C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER); + if (tex && subtex) { + texture->tex = tex; + texture->subtex = subtex; + return true; + } + return false; } -extern "C" -{ - #include +extern "C" { +#include } static const u32 BYTES_PER_PIXEL = 4; #define MAX_IMAGE_BYTES (48 * 1024 * 1024) namespace LIBBMP { - static void *bitmap_create(int width, int height, [[maybe_unused]] unsigned int state) { - /* ensure a stupidly large (>50Megs or so) bitmap is not created */ - if ((static_cast(width) * static_cast(height)) > (MAX_IMAGE_BYTES/BYTES_PER_PIXEL)) - return nullptr; - - return std::calloc(width * height, BYTES_PER_PIXEL); +static void *bitmap_create(int width, int height, + [[maybe_unused]] unsigned int state) { + /* ensure a stupidly large (>50Megs or so) bitmap is not created */ + if ((static_cast(width) * static_cast(height)) > + (MAX_IMAGE_BYTES / BYTES_PER_PIXEL)) + return nullptr; + + return std::calloc(width * height, BYTES_PER_PIXEL); +} + +static unsigned char *bitmap_get_buffer(void *bitmap) { + assert(bitmap); + return static_cast(bitmap); +} + +static size_t bitmap_get_bpp([[maybe_unused]] void *bitmap) { + return BYTES_PER_PIXEL; +} + +static void bitmap_destroy(void *bitmap) { + assert(bitmap); + std::free(bitmap); +} +} // namespace LIBBMP + +unsigned Image_to_C3D(C2D_Image img, const std::vector &bmpc) { + bmp_bitmap_callback_vt bitmap_callbacks = { + LIBBMP::bitmap_create, LIBBMP::bitmap_destroy, LIBBMP::bitmap_get_buffer, + LIBBMP::bitmap_get_bpp}; + + bmp_result code = BMP_OK; + bmp_image bmp; + bmp_create(&bmp, &bitmap_callbacks); + + code = bmp_analyse(&bmp, bmpc.size(), (u8 *)bmpc.data()); + if (code != BMP_OK) { + bmp_finalise(&bmp); + return 1; + } + + code = bmp_decode(&bmp); + if (code != BMP_OK) { + if ((code != BMP_INSUFFICIENT_DATA) && (code != BMP_DATA_ERROR)) { + bmp_finalise(&bmp); + return 2; } - - static unsigned char *bitmap_get_buffer(void *bitmap) { - assert(bitmap); - return static_cast(bitmap); + + /* skip if the decoded image would be ridiculously large */ + if ((bmp.width * bmp.height) > 200000) { + bmp_finalise(&bmp); + return 3; } - - static size_t bitmap_get_bpp([[maybe_unused]] void *bitmap) { - return BYTES_PER_PIXEL; + } + C2D_Image *texture = new C2D_Image(); + bool ret = C3DTexToC2DImage(texture, static_cast(bmp.width), + static_cast(bmp.height), + static_cast(bmp.bitmap)); + bmp_finalise(&bmp); + delete texture; + if (!ret) { + return 4; + } + return 0; +} + +void RenderD7::Image::LoadPng(const std::string path) { + if (usedbgmsg) { + // RenderD7::Msg::Display("RenderD7", "Loading Png:" + path, Top); + } + std::vector ImageBuffer; + unsigned width, height; + if (loadet) { + C3D_TexDelete(this->img.tex); + loadet = false; + } + lodepng::decode(ImageBuffer, width, height, path); + + this->img.tex = new C3D_Tex; + this->img.subtex = + new Tex3DS_SubTexture({(u16)width, (u16)height, 0.0f, 1.0f, + width / 1024.0f, 1.0f - (height / 1024.0f)}); + + C3D_TexInit(this->img.tex, 1024, 1024, GPU_RGBA8); + C3D_TexSetFilter(this->img.tex, GPU_LINEAR, GPU_LINEAR); + this->img.tex->border = 0xFFFFFFFF; + C3D_TexSetWrap(this->img.tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER); + + for (u32 x = 0; x < width && x < 1024; x++) { + for (u32 y = 0; y < height && y < 1024; y++) { + const u32 dstPos = ((((y >> 3) * (1024 >> 3) + (x >> 3)) << 6) + + ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | + ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) * + 4; + + const u32 srcPos = (y * width + x) * 4; + ((uint8_t *)this->img.tex->data)[dstPos + 0] = + ImageBuffer.data()[srcPos + 3]; + ((uint8_t *)this->img.tex->data)[dstPos + 1] = + ImageBuffer.data()[srcPos + 2]; + ((uint8_t *)this->img.tex->data)[dstPos + 2] = + ImageBuffer.data()[srcPos + 1]; + ((uint8_t *)this->img.tex->data)[dstPos + 3] = + ImageBuffer.data()[srcPos + 0]; } - - static void bitmap_destroy(void *bitmap) { - assert(bitmap); - std::free(bitmap); + } + loadet = true; +} + +RenderD7::Image::~Image() { + if (loadet) + C3D_TexDelete(img.tex); + loadet = false; +} + +void RenderD7::Image::Unload() { + if (loadet) + C3D_TexDelete(img.tex); + loadet = false; +} + +void RenderD7::Image::LoadPFromBuffer(const std::vector &buffer) { + std::vector ImageBuffer; + if (loadet) { + C3D_TexDelete(this->img.tex); + loadet = false; + } + unsigned width, height; + lodepng::decode(ImageBuffer, width, height, buffer); + + img.tex = new C3D_Tex; + img.subtex = + new Tex3DS_SubTexture({(u16)width, (u16)height, 0.0f, 1.0f, + width / 512.0f, 1.0f - (height / 512.0f)}); + + C3D_TexInit(img.tex, 512, 512, GPU_RGBA8); + C3D_TexSetFilter(img.tex, GPU_LINEAR, GPU_LINEAR); + img.tex->border = 0xFFFFFFFF; + C3D_TexSetWrap(img.tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER); + + for (u32 x = 0; x < width && x < 512; x++) { + for (u32 y = 0; y < height && y < 512; y++) { + const u32 dstPos = ((((y >> 3) * (512 >> 3) + (x >> 3)) << 6) + + ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | + ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) * + 4; + + const u32 srcPos = (y * width + x) * 4; + ((uint8_t *)img.tex->data)[dstPos + 0] = ImageBuffer.data()[srcPos + 3]; + ((uint8_t *)img.tex->data)[dstPos + 1] = ImageBuffer.data()[srcPos + 2]; + ((uint8_t *)img.tex->data)[dstPos + 2] = ImageBuffer.data()[srcPos + 1]; + ((uint8_t *)img.tex->data)[dstPos + 3] = ImageBuffer.data()[srcPos + 0]; } + } } +void RenderD7::Image::FromSheet(RenderD7::Sheet sheet, size_t index) {} -unsigned Image_to_C3D(C2D_Image img, const std::vector& bmpc) { - bmp_bitmap_callback_vt bitmap_callbacks = { - LIBBMP::bitmap_create, - LIBBMP::bitmap_destroy, - LIBBMP::bitmap_get_buffer, - LIBBMP::bitmap_get_bpp - }; - - bmp_result code = BMP_OK; - bmp_image bmp; - bmp_create(&bmp, &bitmap_callbacks); - - code = bmp_analyse(&bmp, bmpc.size(), (u8*)bmpc.data()); - if (code != BMP_OK) { - bmp_finalise(&bmp); - return 1; - } - - code = bmp_decode(&bmp); - if (code != BMP_OK) { - if ((code != BMP_INSUFFICIENT_DATA) && (code != BMP_DATA_ERROR)) { - bmp_finalise(&bmp); - return 2; - } - - /* skip if the decoded image would be ridiculously large */ - if ((bmp.width * bmp.height) > 200000) { - bmp_finalise(&bmp); - return 3; - } - } - C2D_Image* texture = new C2D_Image(); - bool ret = C3DTexToC2DImage(texture, static_cast(bmp.width), static_cast(bmp.height), static_cast(bmp.bitmap)); - bmp_finalise(&bmp); - delete texture; - if (!ret) - { - return 4; - } - return 0; +bool RenderD7::Image::Draw(float x, float y, float scaleX, float scaleY) { + if (loadet) + return C2D_DrawImageAt(this->img, x, y, 0.5f, nullptr, scaleX, scaleY); + return false; } -void RenderD7::Image::LoadPng(const std::string path) -{ - if (usedbgmsg) - { - //RenderD7::Msg::Display("RenderD7", "Loading Png:" + path, Top); - } - std::vector ImageBuffer; - unsigned width, height; - if (loadet) - { - C3D_TexDelete(this->img.tex); - loadet = false; - } - lodepng::decode(ImageBuffer, width, height, path); +void RenderD7::Image::LoadFromBitmap(BMP bitmap) { + loadet = false; + unsigned error = Image_to_C3D(this->img, bitmap.DATA()); + if (error == 0) { + this->loadet = true; + } - this->img.tex = new C3D_Tex; - this->img.subtex = new Tex3DS_SubTexture({(u16)width, (u16)height, 0.0f, 1.0f, width / 1024.0f, 1.0f - (height / 1024.0f)}); - - C3D_TexInit(this->img.tex, 1024, 1024, GPU_RGBA8); - C3D_TexSetFilter(this->img.tex, GPU_LINEAR, GPU_LINEAR); - this->img.tex->border = 0xFFFFFFFF; - C3D_TexSetWrap(this->img.tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER); - - for (u32 x = 0; x < width && x < 1024; x++) { - for (u32 y = 0; y < height && y < 1024; y++) { - const u32 dstPos = ((((y >> 3) * (1024 >> 3) + (x >> 3)) << 6) + - ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) | - ((x & 4) << 2) | ((y & 4) << 3))) * 4; - - const u32 srcPos = (y * width + x) * 4; - ((uint8_t *)this->img.tex->data)[dstPos + 0] = ImageBuffer.data()[srcPos + 3]; - ((uint8_t *)this->img.tex->data)[dstPos + 1] = ImageBuffer.data()[srcPos + 2]; - ((uint8_t *)this->img.tex->data)[dstPos + 2] = ImageBuffer.data()[srcPos + 1]; - ((uint8_t *)this->img.tex->data)[dstPos + 3] = ImageBuffer.data()[srcPos + 0]; - } - } - loadet = true; -} - -RenderD7::Image::~Image() -{ - if(loadet) C3D_TexDelete(img.tex); - loadet = false; -} - -void RenderD7::Image::Unload() -{ - if(loadet) C3D_TexDelete(img.tex); - loadet = false; -} - -void RenderD7::Image::LoadPFromBuffer(const std::vector &buffer) -{ - std::vector ImageBuffer; - if (loadet) - { - C3D_TexDelete(this->img.tex); - loadet = false; - } - unsigned width, height; - lodepng::decode(ImageBuffer, width, height, buffer); - - img.tex = new C3D_Tex; - img.subtex = new Tex3DS_SubTexture({(u16)width, (u16)height, 0.0f, 1.0f, width / 512.0f, 1.0f - (height / 512.0f)}); - - C3D_TexInit(img.tex, 512, 512, GPU_RGBA8); - C3D_TexSetFilter(img.tex, GPU_LINEAR, GPU_LINEAR); - img.tex->border = 0xFFFFFFFF; - C3D_TexSetWrap(img.tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER); - - for (u32 x = 0; x < width && x < 512; x++) { - for (u32 y = 0; y < height && y < 512; y++) { - const u32 dstPos = ((((y >> 3) * (512 >> 3) + (x >> 3)) << 6) + - ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) | - ((x & 4) << 2) | ((y & 4) << 3))) * 4; - - const u32 srcPos = (y * width + x) * 4; - ((uint8_t *)img.tex->data)[dstPos + 0] = ImageBuffer.data()[srcPos + 3]; - ((uint8_t *)img.tex->data)[dstPos + 1] = ImageBuffer.data()[srcPos + 2]; - ((uint8_t *)img.tex->data)[dstPos + 2] = ImageBuffer.data()[srcPos + 1]; - ((uint8_t *)img.tex->data)[dstPos + 3] = ImageBuffer.data()[srcPos + 0]; - } - } -} - -void RenderD7::Image::FromSheet(RenderD7::Sheet sheet, size_t index) -{ - -} - -bool RenderD7::Image::Draw(float x, float y, float scaleX, float scaleY) -{ - if(loadet) return C2D_DrawImageAt(this->img, x, y, 0.5f, nullptr, scaleX, scaleY); - return false; -} - -void RenderD7::Image::LoadFromBitmap(BMP bitmap) -{ - loadet = false; - unsigned error = Image_to_C3D(this->img, bitmap.DATA()); - if (error == 0) - { - this->loadet = true; - } - - if(error) { + if (error) { std::cout << "BMP decoding error " << error << std::endl; - RenderD7::AddOvl(std::make_unique("Bmp - Error", "Code: " + std::to_string(error))); + RenderD7::AddOvl(std::make_unique( + "Bmp - Error", "Code: " + std::to_string(error))); } } \ No newline at end of file diff --git a/source/NFontApi.cpp b/source/NFontApi.cpp index 69285ab..9b50987 100644 --- a/source/NFontApi.cpp +++ b/source/NFontApi.cpp @@ -1,76 +1,66 @@ #include -#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation +#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate + // implementation #include #define STB_IMAGE_WRITE_IMPLEMENTATION #include -RenderD7::NFontApi::NFontApi() -{ - +RenderD7::NFontApi::NFontApi() {} + +RenderD7::NFontApi::~NFontApi() {} + +void RenderD7::NFontApi::LoadTTF(std::string path) { + /////READ FILE + unsigned char *buffer; + long size = 0; + FILE *ttf__ = fopen(path.c_str(), "rb"); + fseek(ttf__, 0, SEEK_END); + size = ftell(ttf__); + fseek(ttf__, 0, SEEK_SET); + buffer = (unsigned char *)malloc(size); + fread(buffer, size, 1, ttf__); + fclose(ttf__); + /////Setup Font + if (!stbtt_InitFont(&font, buffer, 0)) { + printf("failed\n"); + status += "failed\n"; + return; + } + status += "success!\n"; + b_h = 128; + b_w = 512; + l_h = 24; /* line height */ + scale = stbtt_ScaleForPixelHeight(&font, l_h); + + stbtt_GetFontVMetrics(&font, &ascent, &decent, &linegap); + linespace = scale * (ascent - decent + linegap); + + baseline = (int)(ascent * scale); + height = (int)((ascent - decent) * scale); } -RenderD7::NFontApi::~NFontApi() -{ - +unsigned char *RenderD7::NFontApi::GetGlyphBitmap(char glyph) { + // stbtt_GetGlyphBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); + stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); + w = x1 - x0; + h = y1 - y0; + + unsigned char *bitmap; + bitmap = stbtt_GetCodepointBitmap(&font, scale, scale, glyph, &w, &h, 0, 0); + return bitmap; } -void RenderD7::NFontApi::LoadTTF(std::string path) -{ - /////READ FILE - unsigned char* buffer; - long size = 0; - FILE *ttf__ = fopen(path.c_str(), "rb"); - fseek(ttf__, 0, SEEK_END); - size = ftell(ttf__); - fseek(ttf__, 0, SEEK_SET); - buffer = (unsigned char*)malloc(size); - fread(buffer, size, 1, ttf__); - fclose(ttf__); - /////Setup Font - if (!stbtt_InitFont(&font, buffer, 0)) - { - printf("failed\n"); - status+="failed\n"; - return; - } - status+="success!\n"; - b_h = 128; - b_w = 512; - l_h = 24; /* line height */ - scale = stbtt_ScaleForPixelHeight(&font, l_h); - - stbtt_GetFontVMetrics(&font, &ascent,&decent,&linegap); - linespace = scale * (ascent - decent + linegap); - - baseline = (int) (ascent*scale); - height = (int) ((ascent - decent)*scale); +int RenderD7::NFontApi::GetGlyphHeight(char glyph) { + stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); + w = x1 - x0; + h = y1 - y0; + return h; } -unsigned char* RenderD7::NFontApi::GetGlyphBitmap(char glyph) -{ - //stbtt_GetGlyphBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); - stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); - w = x1-x0; - h = y1-y0; - - unsigned char* bitmap; - bitmap = stbtt_GetCodepointBitmap(&font, scale, scale, glyph, &w, &h, 0, 0); - return bitmap; -} - -int RenderD7::NFontApi::GetGlyphHeight(char glyph) -{ - stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); - w = x1-x0; - h = y1-y0; - return h; -} - -int RenderD7::NFontApi::GetGlyphWidth(char glyph) -{ - stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); - w = x1-x0; - h = y1-y0; - return w; +int RenderD7::NFontApi::GetGlyphWidth(char glyph) { + stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); + w = x1 - x0; + h = y1 - y0; + return w; } diff --git a/source/Screen.cpp b/source/Screen.cpp index c7c193f..b123de8 100644 --- a/source/Screen.cpp +++ b/source/Screen.cpp @@ -2,8 +2,7 @@ extern bool currentScreen; -void RenderD7::OnScreen(C3D_RenderTarget *target) -{ - C2D_SceneBegin(target); - currentScreen = (target == Top || target == TopRight) ? 1 : 0; +void RenderD7::OnScreen(C3D_RenderTarget *target) { + C2D_SceneBegin(target); + currentScreen = (target == Top || target == TopRight) ? 1 : 0; } \ No newline at end of file diff --git a/source/Sheet.cpp b/source/Sheet.cpp index ff8cfb8..bba2948 100644 --- a/source/Sheet.cpp +++ b/source/Sheet.cpp @@ -1,21 +1,15 @@ #include -RenderD7::Sheet::Sheet() -{ - // +RenderD7::Sheet::Sheet() { + // } -RenderD7::Sheet::~Sheet() -{ - // +RenderD7::Sheet::~Sheet() { + // } -Result RenderD7::Sheet::Load(const char *path) -{ - this->spritesheet = C2D_SpriteSheetLoad(path); - return 0; +Result RenderD7::Sheet::Load(const char *path) { + this->spritesheet = C2D_SpriteSheetLoad(path); + return 0; } -void RenderD7::Sheet::Free() -{ - C2D_SpriteSheetFree(this->spritesheet); -} +void RenderD7::Sheet::Free() { C2D_SpriteSheetFree(this->spritesheet); } diff --git a/source/Sprite.cpp b/source/Sprite.cpp index d58a103..fc0138b 100644 --- a/source/Sprite.cpp +++ b/source/Sprite.cpp @@ -1,60 +1,36 @@ #include -RenderD7::Sprite::Sprite() -{ -// +RenderD7::Sprite::Sprite() { + // } -RenderD7::Sprite::~Sprite() -{ - // +RenderD7::Sprite::~Sprite() { + // } -void RenderD7::Sprite::FromSheet(RenderD7::Sheet *sheet, size_t index) -{ - C2D_SpriteFromSheet(&this->sprite, sheet->spritesheet, index); +void RenderD7::Sprite::FromSheet(RenderD7::Sheet *sheet, size_t index) { + C2D_SpriteFromSheet(&this->sprite, sheet->spritesheet, index); } -bool RenderD7::Sprite::Draw() -{ - return C2D_DrawSprite(&this->sprite); +bool RenderD7::Sprite::Draw() { return C2D_DrawSprite(&this->sprite); } +void RenderD7::Sprite::SetCenter(float x, float y) { + C2D_SpriteSetCenter(&this->sprite, x, y); } -void RenderD7::Sprite::SetCenter(float x, float y) -{ - C2D_SpriteSetCenter(&this->sprite, x, y); +void RenderD7::Sprite::SetPos(float x, float y) { + C2D_SpriteSetPos(&this->sprite, x, y); } -void RenderD7::Sprite::SetPos(float x, float y) -{ - C2D_SpriteSetPos(&this->sprite, x, y); +void RenderD7::Sprite::SetRotation(float rotation) { + C2D_SpriteSetRotation(&this->sprite, rotation); } -void RenderD7::Sprite::SetRotation(float rotation) -{ - C2D_SpriteSetRotation(&this->sprite, rotation); +void RenderD7::Sprite::Rotate(float speed) { + C2D_SpriteRotateDegrees(&this->sprite, speed); } -void RenderD7::Sprite::Rotate(float speed) -{ - C2D_SpriteRotateDegrees(&this->sprite, speed); -} -float RenderD7::Sprite::getHeigh() -{ - return this->sprite.params.pos.h; -} -float RenderD7::Sprite::getWidth() -{ - return this->sprite.params.pos.w; -} -float RenderD7::Sprite::getPosX() -{ - return this->sprite.params.pos.x; -} -float RenderD7::Sprite::getPosY() -{ - return this->sprite.params.pos.y; +float RenderD7::Sprite::getHeigh() { return this->sprite.params.pos.h; } +float RenderD7::Sprite::getWidth() { return this->sprite.params.pos.w; } +float RenderD7::Sprite::getPosX() { return this->sprite.params.pos.x; } +float RenderD7::Sprite::getPosY() { return this->sprite.params.pos.y; } + +void RenderD7::Sprite::FromImage(RenderD7::Image *img) { + C2D_SpriteFromImage(&this->sprite, img->img); } -void RenderD7::Sprite::FromImage(RenderD7::Image *img) -{ - C2D_SpriteFromImage(&this->sprite, img->img); -} - -void RenderD7::Sprite::SetScale(float x, float y) -{ - C2D_SpriteScale(&this->sprite, x, y); +void RenderD7::Sprite::SetScale(float x, float y) { + C2D_SpriteScale(&this->sprite, x, y); } \ No newline at end of file diff --git a/source/SpriteSheetAnimation.cpp b/source/SpriteSheetAnimation.cpp index e923933..88395f3 100644 --- a/source/SpriteSheetAnimation.cpp +++ b/source/SpriteSheetAnimation.cpp @@ -3,39 +3,36 @@ extern Log renderd7log; -RenderD7::SpriteSheetAnimation::SpriteSheetAnimation() -{ - renderd7log.Write("SpriteSheetAnimation createt!"); +RenderD7::SpriteSheetAnimation::SpriteSheetAnimation() { + renderd7log.Write("SpriteSheetAnimation createt!"); } -RenderD7::SpriteSheetAnimation::~SpriteSheetAnimation() -{ - // +RenderD7::SpriteSheetAnimation::~SpriteSheetAnimation() { + // } -void RenderD7::SpriteSheetAnimation::Setup(RenderD7::Sheet *sheet, size_t imagecount, size_t startimage, float frame_begin, float frame_finish) -{ - D_totaltime = frame_begin; - renderd7log.Write("frame_begin success"); - this->images = imagecount; - renderd7log.Write("imagecount success"); - this->sheet = sheet; - renderd7log.Write("sheet success"); - this->time = frame_finish; - renderd7log.Write("frame_finish success"); - RenderD7::SpriteSheetAnimation::FromSheet(this->sheet, startimage); +void RenderD7::SpriteSheetAnimation::Setup(RenderD7::Sheet *sheet, + size_t imagecount, size_t startimage, + float frame_begin, + float frame_finish) { + D_totaltime = frame_begin; + renderd7log.Write("frame_begin success"); + this->images = imagecount; + renderd7log.Write("imagecount success"); + this->sheet = sheet; + renderd7log.Write("sheet success"); + this->time = frame_finish; + renderd7log.Write("frame_finish success"); + RenderD7::SpriteSheetAnimation::FromSheet(this->sheet, startimage); } -void RenderD7::SpriteSheetAnimation::Play(float timespeed) -{ - D_totaltime += timespeed; - if (D_totaltime >= time) - { - D_totaltime -= time; - imgs++; - if (imgs == images) - { - imgs = 0; - } +void RenderD7::SpriteSheetAnimation::Play(float timespeed) { + D_totaltime += timespeed; + if (D_totaltime >= time) { + D_totaltime -= time; + imgs++; + if (imgs == images) { + imgs = 0; } - RenderD7::SpriteSheetAnimation::FromSheet(sheet, imgs); - //RenderD7::SpriteSheetAnimation::Draw(); + } + RenderD7::SpriteSheetAnimation::FromSheet(sheet, imgs); + // RenderD7::SpriteSheetAnimation::Draw(); } \ No newline at end of file diff --git a/source/Time.cpp b/source/Time.cpp index 0204637..9345ca8 100644 --- a/source/Time.cpp +++ b/source/Time.cpp @@ -1,31 +1,30 @@ -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include #include +#include +#include - -std::string RenderD7::FormatString(std::string fmt_str, ...) -{ - va_list ap; - char* fp = NULL; - va_start(ap, fmt_str); - vasprintf(&fp, fmt_str.c_str(), ap); - va_end(ap); - std::unique_ptr formatted(fp, free); - return std::string(formatted.get()); +std::string RenderD7::FormatString(std::string fmt_str, ...) { + va_list ap; + char *fp = NULL; + va_start(ap, fmt_str); + vasprintf(&fp, fmt_str.c_str(), ap); + va_end(ap); + std::unique_ptr formatted(fp, free); + return std::string(formatted.get()); } -std::string RenderD7::GetTimeStr(void) -{ - time_t unixTime; - struct tm timeStruct; - time(&unixTime); - localtime_r(&unixTime, &timeStruct); - return FormatString("%04i-%02i-%02i_%02i-%02i-%02i", timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, timeStruct.tm_mday, - timeStruct.tm_hour, timeStruct.tm_min, timeStruct.tm_sec); +std::string RenderD7::GetTimeStr(void) { + time_t unixTime; + struct tm timeStruct; + time(&unixTime); + localtime_r(&unixTime, &timeStruct); + return FormatString("%04i-%02i-%02i_%02i-%02i-%02i", + timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, + timeStruct.tm_mday, timeStruct.tm_hour, timeStruct.tm_min, + timeStruct.tm_sec); } diff --git a/source/Toast.cpp b/source/Toast.cpp index 678ab39..e12941b 100644 --- a/source/Toast.cpp +++ b/source/Toast.cpp @@ -1,37 +1,38 @@ -#include #include +#include -RenderD7::Toast::Toast(std::string head, std::string msg) -{ - this->head = head; - this->msg = msg; - /*this->toast = RenderD7::BitmapPrinter(400, 70); - this->toast.ClearBlank(); - this->toast.DrawRectFilled(0, 0, 400, 70, 40, 40, 40, 255); - this->toast.DrawRectFilled(0, 0, 400, 25, 70, 70, 70, 255); - this->toast.DrawDebugText(4, 5, 0, RenderD7::Color::Hex("#ffffff"), this->head); - this->toast.DrawDebugText(4, 40, 0, RenderD7::Color::Hex("#ffffff"), this->msg); - this->toastrendered->LoadPFromBuffer(BitmapConverter::ConvertData(toast.GetBitmap().DATA()));*/ +RenderD7::Toast::Toast(std::string head, std::string msg) { + this->head = head; + this->msg = msg; + /*this->toast = RenderD7::BitmapPrinter(400, 70); + this->toast.ClearBlank(); + this->toast.DrawRectFilled(0, 0, 400, 70, 40, 40, 40, 255); + this->toast.DrawRectFilled(0, 0, 400, 25, 70, 70, 70, 255); + this->toast.DrawDebugText(4, 5, 0, RenderD7::Color::Hex("#ffffff"), + this->head); this->toast.DrawDebugText(4, 40, 0, + RenderD7::Color::Hex("#ffffff"), this->msg); + this->toastrendered->LoadPFromBuffer(BitmapConverter::ConvertData(toast.GetBitmap().DATA()));*/ } -void RenderD7::Toast::Draw(void) const -{ - RenderD7::OnScreen(Top); - RenderD7::Draw::Rect(0, msgposy, 400, 70, RenderD7::Color::Hex("#111111")); - RenderD7::Draw::Rect(0, msgposy, 400, 25, RenderD7::Color::Hex("#222222")); - RenderD7::Draw::Text(2, msgposy+3, 0.7f, RenderD7::Color::Hex("#ffffff"), head); - RenderD7::Draw::Text(2, msgposy+30, 0.6f, RenderD7::Color::Hex("#ffffff"), msg); - //toastrendered->Draw(0, msgposy); +void RenderD7::Toast::Draw(void) const { + RenderD7::OnScreen(Top); + RenderD7::Draw::Rect(0, msgposy, 400, 70, RenderD7::Color::Hex("#111111")); + RenderD7::Draw::Rect(0, msgposy, 400, 25, RenderD7::Color::Hex("#222222")); + RenderD7::Draw::Text(2, msgposy + 3, 0.7f, RenderD7::Color::Hex("#ffffff"), + head); + RenderD7::Draw::Text(2, msgposy + 30, 0.6f, RenderD7::Color::Hex("#ffffff"), + msg); + // toastrendered->Draw(0, msgposy); } -void RenderD7::Toast::Logic() -{ - this->delay++/*=1*(int)RenderD7::GetDeltaTime()*/; - if (msgposy > 170 && delay < 2*60) msgposy--/*=(int)RenderD7::GetDeltaTime()*/; - - if (delay >= 5*60) - { - msgposy++/*=(int)RenderD7::GetDeltaTime*/; - if(msgposy > 400) this->Kill(); - } +void RenderD7::Toast::Logic() { + this->delay++ /*=1*(int)RenderD7::GetDeltaTime()*/; + if (msgposy > 170 && delay < 2 * 60) + msgposy-- /*=(int)RenderD7::GetDeltaTime()*/; + + if (delay >= 5 * 60) { + msgposy++ /*=(int)RenderD7::GetDeltaTime*/; + if (msgposy > 400) + this->Kill(); + } } \ No newline at end of file diff --git a/source/bmpconverter.cpp b/source/bmpconverter.cpp index 13e6d5f..4f76c98 100644 --- a/source/bmpconverter.cpp +++ b/source/bmpconverter.cpp @@ -1,29 +1,36 @@ #include -namespace BitmapConverter{ +namespace BitmapConverter { -//returns 0 if all went ok, non-0 if error -//output image is always given in RGBA (with alpha channel), even if it's a BMP without alpha channel -unsigned decodeBMP(std::vector& image, unsigned& w, unsigned& h, const std::vector& bmp) { - static const unsigned MINHEADER = 54; //minimum BMP header size +// returns 0 if all went ok, non-0 if error +// output image is always given in RGBA (with alpha channel), even if it's a BMP +// without alpha channel +unsigned decodeBMP(std::vector &image, unsigned &w, unsigned &h, + const std::vector &bmp) { + static const unsigned MINHEADER = 54; // minimum BMP header size - if(bmp.size() < MINHEADER) return -1; - if(bmp[0] != 'B' || bmp[1] != 'M') return 1; //It's not a BMP file if it doesn't start with marker 'BM' - unsigned pixeloffset = bmp[10] + 256 * bmp[11]; //where the pixel data starts - //read width and height from BMP header + if (bmp.size() < MINHEADER) + return -1; + if (bmp[0] != 'B' || bmp[1] != 'M') + return 1; // It's not a BMP file if it doesn't start with marker 'BM' + unsigned pixeloffset = bmp[10] + 256 * bmp[11]; // where the pixel data starts + // read width and height from BMP header w = bmp[18] + bmp[19] * 256; h = bmp[22] + bmp[23] * 256; - //read number of channels from BMP header - if(bmp[28] != 24 && bmp[28] != 32) return 2; //only 24-bit and 32-bit BMPs are supported. + // read number of channels from BMP header + if (bmp[28] != 24 && bmp[28] != 32) + return 2; // only 24-bit and 32-bit BMPs are supported. unsigned numChannels = bmp[28] / 8; - //The amount of scanline bytes is width of image times channels, with extra bytes added if needed - //to make it a multiple of 4 bytes. + // The amount of scanline bytes is width of image times channels, with extra + // bytes added if needed to make it a multiple of 4 bytes. unsigned scanlineBytes = w * numChannels; - if(scanlineBytes % 4 != 0) scanlineBytes = (scanlineBytes / 4) * 4 + 4; + if (scanlineBytes % 4 != 0) + scanlineBytes = (scanlineBytes / 4) * 4 + 4; unsigned dataSize = scanlineBytes * h; - if(bmp.size() < dataSize + pixeloffset) return 3; //BMP file too small to contain all pixels + if (bmp.size() < dataSize + pixeloffset) + return 3; // BMP file too small to contain all pixels image.resize(w * h * 4); @@ -34,24 +41,25 @@ unsigned decodeBMP(std::vector& image, unsigned& w, unsigned& h, -each scanline has padding bytes to make it a multiple of 4 if needed The 2D for loop below does all these 3 conversions at once. */ - for(unsigned y = 0; y < h; y++) - for(unsigned x = 0; x < w; x++) { - //pixel start byte position in the BMP - unsigned bmpos = pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x; - //pixel start byte position in the new raw image - unsigned newpos = 4 * y * w + 4 * x; - if(numChannels == 3) { - image[newpos + 0] = bmp[bmpos + 2]; //R - image[newpos + 1] = bmp[bmpos + 1]; //G - image[newpos + 2] = bmp[bmpos + 0]; //B - image[newpos + 3] = 255; //A - } else { - image[newpos + 0] = bmp[bmpos + 2]; //R - image[newpos + 1] = bmp[bmpos + 1]; //G - image[newpos + 2] = bmp[bmpos + 0]; //B - image[newpos + 3] = bmp[bmpos + 3]; //A + for (unsigned y = 0; y < h; y++) + for (unsigned x = 0; x < w; x++) { + // pixel start byte position in the BMP + unsigned bmpos = + pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x; + // pixel start byte position in the new raw image + unsigned newpos = 4 * y * w + 4 * x; + if (numChannels == 3) { + image[newpos + 0] = bmp[bmpos + 2]; // R + image[newpos + 1] = bmp[bmpos + 1]; // G + image[newpos + 2] = bmp[bmpos + 0]; // B + image[newpos + 3] = 255; // A + } else { + image[newpos + 0] = bmp[bmpos + 2]; // R + image[newpos + 1] = bmp[bmpos + 1]; // G + image[newpos + 2] = bmp[bmpos + 0]; // B + image[newpos + 3] = bmp[bmpos + 3]; // A + } } - } return 0; } @@ -59,48 +67,44 @@ std::vector ConvertFile(std::string filename) { std::vector bmp; lodepng::load_file(bmp, filename); - + std::vector image; unsigned w, h; unsigned error = BitmapConverter::decodeBMP(image, w, h, bmp); - if(error) { + if (error) { std::cout << "BMP decoding error " << error << std::endl; - } std::vector png; error = lodepng::encode(png, image, w, h); - if(error) { - std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl; - + if (error) { + std::cout << "PNG encoding error " << error << ": " + << lodepng_error_text(error) << std::endl; } return png; - } std::vector ConvertData(std::vector data) { - + std::vector image; unsigned w, h; unsigned error = BitmapConverter::decodeBMP(image, w, h, data); - if(error) { + if (error) { std::cout << "BMP decoding error " << error << std::endl; - } std::vector png; error = lodepng::encode(png, image, w, h); - if(error) { - std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl; - + if (error) { + std::cout << "PNG encoding error " << error << ": " + << lodepng_error_text(error) << std::endl; } return png; - } -} \ No newline at end of file +} // namespace BitmapConverter \ No newline at end of file diff --git a/source/lang.cpp b/source/lang.cpp index 167ff65..26ec5ba 100644 --- a/source/lang.cpp +++ b/source/lang.cpp @@ -1,98 +1,97 @@ +#include <3ds.h> #include #include -#include #include -#include <3ds.h> +#include static nlohmann::json appJson; -std::string RenderD7::Lang::getSys() -{ - - u8 language = 1; - CFGU_GetSystemLanguage(&language); +std::string RenderD7::Lang::getSys() { - switch(language) { - case 0: - return "jp"; // Japanese - break; + u8 language = 1; + CFGU_GetSystemLanguage(&language); - case 1: - return "en"; // English - break; + switch (language) { + case 0: + return "jp"; // Japanese + break; - case 2: - return "fr"; // French - break; + case 1: + return "en"; // English + break; - case 3: - return "de"; // German - break; + case 2: + return "fr"; // French + break; - case 4: - return "it"; // Italian - break; + case 3: + return "de"; // German + break; - case 5: - return "es"; // Spanish - break; + case 4: + return "it"; // Italian + break; - case 6: - return "zh-CN"; // Chinese (Simplified) - break; + case 5: + return "es"; // Spanish + break; - // case 7: - // return "ko"; // Korean - // break; + case 6: + return "zh-CN"; // Chinese (Simplified) + break; - // case 8: - // return "nl"; // Dutch - // break; + // case 7: + // return "ko"; // Korean + // break; - case 9: - return "pt"; // Portuguese - break; + // case 8: + // return "nl"; // Dutch + // break; - case 10: - return "ru"; // Russian - break; + case 9: + return "pt"; // Portuguese + break; - case 11: - return "zh-TW"; // Chinese (Traditional) - break; + case 10: + return "ru"; // Russian + break; - default: - return "en"; // Fall back to English if missing - break; - } + case 11: + return "zh-TW"; // Chinese (Traditional) + break; + default: + return "en"; // Fall back to English if missing + break; + } } std::string RenderD7::Lang::get(const std::string &key) { - if (!appJson.contains(key)) return key; + if (!appJson.contains(key)) + return key; - return appJson.at(key).get_ref(); + return appJson.at(key).get_ref(); } void RenderD7::Lang::load(const std::string &lang) { - FILE *values; + FILE *values; - if (access(("romfs:/lang/" + lang + "/app.json").c_str(), F_OK) == 0) { - values = fopen(("romfs:/lang/" + lang + "/app.json").c_str(), "rt"); - if (values) { - appJson = nlohmann::json::parse(values, nullptr, false); - fclose(values); - } - if (appJson.is_discarded()) - appJson = { }; - return; + if (access(("romfs:/lang/" + lang + "/app.json").c_str(), F_OK) == 0) { + values = fopen(("romfs:/lang/" + lang + "/app.json").c_str(), "rt"); + if (values) { + appJson = nlohmann::json::parse(values, nullptr, false); + fclose(values); + } + if (appJson.is_discarded()) + appJson = {}; + return; - } else { - values = fopen("romfs:/lang/en/app.json", "rt"); - if (values) { - appJson = nlohmann::json::parse(values, nullptr, false); - fclose(values); - } - if (appJson.is_discarded()) - appJson = { }; - return; - } + } else { + values = fopen("romfs:/lang/en/app.json", "rt"); + if (values) { + appJson = nlohmann::json::parse(values, nullptr, false); + fclose(values); + } + if (appJson.is_discarded()) + appJson = {}; + return; + } } \ No newline at end of file diff --git a/source/log.cpp b/source/log.cpp index 72f4518..0024612 100644 --- a/source/log.cpp +++ b/source/log.cpp @@ -2,62 +2,50 @@ #include -std::string Log::format(const std::string& fmt_str, ...) -{ - va_list ap; - char* fp = NULL; - va_start(ap, fmt_str); - vasprintf(&fp, fmt_str.c_str(), ap); - va_end(ap); - std::unique_ptr formatted(fp, free); - return std::string(formatted.get()); +std::string Log::format(const std::string &fmt_str, ...) { + va_list ap; + char *fp = NULL; + va_start(ap, fmt_str); + vasprintf(&fp, fmt_str.c_str(), ap); + va_end(ap); + std::unique_ptr formatted(fp, free); + return std::string(formatted.get()); } -std::string Log::logDate(void) -{ - time_t unixTime; - struct tm timeStruct; - time(&unixTime); - localtime_r(&unixTime, &timeStruct); - return format("%04i-%02i-%02i_%02i-%02i-%02i", timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, timeStruct.tm_mday, - timeStruct.tm_hour, timeStruct.tm_min, timeStruct.tm_sec); +std::string Log::logDate(void) { + time_t unixTime; + struct tm timeStruct; + time(&unixTime); + localtime_r(&unixTime, &timeStruct); + return format("%04i-%02i-%02i_%02i-%02i-%02i", timeStruct.tm_year + 1900, + timeStruct.tm_mon + 1, timeStruct.tm_mday, timeStruct.tm_hour, + timeStruct.tm_min, timeStruct.tm_sec); } -Log::Log() -{ +Log::Log() {} +void Log::Init(const char *filename) { + printf("%s\n", filename); + std::string fn = filename; + std::string name = fn + ".txt"; + this->filename = name.c_str(); + if ((access(name.c_str(), F_OK) == 0)) { + + } else { + FILE *logfile = fopen((name.c_str()), "w"); + fclose(logfile); + } } -void Log::Init(const char *filename) -{ - printf("%s\n", filename); - std::string fn = filename; - std::string name = fn + ".txt"; - this->filename = name.c_str(); - if ((access(name.c_str(), F_OK) == 0)) - { - - } - else - { - FILE* logfile = fopen((name.c_str()), "w"); - fclose(logfile); - } -} - -void Log::Write(std::string debug_text) -{ - printf("%s\n", debug_text.c_str()); - std::ofstream logFile; - logFile.open((this->filename), std::ofstream::app); - std::string writeDebug = "["; - writeDebug += logDate(); - writeDebug += "] "; - writeDebug += debug_text.c_str(); - logFile << writeDebug << std::endl; - logFile.close(); -} -Log::~Log() -{ - +void Log::Write(std::string debug_text) { + printf("%s\n", debug_text.c_str()); + std::ofstream logFile; + logFile.open((this->filename), std::ofstream::app); + std::string writeDebug = "["; + writeDebug += logDate(); + writeDebug += "] "; + writeDebug += debug_text.c_str(); + logFile << writeDebug << std::endl; + logFile.close(); } +Log::~Log() {} diff --git a/source/renderd7.cpp b/source/renderd7.cpp index f85df6a..227d7bc 100644 --- a/source/renderd7.cpp +++ b/source/renderd7.cpp @@ -1,6 +1,7 @@ -#include -#include #include +#include +#include + #define D7_NOTHING C2D_Color32(0, 0, 0, 0) #define CFGVER "3" @@ -16,7 +17,7 @@ std::string dspststus = "Not Initialisized!"; int cobj___; int maxobj__; -//INI::INIFile cfgfile; +// INI::INIFile cfgfile; std::unique_ptr cfgfile = nullptr; INI::INIStructure cfgstruct; std::string cfgpath; @@ -46,7 +47,7 @@ static u64 last_time = 0; float d11framerate = 0; //----------------- -//Metrik------------------------------------- +// Metrik------------------------------------- u32 mt_color; u32 mt_txtcolor; @@ -58,940 +59,960 @@ std::string mt_cmd; bool shouldbe_disabled = false; int cnttttt = 0; int mt_screen; -//int mt_width = mt_screen ? 320 : 400; +// int mt_width = mt_screen ? 320 : 400; float mt_txtSize; bool metrikd = false; -//double mt_fpsgraph[320]; +// double mt_fpsgraph[320]; std::vector mt_fpsgraph(320); -//Metrik-CSV +// Metrik-CSV std::string csvpc; -bool mt_dumpcsv = false; //Logs the Fps and stuff to csv. It saves every second to not loose performence. -bool mt_csvloop = false; //Saves In Every Frame but slows down performens. mt_dumpcsv must be enabled. +bool mt_dumpcsv = false; // Logs the Fps and stuff to csv. It saves every second + // to not loose performence. +bool mt_csvloop = false; // Saves In Every Frame but slows down performens. + // mt_dumpcsv must be enabled. std::ofstream mt_csv; std::string mt_cname; //------------------------------------------- bool currentScreen = false; -C3D_RenderTarget* Top; -C3D_RenderTarget* TopRight; -C3D_RenderTarget* Bottom; +C3D_RenderTarget *Top; +C3D_RenderTarget *TopRight; +C3D_RenderTarget *Bottom; -#define DSEVENBLACK C2D_Color32(0, 0 ,0, 255) +#define DSEVENBLACK C2D_Color32(0, 0, 0, 255) #define DSEVENWHITE C2D_Color32(255, 255, 255, 255) u64 delta_time; -//Screen Fade +// Screen Fade bool fadeout = false, fadein = false, fadeout2 = false, fadein2 = false; int fadealpha = 0; int fadecolor = 0; - -std::string _FMT_(const std::string& fmt_str, ...) -{ - va_list ap; - char* fp = NULL; - va_start(ap, fmt_str); - vasprintf(&fp, fmt_str.c_str(), ap); - va_end(ap); - std::unique_ptr formatted(fp, free); - return std::string(formatted.get()); +std::string _FMT_(const std::string &fmt_str, ...) { + va_list ap; + char *fp = NULL; + va_start(ap, fmt_str); + vasprintf(&fp, fmt_str.c_str(), ap); + va_end(ap); + std::unique_ptr formatted(fp, free); + return std::string(formatted.get()); } -std::string Date(void) -{ - time_t unixTime; - struct tm timeStruct; - time(&unixTime); - localtime_r(&unixTime, &timeStruct); - return _FMT_("%04i-%02i-%02i_%02i-%02i-%02i", timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, timeStruct.tm_mday, - timeStruct.tm_hour, timeStruct.tm_min, timeStruct.tm_sec); +std::string Date(void) { + time_t unixTime; + struct tm timeStruct; + time(&unixTime); + localtime_r(&unixTime, &timeStruct); + return _FMT_("%04i-%02i-%02i_%02i-%02i-%02i", timeStruct.tm_year + 1900, + timeStruct.tm_mon + 1, timeStruct.tm_mday, timeStruct.tm_hour, + timeStruct.tm_min, timeStruct.tm_sec); } -void screenoff() -{ - gspLcdInit();\ - GSPLCD_PowerOffBacklight(GSPLCD_SCREEN_BOTH);\ - gspLcdExit(); +void screenoff() { + gspLcdInit(); + GSPLCD_PowerOffBacklight(GSPLCD_SCREEN_BOTH); + gspLcdExit(); } -void screenon() -{ - gspLcdInit();\ - GSPLCD_PowerOnBacklight(GSPLCD_SCREEN_BOTH);\ - gspLcdExit(); +void screenon() { + gspLcdInit(); + GSPLCD_PowerOnBacklight(GSPLCD_SCREEN_BOTH); + gspLcdExit(); } -float RenderD7::GetDeltaTime() -{ - return delta_time; -} +float RenderD7::GetDeltaTime() { return delta_time; } -bool RenderD7::DrawImageFromSheet(RenderD7::Sheet* sheet, size_t index, float x, float y, float scaleX, float scaleY) -{ - if (sheet->spritesheet != nullptr) - { - if (C2D_SpriteSheetCount(sheet->spritesheet) >= index) - { - return C2D_DrawImageAt(C2D_SpriteSheetGetImage(sheet->spritesheet, index), x, y, 0.5f, nullptr, scaleX, scaleY); - } - } - return false; -} -void RenderD7::Init::NdspFirm(bool useit) -{ - if (useit) - { - if ( access( "sdmc:/3ds/dspfirm.cdc", F_OK ) != -1 ) - { - ndspInit(); - isndspinit = true; - dspststus = "Initialisized success!"; - } - else - { - dspststus = "Not found: dspfirm.cdc"; - renderd7log.Write("RenderD7: SoundEngine Error! ndspfirm not found!"); - RenderD7::AddOvl(std::make_unique()); - } +bool RenderD7::DrawImageFromSheet(RenderD7::Sheet *sheet, size_t index, float x, + float y, float scaleX, float scaleY) { + if (sheet->spritesheet != nullptr) { + if (C2D_SpriteSheetCount(sheet->spritesheet) >= index) { + return C2D_DrawImageAt(C2D_SpriteSheetGetImage(sheet->spritesheet, index), + x, y, 0.5f, nullptr, scaleX, scaleY); } + } + return false; } -void RenderD7::Exit::NdspFirm() -{ - if (isndspinit) - { - ndspExit(); +void RenderD7::Init::NdspFirm(bool useit) { + if (useit) { + if (access("sdmc:/3ds/dspfirm.cdc", F_OK) != -1) { + ndspInit(); + isndspinit = true; + dspststus = "Initialisized success!"; + } else { + dspststus = "Not found: dspfirm.cdc"; + renderd7log.Write("RenderD7: SoundEngine Error! ndspfirm not found!"); + RenderD7::AddOvl(std::make_unique()); } + } } -void RenderD7::Msg::Display(std::string titletxt, std::string subtext, C3D_RenderTarget *target) -{ - shouldbe_disabled = true; - cnttttt = 0; - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - C2D_TargetClear(Top, DSEVENBLACK); - C2D_TargetClear(Bottom, DSEVENBLACK); - RenderD7::ClearTextBufs(); - RenderD7::OnScreen(Top); - RenderD7::Draw::Rect(0, 0, 400, 240, RenderD7::Color::Hex("#111111")); - RenderD7::OnScreen(Bottom); - RenderD7::Draw::Rect(0, 0, 320, 240, RenderD7::Color::Hex("#111111")); - RenderD7::OnScreen(target); - RenderD7::Draw::Rect(0, 0, 400, 26, RenderD7::Color::Hex("#333333", 200)); - RenderD7::Draw::Text(5, 2, 0.7f, DSEVENWHITE, titletxt); - RenderD7::Draw::Text(5, 30, 0.6f, DSEVENWHITE, subtext); - C3D_FrameEnd(0); +void RenderD7::Exit::NdspFirm() { + if (isndspinit) { + ndspExit(); + } } -void RenderD7::Msg::DisplayWithProgress(std::string titletext, std::string subtext, float current, float total, u32 prgbarcolor) -{ - shouldbe_disabled = true; - cnttttt = 0; - RenderD7::ClearTextBufs(); - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - C2D_TargetClear(Top, DSEVENBLACK); - C2D_TargetClear(Bottom, DSEVENBLACK); - char str[256]; - snprintf(str, sizeof(str), "(%.2f%%)", ((float)current/(float)total) * 100.0f); - RenderD7::OnScreen(Top); - RenderD7::Draw::Rect(0, 0, 400, 240, RenderD7::Color::Hex("#111111")); - RenderD7::Draw::Rect(0, 0, 400, 26, RenderD7::Color::Hex("#333333", 200)); - RenderD7::Draw::Text(5, 2, 0.7f, DSEVENWHITE, titletext); - RenderD7::Draw::Text(5, 30, 0.6f, DSEVENWHITE, subtext); - RenderD7::Draw::Rect(30, 120, 342, 30, RenderD7::Color::Hex("#333333")); - RenderD7::Draw::Rect(31, 121, (int)(((float)current / (float)total) * 338.0f), 28, prgbarcolor); - RenderD7::Draw::TextCentered(5, 124, 0.7f, RenderD7::Color::Hex("#111111"), str, 390); - RenderD7::OnScreen(Bottom); - RenderD7::Draw::Rect(0, 0, 320, 240, RenderD7::Color::Hex("#111111")); - C3D_FrameEnd(0); +void RenderD7::Msg::Display(std::string titletxt, std::string subtext, + C3D_RenderTarget *target) { + shouldbe_disabled = true; + cnttttt = 0; + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + C2D_TargetClear(Top, DSEVENBLACK); + C2D_TargetClear(Bottom, DSEVENBLACK); + RenderD7::ClearTextBufs(); + RenderD7::OnScreen(Top); + RenderD7::Draw::Rect(0, 0, 400, 240, RenderD7::Color::Hex("#111111")); + RenderD7::OnScreen(Bottom); + RenderD7::Draw::Rect(0, 0, 320, 240, RenderD7::Color::Hex("#111111")); + RenderD7::OnScreen(target); + RenderD7::Draw::Rect(0, 0, 400, 26, RenderD7::Color::Hex("#333333", 200)); + RenderD7::Draw::Text(5, 2, 0.7f, DSEVENWHITE, titletxt); + RenderD7::Draw::Text(5, 30, 0.6f, DSEVENWHITE, subtext); + C3D_FrameEnd(0); } -void RenderD7::SetupLog() -{ - renderd7log.Init("RenderD7/RenderD7.log"); +void RenderD7::Msg::DisplayWithProgress(std::string titletext, + std::string subtext, float current, + float total, u32 prgbarcolor) { + shouldbe_disabled = true; + cnttttt = 0; + RenderD7::ClearTextBufs(); + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + C2D_TargetClear(Top, DSEVENBLACK); + C2D_TargetClear(Bottom, DSEVENBLACK); + char str[256]; + snprintf(str, sizeof(str), "(%.2f%%)", + ((float)current / (float)total) * 100.0f); + RenderD7::OnScreen(Top); + RenderD7::Draw::Rect(0, 0, 400, 240, RenderD7::Color::Hex("#111111")); + RenderD7::Draw::Rect(0, 0, 400, 26, RenderD7::Color::Hex("#333333", 200)); + RenderD7::Draw::Text(5, 2, 0.7f, DSEVENWHITE, titletext); + RenderD7::Draw::Text(5, 30, 0.6f, DSEVENWHITE, subtext); + RenderD7::Draw::Rect(30, 120, 342, 30, RenderD7::Color::Hex("#333333")); + RenderD7::Draw::Rect(31, 121, (int)(((float)current / (float)total) * 338.0f), + 28, prgbarcolor); + RenderD7::Draw::TextCentered(5, 124, 0.7f, RenderD7::Color::Hex("#111111"), + str, 390); + RenderD7::OnScreen(Bottom); + RenderD7::Draw::Rect(0, 0, 320, 240, RenderD7::Color::Hex("#111111")); + C3D_FrameEnd(0); } +void RenderD7::SetupLog() { renderd7log.Init("RenderD7/RenderD7.log"); } -void RenderD7::Error::DisplayError(std::string toptext, std::string errortext, int timesec) -{ - shouldbe_disabled = true; - cnttttt = 0; - RenderD7::ClearTextBufs(); - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - C2D_TargetClear(Top, DSEVENBLACK); - C2D_TargetClear(Bottom, DSEVENBLACK); - RenderD7::OnScreen(Top); - RenderD7::Draw::Text(0, 0, 0.7f, DSEVENWHITE, toptext); - RenderD7::Draw::Text(0, 30, 0.6f, DSEVENWHITE, errortext); - C3D_FrameEnd(0); - for (int i = 0; i < 60*timesec; i++) { - RenderD7::Draw::Rect(0, 236, (int)(((float)i / (float)60*timesec) * 400.0f), 4, RenderD7::Color::Hex("#00ff00")); - gspWaitForVBlank(); - - - } +void RenderD7::Error::DisplayError(std::string toptext, std::string errortext, + int timesec) { + shouldbe_disabled = true; + cnttttt = 0; + RenderD7::ClearTextBufs(); + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + C2D_TargetClear(Top, DSEVENBLACK); + C2D_TargetClear(Bottom, DSEVENBLACK); + RenderD7::OnScreen(Top); + RenderD7::Draw::Text(0, 0, 0.7f, DSEVENWHITE, toptext); + RenderD7::Draw::Text(0, 30, 0.6f, DSEVENWHITE, errortext); + C3D_FrameEnd(0); + for (int i = 0; i < 60 * timesec; i++) { + RenderD7::Draw::Rect(0, 236, + (int)(((float)i / (float)60 * timesec) * 400.0f), 4, + RenderD7::Color::Hex("#00ff00")); + gspWaitForVBlank(); + } } #include -void RenderD7::Error::DisplayFatalError(std::string toptext, std::string errortext) -{ - shouldbe_disabled = true; - cnttttt = 0; - bool error___ = true; - RenderD7::ClearTextBufs(); - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - C2D_TargetClear(Top, DSEVENBLACK); - C2D_TargetClear(Bottom, DSEVENBLACK); - RenderD7::BitmapPrinter errorss(400, 240); - errorss.DrawRectFilled(0, 0, 400, 240, 0, 0, 0, 255); - errorss.DrawDebugText(4, 4, 2, RenderD7::Color::Hex("#ff0000"), toptext); - errorss.DrawDebugText(4, 26, 1, RenderD7::Color::Hex("#000000"), errortext); - errorss.DrawDebugText(4, 230, 1, RenderD7::Color::Hex("#000000"), "Press Start to Exit!"); - RenderD7::Image img; - img.LoadFromBitmap(errorss.GetBitmap()); - RenderD7::OnScreen(Top); - img.Draw(0, 0); - /*RenderD7::Draw::TextCentered(0, 0, 0.7f, DSEVENWHITE, toptext, 400); - RenderD7::Draw::TextCentered(0, 100, 0.6f, DSEVENWHITE, errortext, 400); - RenderD7::Draw::TextCentered(0, 200, 0.6f, DSEVENWHITE, "Press Start to Exit!", 400);*/ - C3D_FrameEnd(0); - while (error___) - { - if(d7_hDown & KEY_START) - { - RenderD7::ExitApp(); - } +void RenderD7::Error::DisplayFatalError(std::string toptext, + std::string errortext) { + shouldbe_disabled = true; + cnttttt = 0; + bool error___ = true; + RenderD7::ClearTextBufs(); + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + C2D_TargetClear(Top, DSEVENBLACK); + C2D_TargetClear(Bottom, DSEVENBLACK); + RenderD7::BitmapPrinter errorss(400, 240); + errorss.DrawRectFilled(0, 0, 400, 240, 0, 0, 0, 255); + errorss.DrawDebugText(4, 4, 2, RenderD7::Color::Hex("#ff0000"), toptext); + errorss.DrawDebugText(4, 26, 1, RenderD7::Color::Hex("#000000"), errortext); + errorss.DrawDebugText(4, 230, 1, RenderD7::Color::Hex("#000000"), + "Press Start to Exit!"); + RenderD7::Image img; + img.LoadFromBitmap(errorss.GetBitmap()); + RenderD7::OnScreen(Top); + img.Draw(0, 0); + /*RenderD7::Draw::TextCentered(0, 0, 0.7f, DSEVENWHITE, toptext, 400); + RenderD7::Draw::TextCentered(0, 100, 0.6f, DSEVENWHITE, errortext, 400); + RenderD7::Draw::TextCentered(0, 200, 0.6f, DSEVENWHITE, "Press Start to + Exit!", 400);*/ + C3D_FrameEnd(0); + while (error___) { + if (d7_hDown & KEY_START) { + RenderD7::ExitApp(); } + } } void RenderD7::Scene::doDraw() { - if(!RenderD7::Scene::scenes.empty()) - RenderD7::Scene::scenes.top()->Draw(); + if (!RenderD7::Scene::scenes.empty()) + RenderD7::Scene::scenes.top()->Draw(); } -void RenderD7::Scene::doLogic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) { - if(!RenderD7::Scene::scenes.empty()) - RenderD7::Scene::scenes.top()->Logic(hDown, hHeld, hUp, touch); +void RenderD7::Scene::doLogic(u32 hDown, u32 hHeld, u32 hUp, + touchPosition touch) { + if (!RenderD7::Scene::scenes.empty()) + RenderD7::Scene::scenes.top()->Logic(hDown, hHeld, hUp, touch); } -void RenderD7::Scene::Load(std::unique_ptr scene, bool fade) -{ - Scene::scenes.push(std::move(scene)); +void RenderD7::Scene::Load(std::unique_ptr scene, bool fade) { + Scene::scenes.push(std::move(scene)); } void RenderD7::Scene::Back() { - if(RenderD7::Scene::scenes.size() > 0) - RenderD7::Scene::scenes.pop(); + if (RenderD7::Scene::scenes.size() > 0) + RenderD7::Scene::scenes.pop(); } -void frameloop() -{ - frames++; - delta_time = osGetTime() - last_time; - if (delta_time >= 1000) { - current_fps = frames/(delta_time/1000.0f)+1; - frames = 0; - last_time = osGetTime(); - } - d11framerate = current_fps; - //for (int i = 0; i < 320; i++) mt_fpsgraph[i] = current_fps; - +void frameloop() { + frames++; + delta_time = osGetTime() - last_time; + if (delta_time >= 1000) { + current_fps = frames / (delta_time / 1000.0f) + 1; + frames = 0; + last_time = osGetTime(); + } + d11framerate = current_fps; + // for (int i = 0; i < 320; i++) mt_fpsgraph[i] = current_fps; } -float getframerate() -{ - return d11framerate; +float getframerate() { return d11framerate; } + +std::string RenderD7::GetFramerate() { + return (std::to_string((int)d11framerate).substr(0, 2)); } -std::string RenderD7::GetFramerate() -{ - return (std::to_string((int)d11framerate).substr(0, 2)); +bool RenderD7::MainLoop() { + if (!aptMainLoop()) + return false; + hidScanInput(); + d7_hDown = hidKeysDown(); + d7_hUp = hidKeysUp(); + d7_hHeld = hidKeysHeld(); + hidTouchRead(&d7_touch); + + RenderD7::ClearTextBufs(); + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + + C2D_TargetClear(Top, C2D_Color32(0, 0, 0, 0)); + C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0)); + frameloop(); + RenderD7::Scene::doDraw(); + RenderD7::Scene::doLogic(d7_hDown, d7_hHeld, d7_hUp, d7_touch); + cnttttt++; + if (cnttttt > 90) { + shouldbe_disabled = false; + cnttttt = 0; + } + + return running; } -bool RenderD7::MainLoop() -{ - if (!aptMainLoop()) return false; - hidScanInput(); - d7_hDown = hidKeysDown(); - d7_hUp = hidKeysUp(); - d7_hHeld = hidKeysHeld(); - hidTouchRead(&d7_touch); - - RenderD7::ClearTextBufs(); - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - - C2D_TargetClear(Top, C2D_Color32(0, 0, 0, 0)); - C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0)); - frameloop(); - RenderD7::Scene::doDraw(); - RenderD7::Scene::doLogic(d7_hDown, d7_hHeld, d7_hUp, d7_touch); - cnttttt++; - if (cnttttt > 90) - { - shouldbe_disabled = false; - cnttttt = 0; - } - - return running; -} - -void RenderD7::ClearTextBufs(void) -{ - C2D_TextBufClear(TextBuf); -} +void RenderD7::ClearTextBufs(void) { C2D_TextBufClear(TextBuf); } void MetrikThread(RenderD7::Parameter param) { - while (true) { - RenderD7::DrawMetrikOvl(); - RenderD7::Thread::sleep(1000 * 1); // wait; also, this is needed to allow for concurrency (refer to the documentation for m3d::Thread::sleep()) - } + while (true) { + RenderD7::DrawMetrikOvl(); + RenderD7::Thread::sleep( + 1000 * 1); // wait; also, this is needed to allow for concurrency (refer + // to the documentation for m3d::Thread::sleep()) + } } -void RenderD7::Init::Graphics() -{ - C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); - C2D_Init(size_t(maxobj__)); - C2D_Prepare(); - Top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); - TopRight = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); - Bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); - TextBuf = C2D_TextBufNew(4096); - Font = C2D_FontLoadSystem(CFG_REGION_USA); +void RenderD7::Init::Graphics() { + C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); + C2D_Init(size_t(maxobj__)); + C2D_Prepare(); + Top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); + TopRight = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); + Bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); + TextBuf = C2D_TextBufNew(4096); + Font = C2D_FontLoadSystem(CFG_REGION_USA); } -void RenderD7::Exit::Graphics() -{ - C2D_TextBufDelete(TextBuf); - C2D_Fini(); - C3D_Fini(); +void RenderD7::Exit::Graphics() { + C2D_TextBufDelete(TextBuf); + C2D_Fini(); + C3D_Fini(); } -Result RenderD7::Init::Main(std::string app_name) -{ - gfxInitDefault(); - //consoleInit(GFX_TOP, NULL); - Result res = cfguInit(); - if (R_SUCCEEDED(res)) { - CFGU_SecureInfoGetRegion(&sysRegion); - CFGU_GetSystemModel(&consoleModel); - cfguExit(); - } - printf("cfgu\n"); - if (rd7_superreselution) - { - gfxSetWide(consoleModel != 3); - } - printf("rd7sr\n"); - aptInit(); - romfsInit(); - cfguInit(); - printf("stuff\n"); - if (cobj___){maxobj__ = cobj___;} - if (!cobj___){maxobj__ = C2D_DEFAULT_MAX_OBJECTS;} - D_app_name = app_name; - cfgpath = "sdmc:/RenderD7/Apps/"; - cfgpath += D_app_name; - csvpc = "sdmc:/RenderD7/Apps/"; - csvpc += D_app_name; - csvpc += "/mt"; - mkdir("sdmc:/RenderD7/", 0777); - mkdir("sdmc:/RenderD7/Apps", 0777); - mkdir(cfgpath.c_str(), 0777); - mkdir(csvpc.c_str(), 0777); - bool renew = false; - printf("folderset\n"); - if (FS::FileExist(cfgpath + "/config.ini")) - { - cfgfile = std::make_unique(cfgpath + "/config.ini"); - cfgfile->read(cfgstruct); - std::string version = cfgstruct["info"]["version"]; - if (version != CFGVER) renew = true; - } - printf("vercheck\n"); - renderd7log.Write("Point At: " + std::to_string(__LINE__) + " : " + GetFileName(__FILE__)); - if (!FS::FileExist(cfgpath + "/config.ini") || renew) - { - cfgfile = std::make_unique(cfgpath+ "/config.ini"); - renderd7log.Write("Point At: " + std::to_string(__LINE__) + " : " + GetFileName(__FILE__)); - cfgfile->read(cfgstruct); - renderd7log.Write("Point At: " + std::to_string(__LINE__) + " : " + GetFileName(__FILE__)); - cfgstruct["info"]["version"] = CFGVER; - cfgstruct["info"]["renderd7ver"] = RENDERD7VSTRING; - cfgstruct["settings"]["doscreentimeout"] = "0"; - cfgstruct["settings"]["forcetimeoutLB"] = "1"; - cfgstruct["settings"]["forceFrameRate"] = "60"; - cfgstruct["settings"]["super-reselution"] = "0"; - cfgstruct["settings"]["renderer"] = "c3d_c2d"; - renderd7log.Write("Point At: " + std::to_string(__LINE__) + " : " + GetFileName(__FILE__)); - cfgstruct["metrik-settings"]["enableoverlay"] = "0"; - cfgstruct["metrik-settings"]["Screen"] = "0"; - cfgstruct["metrik-settings"]["txtColor"] = "#ffffff"; - cfgstruct["metrik-settings"]["txtColorA"] = "255"; - cfgstruct["metrik-settings"]["ColorA"] = "255"; - cfgstruct["metrik-settings"]["Color"] = "#000000"; - cfgstruct["metrik-settings"]["txtSize"] = "0.7f"; - cfgstruct["metrik-settings"]["dumpcsv"] = "0"; - cfgstruct["metrik-settings"]["dumpcsvloop"] = "0"; - cfgfile->write(cfgstruct); - } - if (renew) - printf("renew\n"); - renderd7log.Write("Point At: " + std::to_string(__LINE__) + " : " + GetFileName(__FILE__)); - cfgfile = std::make_unique(cfgpath+ "/config.ini"); - cfgfile->read(cfgstruct); - std::string Fps = cfgstruct["settings"]["forceFrameRate"]; - C3D_FrameRate(RenderD7::Convert::StringtoFloat(Fps)); - metrikd = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["enableoverlay"])); - mt_txtcolor = RenderD7::Color::Hex(cfgstruct["metrik-settings"]["txtColor"], (u8)RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["txtColorA"])); - mt_color = RenderD7::Color::Hex(cfgstruct["metrik-settings"]["Color"], (u8)RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["ColorA"])); - mt_txtSize = RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["txtSize"]); - mt_screen = RenderD7::Convert::StringtoInt(cfgstruct["metrik-settings"]["Screen"]); - rd7_superreselution = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat(cfgstruct["settings"]["super-reselution"])); - mt_dumpcsv = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["dumpcsv"])); - mt_csvloop = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["dumpcsvloop"])); - printf("read\n"); - //Check if citra - s64 citracheck = 0; - svcGetSystemInfo(&citracheck, 0x20000, 0); - is_citra = citracheck ? true : false; - printf("citra\n"); - //Speedup - osSetSpeedupEnable(true); - printf("boost\n"); - if (!is_citra && rd7_superreselution) - { - if (consoleModel != 3) gfxSetWide(true); - } - printf("rd7sr\n"); - //consoleInit(GFX_BOTTOM, NULL); - if (mt_dumpcsv) - { - mt_cname = csvpc; - mt_cname += "/"; - mt_cname += Date(); - mt_cname += ".csv"; - - FILE* logfile = fopen((mt_cname.c_str()), "w"); - fclose(logfile); - - mt_csv.open((mt_cname), std::ofstream::app); - mt_csv << "FPS,CPU,GPU,CMD\n"; - mt_csv.close(); - } - printf("csv\n"); - C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); - C2D_Init(C2D_DEFAULT_MAX_OBJECTS); - C2D_Prepare(); - Top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); - TopRight = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); - Bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); - TextBuf = C2D_TextBufNew(4096); - Font = C2D_FontLoadSystem(CFG_REGION_USA); - printf("Graphical Interface\n"); - //RenderD7::Msg::Display("RenderD7", "RenderD7 init success!\nWaiting for MainLoop!", Top); - return 0; -} - -Result RenderD7::Init::Reload() -{ - C2D_TextBufDelete(TextBuf); - C2D_Fini(); - C3D_Fini(); - C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); - C2D_Init(size_t(maxobj__)); - C2D_Prepare(); - Top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); - TopRight = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); - Bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); - TextBuf = C2D_TextBufNew(4096); - Font = C2D_FontLoadSystem(CFG_REGION_USA); - - return 0; -} - -void RenderD7::ToggleRD7SR() -{ - shouldbe_disabled = true; - cnttttt = 0; - // Display black screen - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - C2D_TargetClear(Top, RenderD7::Color::Hex("#000000")); - RenderD7::OnScreen(Top); - C3D_FrameEnd(0); - // Toggle 400px/800px mode - gfxSetWide(gfxIsWide() ? false : true); - rd7_superreselution = gfxIsWide(); - RenderD7::Init::Reload(); -} - -bool RenderD7::IsRD7SR() -{ - return gfxIsWide(); -} - -void RenderD7::Exit::Main() -{ - cfgfile->write(cfgstruct); - if (RenderD7::Threads::threadrunning) RenderD7::Threads::Exit(); - C2D_TextBufDelete(TextBuf); - C2D_Fini(); - C3D_Fini(); - aptExit(); - gfxExit(); - romfsExit(); +Result RenderD7::Init::Main(std::string app_name) { + gfxInitDefault(); + // consoleInit(GFX_TOP, NULL); + Result res = cfguInit(); + if (R_SUCCEEDED(res)) { + CFGU_SecureInfoGetRegion(&sysRegion); + CFGU_GetSystemModel(&consoleModel); cfguExit(); - romfsExit(); + } + printf("cfgu\n"); + if (rd7_superreselution) { + gfxSetWide(consoleModel != 3); + } + printf("rd7sr\n"); + aptInit(); + romfsInit(); + cfguInit(); + printf("stuff\n"); + if (cobj___) { + maxobj__ = cobj___; + } + if (!cobj___) { + maxobj__ = C2D_DEFAULT_MAX_OBJECTS; + } + D_app_name = app_name; + cfgpath = "sdmc:/RenderD7/Apps/"; + cfgpath += D_app_name; + csvpc = "sdmc:/RenderD7/Apps/"; + csvpc += D_app_name; + csvpc += "/mt"; + mkdir("sdmc:/RenderD7/", 0777); + mkdir("sdmc:/RenderD7/Apps", 0777); + mkdir(cfgpath.c_str(), 0777); + mkdir(csvpc.c_str(), 0777); + bool renew = false; + printf("folderset\n"); + if (FS::FileExist(cfgpath + "/config.ini")) { + cfgfile = std::make_unique(cfgpath + "/config.ini"); + cfgfile->read(cfgstruct); + std::string version = cfgstruct["info"]["version"]; + if (version != CFGVER) + renew = true; + } + printf("vercheck\n"); + renderd7log.Write("Point At: " + std::to_string(__LINE__) + " : " + + GetFileName(__FILE__)); + if (!FS::FileExist(cfgpath + "/config.ini") || renew) { + cfgfile = std::make_unique(cfgpath + "/config.ini"); + renderd7log.Write("Point At: " + std::to_string(__LINE__) + " : " + + GetFileName(__FILE__)); + cfgfile->read(cfgstruct); + renderd7log.Write("Point At: " + std::to_string(__LINE__) + " : " + + GetFileName(__FILE__)); + cfgstruct["info"]["version"] = CFGVER; + cfgstruct["info"]["renderd7ver"] = RENDERD7VSTRING; + cfgstruct["settings"]["doscreentimeout"] = "0"; + cfgstruct["settings"]["forcetimeoutLB"] = "1"; + cfgstruct["settings"]["forceFrameRate"] = "60"; + cfgstruct["settings"]["super-reselution"] = "0"; + cfgstruct["settings"]["renderer"] = "c3d_c2d"; + renderd7log.Write("Point At: " + std::to_string(__LINE__) + " : " + + GetFileName(__FILE__)); + cfgstruct["metrik-settings"]["enableoverlay"] = "0"; + cfgstruct["metrik-settings"]["Screen"] = "0"; + cfgstruct["metrik-settings"]["txtColor"] = "#ffffff"; + cfgstruct["metrik-settings"]["txtColorA"] = "255"; + cfgstruct["metrik-settings"]["ColorA"] = "255"; + cfgstruct["metrik-settings"]["Color"] = "#000000"; + cfgstruct["metrik-settings"]["txtSize"] = "0.7f"; + cfgstruct["metrik-settings"]["dumpcsv"] = "0"; + cfgstruct["metrik-settings"]["dumpcsvloop"] = "0"; + cfgfile->write(cfgstruct); + } + if (renew) + printf("renew\n"); + renderd7log.Write("Point At: " + std::to_string(__LINE__) + " : " + + GetFileName(__FILE__)); + cfgfile = std::make_unique(cfgpath + "/config.ini"); + cfgfile->read(cfgstruct); + std::string Fps = cfgstruct["settings"]["forceFrameRate"]; + C3D_FrameRate(RenderD7::Convert::StringtoFloat(Fps)); + metrikd = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat( + cfgstruct["metrik-settings"]["enableoverlay"])); + mt_txtcolor = + RenderD7::Color::Hex(cfgstruct["metrik-settings"]["txtColor"], + (u8)RenderD7::Convert::StringtoFloat( + cfgstruct["metrik-settings"]["txtColorA"])); + mt_color = RenderD7::Color::Hex(cfgstruct["metrik-settings"]["Color"], + (u8)RenderD7::Convert::StringtoFloat( + cfgstruct["metrik-settings"]["ColorA"])); + mt_txtSize = + RenderD7::Convert::StringtoFloat(cfgstruct["metrik-settings"]["txtSize"]); + mt_screen = + RenderD7::Convert::StringtoInt(cfgstruct["metrik-settings"]["Screen"]); + rd7_superreselution = + RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat( + cfgstruct["settings"]["super-reselution"])); + mt_dumpcsv = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat( + cfgstruct["metrik-settings"]["dumpcsv"])); + mt_csvloop = RenderD7::Convert::FloatToBool(RenderD7::Convert::StringtoFloat( + cfgstruct["metrik-settings"]["dumpcsvloop"])); + printf("read\n"); + // Check if citra + s64 citracheck = 0; + svcGetSystemInfo(&citracheck, 0x20000, 0); + is_citra = citracheck ? true : false; + printf("citra\n"); + // Speedup + osSetSpeedupEnable(true); + printf("boost\n"); + if (!is_citra && rd7_superreselution) { + if (consoleModel != 3) + gfxSetWide(true); + } + printf("rd7sr\n"); + // consoleInit(GFX_BOTTOM, NULL); + if (mt_dumpcsv) { + mt_cname = csvpc; + mt_cname += "/"; + mt_cname += Date(); + mt_cname += ".csv"; + + FILE *logfile = fopen((mt_cname.c_str()), "w"); + fclose(logfile); + + mt_csv.open((mt_cname), std::ofstream::app); + mt_csv << "FPS,CPU,GPU,CMD\n"; + mt_csv.close(); + } + printf("csv\n"); + C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); + C2D_Init(C2D_DEFAULT_MAX_OBJECTS); + C2D_Prepare(); + Top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); + TopRight = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); + Bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); + TextBuf = C2D_TextBufNew(4096); + Font = C2D_FontLoadSystem(CFG_REGION_USA); + printf("Graphical Interface\n"); + // RenderD7::Msg::Display("RenderD7", "RenderD7 init success!\nWaiting for + // MainLoop!", Top); + return 0; } -void RenderD7::DrawTObjects(std::vector tobjects, u32 color, u32 txtcolor, int selection, u32 selbgcolor, u32 selcolor) -{ - for(int i = 0; i < (int)tobjects.size(); i++) - { - if (selection == i) - { - RenderD7::Draw::Rect(tobjects[i].x - 2, tobjects[i].y - 2, tobjects[i].w + 4, tobjects[i].h + 4, selbgcolor); - RenderD7::Draw::Rect(tobjects[i].x, tobjects[i].y, tobjects[i].w, tobjects[i].h, color); - RenderD7::Draw::Rect(tobjects[i].x, tobjects[i].y, tobjects[i].w, tobjects[i].h, selcolor); - RenderD7::Draw::Text(tobjects[i].x + (tobjects[i].w/2) - RenderD7::Draw::GetTextHeight(tobjects[i].txtsize , tobjects[i].text) + tobjects[i].correctx, tobjects[i].y + (tobjects[i].h/2) - RenderD7::Draw::GetTextHeight(tobjects[i].txtsize, tobjects[i].text) + tobjects[i].correcty, tobjects[i].txtsize, txtcolor, tobjects[i].text); - } - else - { - RenderD7::Draw::Rect(tobjects[i].x, tobjects[i].y - 1, tobjects[i].w, tobjects[i].h, color); - RenderD7::Draw::Text(tobjects[i].x + (tobjects[i].w/2) - RenderD7::Draw::GetTextHeight(tobjects[i].txtsize , tobjects[i].text) + tobjects[i].correctx, tobjects[i].y + (tobjects[i].h/2) - RenderD7::Draw::GetTextHeight(tobjects[i].txtsize, tobjects[i].text) + tobjects[i].correcty, tobjects[i].txtsize, txtcolor, tobjects[i].text); - } - } +Result RenderD7::Init::Reload() { + C2D_TextBufDelete(TextBuf); + C2D_Fini(); + C3D_Fini(); + C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); + C2D_Init(size_t(maxobj__)); + C2D_Prepare(); + Top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); + TopRight = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); + Bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); + TextBuf = C2D_TextBufNew(4096); + Font = C2D_FontLoadSystem(CFG_REGION_USA); + + return 0; } -void RenderD7::DrawTLBtns(std::vector btns, u32 color, int selection, u32 selbgcolor, u32 selcolor) -{ - for(int i = 0; i < (int)btns.size(); i++) - { - if (selection == i) - { - RenderD7::Draw::Rect(btns[i].x - 2, btns[i].y - 2, btns[i].w + 4, btns[i].h + 4, selbgcolor); - RenderD7::Draw::Rect(btns[i].x, btns[i].y, btns[i].w, btns[i].h, color); - RenderD7::Draw::Rect(btns[i].x, btns[i].y, btns[i].w, btns[i].h, selcolor); - } - else - { - RenderD7::Draw::Rect(btns[i].x, btns[i].y - 1, btns[i].w, btns[i].h, color); - } - } +void RenderD7::ToggleRD7SR() { + shouldbe_disabled = true; + cnttttt = 0; + // Display black screen + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + C2D_TargetClear(Top, RenderD7::Color::Hex("#000000")); + RenderD7::OnScreen(Top); + C3D_FrameEnd(0); + // Toggle 400px/800px mode + gfxSetWide(gfxIsWide() ? false : true); + rd7_superreselution = gfxIsWide(); + RenderD7::Init::Reload(); } -void RenderD7::ExitApp() -{ - if (!rd7settings) running = false; +bool RenderD7::IsRD7SR() { return gfxIsWide(); } + +void RenderD7::Exit::Main() { + cfgfile->write(cfgstruct); + if (RenderD7::Threads::threadrunning) + RenderD7::Threads::Exit(); + C2D_TextBufDelete(TextBuf); + C2D_Fini(); + C3D_Fini(); + aptExit(); + gfxExit(); + romfsExit(); + cfguExit(); + romfsExit(); } -bool RenderD7::touchTObj(touchPosition touch, RenderD7::TObject button) -{ - if (touch.px >= button.x && touch.px <= (button.x + button.w) && touch.py >= button.y && touch.py <= (button.y + button.h)) return true; - else return false; -} - -bool RenderD7::touchTLBtn(touchPosition touch, RenderD7::TLBtn button) -{ - if (touch.px >= button.x && touch.px <= (button.x + button.w) && touch.py >= button.y && touch.py <= (button.y + button.h)) return true; - else return false; -} - -int RenderD7::GetRandomInt(int b, int e) -{ - std::default_random_engine generator; - std::uniform_int_distribution distribution(b, e); - int r = distribution(generator); - return r; -} - -void RenderD7::DrawSTObject(std::vector tobject, int tobjectindex, u32 color, u32 txtcolor) -{ - RenderD7::Draw::Rect(tobject[tobjectindex].x, tobject[tobjectindex].y, tobject[tobjectindex].w, tobject[tobjectindex].h, color); - RenderD7::Draw::Text(tobject[tobjectindex].x + (tobject[tobjectindex].w/2) - RenderD7::Draw::GetTextHeight(tobject[tobjectindex].txtsize , tobject[tobjectindex].text) + tobject[tobjectindex].correctx, tobject[tobjectindex].y + (tobject[tobjectindex].h/2) - RenderD7::Draw::GetTextHeight(tobject[tobjectindex].txtsize, tobject[tobjectindex].text) + tobject[tobjectindex].correcty, tobject[tobjectindex].txtsize, txtcolor, tobject[tobjectindex].text); -} - -bool dirEntryPredicate(const RenderD7::DirContent &lhs, const RenderD7::DirContent &rhs) { - if (!lhs.isDir && rhs.isDir) return false; - if (lhs.isDir && !rhs.isDir) return true; - - return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0; -} - -void RenderD7::GetDirContentsExt(std::vector &dircontent, const std::vector &extensions) { - struct stat st; - - dircontent.clear(); - - DIR *pdir = opendir("."); - - if (pdir != nullptr) { - while(true) { - RenderD7::DirContent dirEntry; - - struct dirent *pent = readdir(pdir); - if (pent == NULL) break; - - stat(pent->d_name, &st); - dirEntry.name = pent->d_name; - dirEntry.isDir = (st.st_mode & S_IFDIR) ? true : false; - - if (dirEntry.name.compare(".") != 0 && (dirEntry.isDir || RenderD7::NameIsEndingWith(dirEntry.name, extensions))) { - dircontent.push_back(dirEntry); - } - } - - closedir(pdir); - } - sort(dircontent.begin(), dircontent.end(), dirEntryPredicate); -} - -void RenderD7::GetDirContents(std::vector &dircontent) { - RenderD7::GetDirContentsExt(dircontent, {}); -} - -bool RenderD7::FS::FileExist(const std::string& path) -{ - FILE *test = fopen(path.c_str(), "r"); - if(test != NULL) - { - fclose(test); - - return true; +void RenderD7::DrawTObjects(std::vector tobjects, u32 color, + u32 txtcolor, int selection, u32 selbgcolor, + u32 selcolor) { + for (int i = 0; i < (int)tobjects.size(); i++) { + if (selection == i) { + RenderD7::Draw::Rect(tobjects[i].x - 2, tobjects[i].y - 2, + tobjects[i].w + 4, tobjects[i].h + 4, selbgcolor); + RenderD7::Draw::Rect(tobjects[i].x, tobjects[i].y, tobjects[i].w, + tobjects[i].h, color); + RenderD7::Draw::Rect(tobjects[i].x, tobjects[i].y, tobjects[i].w, + tobjects[i].h, selcolor); + RenderD7::Draw::Text(tobjects[i].x + (tobjects[i].w / 2) - + RenderD7::Draw::GetTextHeight( + tobjects[i].txtsize, tobjects[i].text) + + tobjects[i].correctx, + tobjects[i].y + (tobjects[i].h / 2) - + RenderD7::Draw::GetTextHeight( + tobjects[i].txtsize, tobjects[i].text) + + tobjects[i].correcty, + tobjects[i].txtsize, txtcolor, tobjects[i].text); + } else { + RenderD7::Draw::Rect(tobjects[i].x, tobjects[i].y - 1, tobjects[i].w, + tobjects[i].h, color); + RenderD7::Draw::Text(tobjects[i].x + (tobjects[i].w / 2) - + RenderD7::Draw::GetTextHeight( + tobjects[i].txtsize, tobjects[i].text) + + tobjects[i].correctx, + tobjects[i].y + (tobjects[i].h / 2) - + RenderD7::Draw::GetTextHeight( + tobjects[i].txtsize, tobjects[i].text) + + tobjects[i].correcty, + tobjects[i].txtsize, txtcolor, tobjects[i].text); } + } +} +void RenderD7::DrawTLBtns(std::vector btns, u32 color, + int selection, u32 selbgcolor, u32 selcolor) { + for (int i = 0; i < (int)btns.size(); i++) { + if (selection == i) { + RenderD7::Draw::Rect(btns[i].x - 2, btns[i].y - 2, btns[i].w + 4, + btns[i].h + 4, selbgcolor); + RenderD7::Draw::Rect(btns[i].x, btns[i].y, btns[i].w, btns[i].h, color); + RenderD7::Draw::Rect(btns[i].x, btns[i].y, btns[i].w, btns[i].h, + selcolor); + } else { + RenderD7::Draw::Rect(btns[i].x, btns[i].y - 1, btns[i].w, btns[i].h, + color); + } + } +} + +void RenderD7::ExitApp() { + if (!rd7settings) + running = false; +} + +bool RenderD7::touchTObj(touchPosition touch, RenderD7::TObject button) { + if (touch.px >= button.x && touch.px <= (button.x + button.w) && + touch.py >= button.y && touch.py <= (button.y + button.h)) + return true; + else return false; } -bool RenderD7::IsNdspInit() -{ - if (isndspinit) - { - return true; - } - else - { - return false; - } +bool RenderD7::touchTLBtn(touchPosition touch, RenderD7::TLBtn button) { + if (touch.px >= button.x && touch.px <= (button.x + button.w) && + touch.py >= button.y && touch.py <= (button.y + button.h)) + return true; + else + return false; } -void RenderD7::DrawList1(RenderD7::ScrollList1 &l, float txtsize, C3D_RenderTarget *t) -{ - RenderD7::OnScreen(t); - RenderD7::Draw::Rect(0, 0, 400, 240, RenderD7::Color::Hex("#dddddd")); - RenderD7::Draw::Text(0, 0, 0.8f, RenderD7::Color::Hex("#ffffff"), l.Text); +int RenderD7::GetRandomInt(int b, int e) { + std::default_random_engine generator; + std::uniform_int_distribution distribution(b, e); + int r = distribution(generator); + return r; } +void RenderD7::DrawSTObject(std::vector tobject, + int tobjectindex, u32 color, u32 txtcolor) { + RenderD7::Draw::Rect(tobject[tobjectindex].x, tobject[tobjectindex].y, + tobject[tobjectindex].w, tobject[tobjectindex].h, color); + RenderD7::Draw::Text( + tobject[tobjectindex].x + (tobject[tobjectindex].w / 2) - + RenderD7::Draw::GetTextHeight(tobject[tobjectindex].txtsize, + tobject[tobjectindex].text) + + tobject[tobjectindex].correctx, + tobject[tobjectindex].y + (tobject[tobjectindex].h / 2) - + RenderD7::Draw::GetTextHeight(tobject[tobjectindex].txtsize, + tobject[tobjectindex].text) + + tobject[tobjectindex].correcty, + tobject[tobjectindex].txtsize, txtcolor, tobject[tobjectindex].text); +} -void RenderD7::DrawMetrikOvl() -{ - switch (mt_screen) - { - case 0: - RenderD7::OnScreen(Top); - break; - case 1: - RenderD7::OnScreen(Bottom); - break; - default: - RenderD7::OnScreen(Bottom); - break; +bool dirEntryPredicate(const RenderD7::DirContent &lhs, + const RenderD7::DirContent &rhs) { + if (!lhs.isDir && rhs.isDir) + return false; + if (lhs.isDir && !rhs.isDir) + return true; + + return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0; +} + +void RenderD7::GetDirContentsExt(std::vector &dircontent, + const std::vector &extensions) { + struct stat st; + + dircontent.clear(); + + DIR *pdir = opendir("."); + + if (pdir != nullptr) { + while (true) { + RenderD7::DirContent dirEntry; + + struct dirent *pent = readdir(pdir); + if (pent == NULL) + break; + + stat(pent->d_name, &st); + dirEntry.name = pent->d_name; + dirEntry.isDir = (st.st_mode & S_IFDIR) ? true : false; + + if (dirEntry.name.compare(".") != 0 && + (dirEntry.isDir || + RenderD7::NameIsEndingWith(dirEntry.name, extensions))) { + dircontent.push_back(dirEntry); + } } - std::string __C = RENDERD7VSTRING; - std::string info = "RenderD7 " + __C + " Debug Overlay"; - float infoy = 240 - RenderD7::Draw::GetTextHeight(mt_txtSize, info); - mt_fps = "FPS: " + RenderD7::GetFramerate(); - mt_cpu = "CPU: " + std::to_string(C3D_GetProcessingTime()*(d11framerate/10)).substr(0, 4) + "%/" + std::to_string(C3D_GetProcessingTime()).substr(0, 4) + "ms"; - mt_gpu = "GPU: " + std::to_string(C3D_GetDrawingTime()*(d11framerate/10)).substr(0, 4) + "%/" + std::to_string(C3D_GetDrawingTime()).substr(0, 4) + "ms"; - mt_cmd = "CMD: " + std::to_string(C3D_GetCmdBufUsage()*100.0f).substr(0, 4) + "%/" + std::to_string(C3D_GetCmdBufUsage()).substr(0, 4) + "ms"; - RenderD7::Draw::Rect(0, 0, RenderD7::Draw::GetTextWidth(mt_txtSize, mt_fps), RenderD7::Draw::GetTextHeight(mt_txtSize, mt_fps), mt_color); - RenderD7::Draw::Rect(0, 50, RenderD7::Draw::GetTextWidth(mt_txtSize, mt_cpu), RenderD7::Draw::GetTextHeight(mt_txtSize, mt_cpu), mt_color); - RenderD7::Draw::Rect(0, 70, RenderD7::Draw::GetTextWidth(mt_txtSize, mt_gpu), RenderD7::Draw::GetTextHeight(mt_txtSize, mt_gpu), mt_color); - RenderD7::Draw::Rect(0, 90, RenderD7::Draw::GetTextWidth(mt_txtSize, mt_cmd), RenderD7::Draw::GetTextHeight(mt_txtSize, mt_cmd), mt_color); - RenderD7::Draw::Rect(0, infoy, RenderD7::Draw::GetTextWidth(mt_txtSize, info), RenderD7::Draw::GetTextHeight(mt_txtSize, info), mt_color); - RenderD7::Draw::Text(0, 0, mt_txtSize, mt_txtcolor, mt_fps); - RenderD7::Draw::Text(0, 50, mt_txtSize, mt_txtcolor, mt_cpu); - RenderD7::Draw::Text(0, 70, mt_txtSize, mt_txtcolor, mt_gpu); - RenderD7::Draw::Text(0, 90, mt_txtSize, mt_txtcolor, mt_cmd); - RenderD7::Draw::Text(0, infoy, mt_txtSize, mt_txtcolor, info); - - /*for (int z = 0; z < (int)mt_fpsgraph.size(); z++) - { - //mt_fpsgraph[z] = (int)d11framerate; - C2D_DrawLine(z, 239 - mt_fpsgraph[z], mt_txtcolor, z + 1, 239 - mt_fpsgraph[z + 1], mt_txtcolor, 1, 1); - }*/ + + closedir(pdir); + } + sort(dircontent.begin(), dircontent.end(), dirEntryPredicate); } -RenderD7::DSP_NF::DSP_NF() -{ - +void RenderD7::GetDirContents(std::vector &dircontent) { + RenderD7::GetDirContentsExt(dircontent, {}); } -void RenderD7::DSP_NF::Draw(void) const -{ - RenderD7::OnScreen(Top); - RenderD7::Draw::Rect(0, msgposy, 400, 70, RenderD7::Color::Hex("#111111")); - RenderD7::Draw::Rect(0, msgposy, 400, 25, RenderD7::Color::Hex("#222222")); - RenderD7::Draw::Text(2, msgposy+3, 0.7f, RenderD7::Color::Hex("#ffffff"), "Warning! Code: 00027"); - RenderD7::Draw::Text(2, msgposy+30, 0.6f, RenderD7::Color::Hex("#ffffff"), "You can't use Sound effects because the file\n<> was not found!"); +bool RenderD7::FS::FileExist(const std::string &path) { + FILE *test = fopen(path.c_str(), "r"); + if (test != NULL) { + fclose(test); + + return true; + } + + return false; } -void RenderD7::DSP_NF::Logic() -{ - this->delay++/*=(int)RenderD7::GetDeltaTime()*/; - if (msgposy > 170 && delay < 5*60) msgposy--/*=(int)RenderD7::GetDeltaTime()*/; - - if (delay >= 5*60) - { - msgposy++/*=(int)RenderD7::GetDeltaTime*/; - if(msgposy > 400) this->Kill(); - } +bool RenderD7::IsNdspInit() { + if (isndspinit) { + return true; + } else { + return false; + } } -void OvlHandler() -{ - if (!overlays.empty()) - { - overlays.top()->Draw(); - } - if (!overlays.empty()) - { - overlays.top()->Logic(); - } - if (!overlays.empty()) - { - if (overlays.top()->IsKilled()) overlays.pop(); - } - +void RenderD7::DrawList1(RenderD7::ScrollList1 &l, float txtsize, + C3D_RenderTarget *t) { + RenderD7::OnScreen(t); + RenderD7::Draw::Rect(0, 0, 400, 240, RenderD7::Color::Hex("#dddddd")); + RenderD7::Draw::Text(0, 0, 0.8f, RenderD7::Color::Hex("#ffffff"), l.Text); +} + +void RenderD7::DrawMetrikOvl() { + switch (mt_screen) { + case 0: + RenderD7::OnScreen(Top); + break; + case 1: + RenderD7::OnScreen(Bottom); + break; + default: + RenderD7::OnScreen(Bottom); + break; + } + std::string __C = RENDERD7VSTRING; + std::string info = "RenderD7 " + __C + " Debug Overlay"; + float infoy = 240 - RenderD7::Draw::GetTextHeight(mt_txtSize, info); + mt_fps = "FPS: " + RenderD7::GetFramerate(); + mt_cpu = "CPU: " + + std::to_string(C3D_GetProcessingTime() * (d11framerate / 10)) + .substr(0, 4) + + "%/" + std::to_string(C3D_GetProcessingTime()).substr(0, 4) + "ms"; + mt_gpu = + "GPU: " + + std::to_string(C3D_GetDrawingTime() * (d11framerate / 10)).substr(0, 4) + + "%/" + std::to_string(C3D_GetDrawingTime()).substr(0, 4) + "ms"; + mt_cmd = + "CMD: " + std::to_string(C3D_GetCmdBufUsage() * 100.0f).substr(0, 4) + + "%/" + std::to_string(C3D_GetCmdBufUsage()).substr(0, 4) + "ms"; + RenderD7::Draw::Rect(0, 0, RenderD7::Draw::GetTextWidth(mt_txtSize, mt_fps), + RenderD7::Draw::GetTextHeight(mt_txtSize, mt_fps), + mt_color); + RenderD7::Draw::Rect(0, 50, RenderD7::Draw::GetTextWidth(mt_txtSize, mt_cpu), + RenderD7::Draw::GetTextHeight(mt_txtSize, mt_cpu), + mt_color); + RenderD7::Draw::Rect(0, 70, RenderD7::Draw::GetTextWidth(mt_txtSize, mt_gpu), + RenderD7::Draw::GetTextHeight(mt_txtSize, mt_gpu), + mt_color); + RenderD7::Draw::Rect(0, 90, RenderD7::Draw::GetTextWidth(mt_txtSize, mt_cmd), + RenderD7::Draw::GetTextHeight(mt_txtSize, mt_cmd), + mt_color); + RenderD7::Draw::Rect(0, infoy, RenderD7::Draw::GetTextWidth(mt_txtSize, info), + RenderD7::Draw::GetTextHeight(mt_txtSize, info), + mt_color); + RenderD7::Draw::Text(0, 0, mt_txtSize, mt_txtcolor, mt_fps); + RenderD7::Draw::Text(0, 50, mt_txtSize, mt_txtcolor, mt_cpu); + RenderD7::Draw::Text(0, 70, mt_txtSize, mt_txtcolor, mt_gpu); + RenderD7::Draw::Text(0, 90, mt_txtSize, mt_txtcolor, mt_cmd); + RenderD7::Draw::Text(0, infoy, mt_txtSize, mt_txtcolor, info); + + /*for (int z = 0; z < (int)mt_fpsgraph.size(); z++) + { + //mt_fpsgraph[z] = (int)d11framerate; + C2D_DrawLine(z, 239 - mt_fpsgraph[z], mt_txtcolor, z + 1, 239 - + mt_fpsgraph[z + 1], mt_txtcolor, 1, 1); + }*/ +} + +RenderD7::DSP_NF::DSP_NF() {} + +void RenderD7::DSP_NF::Draw(void) const { + RenderD7::OnScreen(Top); + RenderD7::Draw::Rect(0, msgposy, 400, 70, RenderD7::Color::Hex("#111111")); + RenderD7::Draw::Rect(0, msgposy, 400, 25, RenderD7::Color::Hex("#222222")); + RenderD7::Draw::Text(2, msgposy + 3, 0.7f, RenderD7::Color::Hex("#ffffff"), + "Warning! Code: 00027"); + RenderD7::Draw::Text(2, msgposy + 30, 0.6f, RenderD7::Color::Hex("#ffffff"), + "You can't use Sound effects because the " + "file\n<> was not found!"); +} + +void RenderD7::DSP_NF::Logic() { + this->delay++ /*=(int)RenderD7::GetDeltaTime()*/; + if (msgposy > 170 && delay < 5 * 60) + msgposy-- /*=(int)RenderD7::GetDeltaTime()*/; + + if (delay >= 5 * 60) { + msgposy++ /*=(int)RenderD7::GetDeltaTime*/; + if (msgposy > 400) + this->Kill(); + } +} + +void OvlHandler() { + if (!overlays.empty()) { + overlays.top()->Draw(); + } + if (!overlays.empty()) { + overlays.top()->Logic(); + } + if (!overlays.empty()) { + if (overlays.top()->IsKilled()) + overlays.pop(); + } } int lp = 0; -void RenderD7::FrameEnd() -{ - if (metrikd && !shouldbe_disabled)RenderD7::DrawMetrikOvl(); - if (!shouldbe_disabled) OvlHandler(); - /*if (d7_hHeld & KEY_R && d7_hDown & KEY_SELECT) - { - RenderD7::LoadSettings(); - }*/ - if (mt_dumpcsv && lp == 60) - { - std::string _mt_fps = RenderD7::GetFramerate(); - std::string _mt_cpu = std::to_string(C3D_GetProcessingTime()).substr(0, 4); - std::string _mt_gpu = std::to_string(C3D_GetDrawingTime()).substr(0, 4); - std::string _mt_cmd = std::to_string(C3D_GetCmdBufUsage()).substr(0, 4); - mt_csv.open((mt_cname), std::ofstream::app); - std::string fmt_ = _mt_fps + "," + _mt_cpu + "," + _mt_gpu + "," + _mt_cmd + "\n"; - mt_csv << fmt_; - mt_csv.close(); - lp = 0; - } - lp++; - - C3D_FrameEnd(0); +void RenderD7::FrameEnd() { + if (metrikd && !shouldbe_disabled) + RenderD7::DrawMetrikOvl(); + if (!shouldbe_disabled) + OvlHandler(); + /*if (d7_hHeld & KEY_R && d7_hDown & KEY_SELECT) + { + RenderD7::LoadSettings(); + }*/ + if (mt_dumpcsv && lp == 60) { + std::string _mt_fps = RenderD7::GetFramerate(); + std::string _mt_cpu = std::to_string(C3D_GetProcessingTime()).substr(0, 4); + std::string _mt_gpu = std::to_string(C3D_GetDrawingTime()).substr(0, 4); + std::string _mt_cmd = std::to_string(C3D_GetCmdBufUsage()).substr(0, 4); + mt_csv.open((mt_cname), std::ofstream::app); + std::string fmt_ = + _mt_fps + "," + _mt_cpu + "," + _mt_gpu + "," + _mt_cmd + "\n"; + mt_csv << fmt_; + mt_csv.close(); + lp = 0; + } + lp++; + + C3D_FrameEnd(0); } -RenderD7::RSettings::RSettings() -{ - cfgfile = std::make_unique(cfgpath+ "/config.ini"); - cfgfile->read(cfgstruct); - rd7settings = true; +RenderD7::RSettings::RSettings() { + cfgfile = std::make_unique(cfgpath + "/config.ini"); + cfgfile->read(cfgstruct); + rd7settings = true; } -RenderD7::RSettings::~RSettings() -{ - cfgfile->write(cfgstruct); +RenderD7::RSettings::~RSettings() { cfgfile->write(cfgstruct); } + +void RenderD7::RSettings::Draw(void) const { + if (m_state == RSETTINGS) { + RenderD7::OnScreen(Top); + RenderD7::Draw::Rect(0, 0, 400, 21, RenderD7::Color::Hex("#111111")); + RenderD7::Draw::Rect(0, 21, 400, 220, RenderD7::Color::Hex("#eeeeee")); + RenderD7::Draw::Text(0, 0, 0.7f, DSEVENWHITE, "RenderD7->Settings"); + RenderD7::Draw::TextRight(400, 0, 0.7f, RenderD7::Color::Hex("#ffffff"), + RENDERD7VSTRING); + RenderD7::Draw::Text(0, 30, 0.7f, DSEVENBLACK, "RD7SR: " + rd7srstate); + RenderD7::Draw::Text(0, 50, 0.7f, DSEVENBLACK, + "Metrik to Csv: " + csvstate); + RenderD7::Draw::Text(0, 70, 0.7f, DSEVENBLACK, + "Metrik Overlay: " + mtovlstate); + RenderD7::Draw::Text(0, 90, 0.7f, DSEVENBLACK, "Force FPS: " + fpsstate); + RenderD7::Draw::Text(0, 110, 0.7f, DSEVENBLACK, + "Metrik Screen: " + mtscreenstate); + /*RenderD7::Draw::Text(0, 130, 0.7f, DSEVENBLACK, "Metrik Text RGB: " + + mttxtcolstate); RenderD7::Draw::Text(0, 150, 0.7f, DSEVENBLACK, "Metrik + Alpha: " + mtcola); RenderD7::Draw::Text(0, 170, 0.7f, DSEVENBLACK, "Metrik + Text Alpha: " + mttxtcola);*/ + RenderD7::OnScreen(Bottom); + std::string verc = "Config Version: "; + verc += CFGVER; + RenderD7::Draw::Rect(0, 0, 320, 240, RenderD7::Color::Hex("#eeeeee")); + RenderD7::Draw::Text(0, 0, 0.7f, RenderD7::Color::Hex("#111111"), verc); + RenderD7::DrawTObjects(buttons, RenderD7::Color::Hex("#111111"), + RenderD7::Color::Hex("#eeeeee")); + + } else if (m_state == RINFO) { + std::string rd7ver = RENDERD7VSTRING; + std::string rd7cfgver = CFGVER; + std::string citras = is_citra ? "true" : "false"; + std::string buildtime = V_TIME; + std::string commit = V_STRING; + RenderD7::OnScreen(Top); + RenderD7::Draw::Rect(0, 0, 400, 21, RenderD7::Color::Hex("#111111")); + RenderD7::Draw::Rect(0, 21, 400, 220, RenderD7::Color::Hex("#eeeeee")); + RenderD7::Draw::Text(0, 0, 0.7f, DSEVENWHITE, "RenderD7->Info"); + RenderD7::Draw::TextRight(400, 0, 0.7f, RenderD7::Color::Hex("#ffffff"), + RENDERD7VSTRING); + RenderD7::Draw::Text(0, 30, 0.7f, DSEVENBLACK, "App: " + D_app_name); + RenderD7::Draw::Text(0, 50, 0.7f, DSEVENBLACK, "RenderD7: " + rd7ver); + RenderD7::Draw::Text(0, 70, 0.7f, DSEVENBLACK, + "Config-Version: " + rd7cfgver); + RenderD7::Draw::Text(0, 90, 0.7f, DSEVENBLACK, "Citra: " + citras); + RenderD7::Draw::Text(0, 110, 0.7f, DSEVENBLACK, + "RenderD7-Build-Time: \n" + buildtime); + RenderD7::Draw::Text(0, 150, 0.7f, DSEVENBLACK, + "RenderD7-Commit: " + commit); + /*RenderD7::Draw::Text(0, 130, 0.7f, DSEVENBLACK, "Metrik Text RGB: " + + mttxtcolstate); RenderD7::Draw::Text(0, 150, 0.7f, DSEVENBLACK, "Metrik + Alpha: " + mtcola); RenderD7::Draw::Text(0, 170, 0.7f, DSEVENBLACK, "Metrik + Text Alpha: " + mttxtcola);*/ + RenderD7::OnScreen(Bottom); + std::string verc = "Config Version: "; + verc += CFGVER; + RenderD7::Draw::Rect(0, 0, 320, 240, RenderD7::Color::Hex("#eeeeee")); + RenderD7::Draw::Text(0, 0, 0.7f, RenderD7::Color::Hex("#111111"), verc); + RenderD7::DrawTObjects(buttons, RenderD7::Color::Hex("#111111"), + RenderD7::Color::Hex("#eeeeee")); + } +} +std::string RenderD7::Kbd(int lenght, SwkbdType tp) { + shouldbe_disabled = true; + RenderD7::FrameEnd(); + SwkbdState state; + char temp[lenght + 1] = {0}; + + swkbdInit(&state, tp, 2, lenght); + swkbdSetValidation(&state, SWKBD_NOTBLANK_NOTEMPTY, SWKBD_FILTER_PROFANITY, + 0); + SwkbdButton ret = swkbdInputText(&state, temp, sizeof(temp)); + temp[lenght] = '\0'; + return (ret == SWKBD_BUTTON_CONFIRM ? temp : "60"); +} +void RenderD7::RSettings::Logic(u32 hDown, u32 hHeld, u32 hUp, + touchPosition touch) { + if (m_state == RSETTINGS) { + rd7srstate = rd7_superreselution ? "true" : "false"; + csvstate = mt_dumpcsv ? "true" : "false"; + mtovlstate = metrikd ? "true" : "false"; + fpsstate = cfgstruct["settings"]["forceFrameRate"]; + mtscreenstate = mt_screen ? "Bottom" : "Top"; + if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[0]) && + !metrikd) { + RenderD7::ToggleRD7SR(); + cfgstruct["settings"]["super-reselution"] = + rd7_superreselution ? "1" : "0"; + } + if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[1])) { + mt_dumpcsv = mt_dumpcsv ? false : true; + cfgstruct["metrik-settings"]["dumpcsv"] = mt_dumpcsv ? "1" : "0"; + if (mt_dumpcsv) { + mt_cname = csvpc; + mt_cname += "/"; + mt_cname += Date(); + mt_cname += ".csv"; + FILE *logfile = fopen((mt_cname.c_str()), "w"); + fclose(logfile); + mt_csv.open((mt_cname), std::ofstream::app); + mt_csv << "FPS,CPU,GPU,CMD\n"; + mt_csv.close(); + } + } + if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[2])) { + metrikd = metrikd ? false : true; + cfgstruct["metrik-settings"]["enableoverlay"] = metrikd ? "1" : "0"; + } + if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[3]) && + !metrikd) { + cfgstruct["settings"]["forceFrameRate"] = Kbd(2, SWKBD_TYPE_NUMPAD); + C3D_FrameRate(RenderD7::Convert::StringtoFloat( + cfgstruct["settings"]["forceFrameRate"])); + } + if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[4])) { + mt_screen = mt_screen ? 0 : 1; + cfgstruct["metrik-settings"]["screen"] = mt_screen ? "1" : "0"; + } + if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[5])) { + RenderD7::AddOvl(std::make_unique()); + } + if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[6])) { + m_state = RINFO; + } + if (d7_hDown & KEY_B) { + cfgfile->write(cfgstruct); + rd7settings = false; + RenderD7::Scene::Back(); + } + } + if (m_state == RINFO) { + if (d7_hDown & KEY_B) { + m_state = RSETTINGS; + } + } } -void RenderD7::RSettings::Draw(void) const -{ - if (m_state == RSETTINGS) - { - RenderD7::OnScreen(Top); - RenderD7::Draw::Rect(0, 0, 400, 21, RenderD7::Color::Hex("#111111")); - RenderD7::Draw::Rect(0, 21, 400, 220, RenderD7::Color::Hex("#eeeeee")); - RenderD7::Draw::Text(0, 0, 0.7f, DSEVENWHITE, "RenderD7->Settings"); - RenderD7::Draw::TextRight(400, 0, 0.7f, RenderD7::Color::Hex("#ffffff"), RENDERD7VSTRING); - RenderD7::Draw::Text(0, 30, 0.7f, DSEVENBLACK, "RD7SR: " + rd7srstate); - RenderD7::Draw::Text(0, 50, 0.7f, DSEVENBLACK, "Metrik to Csv: " + csvstate); - RenderD7::Draw::Text(0, 70, 0.7f, DSEVENBLACK, "Metrik Overlay: " + mtovlstate); - RenderD7::Draw::Text(0, 90, 0.7f, DSEVENBLACK, "Force FPS: " + fpsstate); - RenderD7::Draw::Text(0, 110, 0.7f, DSEVENBLACK, "Metrik Screen: " + mtscreenstate); - /*RenderD7::Draw::Text(0, 130, 0.7f, DSEVENBLACK, "Metrik Text RGB: " + mttxtcolstate); - RenderD7::Draw::Text(0, 150, 0.7f, DSEVENBLACK, "Metrik Alpha: " + mtcola); - RenderD7::Draw::Text(0, 170, 0.7f, DSEVENBLACK, "Metrik Text Alpha: " + mttxtcola);*/ - RenderD7::OnScreen(Bottom); - std::string verc = "Config Version: "; - verc += CFGVER; - RenderD7::Draw::Rect(0, 0, 320, 240, RenderD7::Color::Hex("#eeeeee")); - RenderD7::Draw::Text(0, 0, 0.7f, RenderD7::Color::Hex("#111111"), verc); - RenderD7::DrawTObjects(buttons, RenderD7::Color::Hex("#111111"), RenderD7::Color::Hex("#eeeeee")); - - } - else if (m_state == RINFO) - { - std::string rd7ver = RENDERD7VSTRING; - std::string rd7cfgver = CFGVER; - std::string citras = is_citra ? "true" : "false"; - std::string buildtime = V_TIME; - std::string commit = V_STRING; - RenderD7::OnScreen(Top); - RenderD7::Draw::Rect(0, 0, 400, 21, RenderD7::Color::Hex("#111111")); - RenderD7::Draw::Rect(0, 21, 400, 220, RenderD7::Color::Hex("#eeeeee")); - RenderD7::Draw::Text(0, 0, 0.7f, DSEVENWHITE, "RenderD7->Info"); - RenderD7::Draw::TextRight(400, 0, 0.7f, RenderD7::Color::Hex("#ffffff"), RENDERD7VSTRING); - RenderD7::Draw::Text(0, 30, 0.7f, DSEVENBLACK, "App: " + D_app_name); - RenderD7::Draw::Text(0, 50, 0.7f, DSEVENBLACK, "RenderD7: " + rd7ver); - RenderD7::Draw::Text(0, 70, 0.7f, DSEVENBLACK, "Config-Version: " + rd7cfgver); - RenderD7::Draw::Text(0, 90, 0.7f, DSEVENBLACK, "Citra: " + citras); - RenderD7::Draw::Text(0, 110, 0.7f, DSEVENBLACK, "RenderD7-Build-Time: \n" + buildtime); - RenderD7::Draw::Text(0, 150, 0.7f, DSEVENBLACK, "RenderD7-Commit: " + commit); - /*RenderD7::Draw::Text(0, 130, 0.7f, DSEVENBLACK, "Metrik Text RGB: " + mttxtcolstate); - RenderD7::Draw::Text(0, 150, 0.7f, DSEVENBLACK, "Metrik Alpha: " + mtcola); - RenderD7::Draw::Text(0, 170, 0.7f, DSEVENBLACK, "Metrik Text Alpha: " + mttxtcola);*/ - RenderD7::OnScreen(Bottom); - std::string verc = "Config Version: "; - verc += CFGVER; - RenderD7::Draw::Rect(0, 0, 320, 240, RenderD7::Color::Hex("#eeeeee")); - RenderD7::Draw::Text(0, 0, 0.7f, RenderD7::Color::Hex("#111111"), verc); - RenderD7::DrawTObjects(buttons, RenderD7::Color::Hex("#111111"), RenderD7::Color::Hex("#eeeeee")); - - } -} -std::string RenderD7::Kbd(int lenght, SwkbdType tp) -{ - shouldbe_disabled = true; - RenderD7::FrameEnd(); - SwkbdState state; - char temp[lenght + 1] = { 0 }; - - swkbdInit(&state, tp, 2, lenght); - swkbdSetValidation(&state, SWKBD_NOTBLANK_NOTEMPTY, SWKBD_FILTER_PROFANITY, 0); - SwkbdButton ret = swkbdInputText(&state, temp, sizeof(temp)); - temp[lenght] = '\0'; - return (ret == SWKBD_BUTTON_CONFIRM ? temp : "60"); -} -void RenderD7::RSettings::Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) -{ - if (m_state == RSETTINGS) { - rd7srstate = rd7_superreselution ? "true" : "false"; - csvstate = mt_dumpcsv ? "true" : "false"; - mtovlstate = metrikd ? "true" : "false"; - fpsstate = cfgstruct["settings"]["forceFrameRate"]; - mtscreenstate = mt_screen ? "Bottom" : "Top"; - if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[0]) && !metrikd) - { - RenderD7::ToggleRD7SR(); - cfgstruct["settings"]["super-reselution"] = rd7_superreselution ? "1" : "0"; - } - if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[1])) - { - mt_dumpcsv = mt_dumpcsv ? false : true; - cfgstruct["metrik-settings"]["dumpcsv"] = mt_dumpcsv ? "1" : "0"; - if (mt_dumpcsv) - { - mt_cname = csvpc; - mt_cname += "/"; - mt_cname += Date(); - mt_cname += ".csv"; - FILE* logfile = fopen((mt_cname.c_str()), "w"); - fclose(logfile); - mt_csv.open((mt_cname), std::ofstream::app); - mt_csv << "FPS,CPU,GPU,CMD\n"; - mt_csv.close(); - } - } - if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[2])) - { - metrikd = metrikd ? false : true; - cfgstruct["metrik-settings"]["enableoverlay"] = metrikd ? "1" : "0"; - } - if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[3]) && !metrikd) - { - cfgstruct["settings"]["forceFrameRate"] = Kbd(2, SWKBD_TYPE_NUMPAD); - C3D_FrameRate(RenderD7::Convert::StringtoFloat(cfgstruct["settings"]["forceFrameRate"])); - } - if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[4])) - { - mt_screen = mt_screen ? 0 : 1; - cfgstruct["metrik-settings"]["screen"] = mt_screen ? "1" : "0"; - } - if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[5])) - { - RenderD7::AddOvl(std::make_unique()); - } - if (d7_hDown & KEY_TOUCH && RenderD7::touchTObj(d7_touch, buttons[6])) - { - m_state = RINFO; - } - if (d7_hDown & KEY_B) - { - cfgfile->write(cfgstruct); - rd7settings = false; - RenderD7::Scene::Back(); - } - - } - if (m_state == RINFO) - { - if (d7_hDown & KEY_B) - { - m_state = RSETTINGS; - } - } - +void RenderD7::LoadSettings() { + RenderD7::Scene::Load(std::make_unique()); } -void RenderD7::LoadSettings(){ - RenderD7::Scene::Load(std::make_unique()); +void RenderD7::AddOvl(std::unique_ptr overlay) { + overlays.push(std::move(overlay)); } -void RenderD7::AddOvl(std::unique_ptr overlay) -{ - overlays.push(std::move(overlay)); +RenderD7::Console::Console() { + this->x = 0; + this->y = 0; + this->w = 320; + this->h = 240; + this->color = {0, 0, 0, 255}; } - -RenderD7::Console::Console() -{ - this->x = 0; - this->y = 0; - this->w = 320; - this->h = 240; - this->color = {0, 0, 0, 255}; +RenderD7::Console::Console(int x, int y, int w, int h, u8 a) { + this->x = x; + this->y = y; + this->w = w; + this->h = h; + this->color = {0, 0, 0, a}; } -RenderD7::Console::Console(int x, int y, int w, int h, u8 a) -{ - this->x = x; - this->y = y; - this->w = w; - this->h = h; - this->color = {0, 0, 0, a}; - +RenderD7::Console::Console(int x, int y, int w, int h, + RenderD7::Color::rgba col) { + this->x = x; + this->y = y; + this->w = w; + this->h = h; + this->color = col; } -RenderD7::Console::Console(int x, int y, int w, int h, RenderD7::Color::rgba col) -{ - this->x = x; - this->y = y; - this->w = w; - this->h = h; - this->color = col; +RenderD7::Console::Console(int x, int y, int w, int h, std::string name, + RenderD7::Color::rgba col, + RenderD7::Color::rgba barcol, + RenderD7::Color::rgba outlinecol) { + this->x = x; + this->y = y; + this->w = w; + this->h = h; + this->color = col; + this->outlinecol = outlinecol; + this->barcolor = barcol; + this->m_name = name; } -RenderD7::Console::Console(int x, int y, int w, int h, std::string name, RenderD7::Color::rgba col, RenderD7::Color::rgba barcol, RenderD7::Color::rgba outlinecol) -{ - this->x = x; - this->y = y; - this->w = w; - this->h = h; - this->color = col; - this->outlinecol = outlinecol; - this->barcolor = barcol; - this->m_name = name; +RenderD7::Console::~Console() {} +void RenderD7::Console::On(C3D_RenderTarget *t_cscreen) { + this->cscreen = t_cscreen; } -RenderD7::Console::~Console() -{ - -} -void RenderD7::Console::On(C3D_RenderTarget *t_cscreen) -{ - this->cscreen = t_cscreen; -} -bool RenderD7::Console::Update() -{ - bool dr_sc = true; - return dr_sc; +bool RenderD7::Console::Update() { + bool dr_sc = true; + return dr_sc; } diff --git a/source/sound.cpp b/source/sound.cpp index e471217..96beb73 100644 --- a/source/sound.cpp +++ b/source/sound.cpp @@ -10,121 +10,125 @@ using std::string; // Reference: http://yannesposito.com/Scratch/en/blog/2010-10-14-Fun-with-wav/ typedef struct _WavHeader { - char magic[4]; // "RIFF" - u32 totallength; // Total file length, minus 8. - char wavefmt[8]; // Should be "WAVEfmt " - u32 format; // 16 for PCM format - u16 pcm; // 1 for PCM format - u16 channels; // Channels - u32 frequency; // Sampling frequency - u32 bytes_per_second; - u16 bytes_by_capture; - u16 bits_per_sample; - char data[4]; // "data" - u32 bytes_in_data; + char magic[4]; // "RIFF" + u32 totallength; // Total file length, minus 8. + char wavefmt[8]; // Should be "WAVEfmt " + u32 format; // 16 for PCM format + u16 pcm; // 1 for PCM format + u16 channels; // Channels + u32 frequency; // Sampling frequency + u32 bytes_per_second; + u16 bytes_by_capture; + u16 bits_per_sample; + char data[4]; // "data" + u32 bytes_in_data; } WavHeader; static_assert(sizeof(WavHeader) == 44, "WavHeader size is not 44 bytes."); -sound::sound(const string& path, int channel, bool toloop) { - if (isndspinit){ - ndspSetOutputMode(NDSP_OUTPUT_STEREO); - ndspSetOutputCount(2); // Num of buffers +sound::sound(const string &path, int channel, bool toloop) { + if (isndspinit) { + ndspSetOutputMode(NDSP_OUTPUT_STEREO); + ndspSetOutputCount(2); // Num of buffers - // Reading wav file - FILE* fp = fopen(path.c_str(), "rb"); + // Reading wav file + FILE *fp = fopen(path.c_str(), "rb"); - if (!fp) { - printf("Could not open the WAV file: %s\n", path.c_str()); - return; - } + if (!fp) { + printf("Could not open the WAV file: %s\n", path.c_str()); + return; + } - WavHeader wavHeader; - size_t read = fread(&wavHeader, 1, sizeof(wavHeader), fp); - if (read != sizeof(wavHeader)) { - // Short read. - printf("WAV file header is too short: %s\n", path.c_str()); - fclose(fp); - return; - } + WavHeader wavHeader; + size_t read = fread(&wavHeader, 1, sizeof(wavHeader), fp); + if (read != sizeof(wavHeader)) { + // Short read. + printf("WAV file header is too short: %s\n", path.c_str()); + fclose(fp); + return; + } - // Verify the header. - static const char RIFF_magic[4] = {'R','I','F','F'}; - if (memcmp(wavHeader.magic, RIFF_magic, sizeof(wavHeader.magic)) != 0) { - // Incorrect magic number. - printf("Wrong file format.\n"); - fclose(fp); - return; - } + // Verify the header. + static const char RIFF_magic[4] = {'R', 'I', 'F', 'F'}; + if (memcmp(wavHeader.magic, RIFF_magic, sizeof(wavHeader.magic)) != 0) { + // Incorrect magic number. + printf("Wrong file format.\n"); + fclose(fp); + return; + } - if (wavHeader.totallength == 0 || - (wavHeader.channels != 1 && wavHeader.channels != 2) || - (wavHeader.bits_per_sample != 8 && wavHeader.bits_per_sample != 16)) { - // Unsupported WAV file. - printf("Corrupted wav file.\n"); - fclose(fp); - return; - } + if (wavHeader.totallength == 0 || + (wavHeader.channels != 1 && wavHeader.channels != 2) || + (wavHeader.bits_per_sample != 8 && wavHeader.bits_per_sample != 16)) { + // Unsupported WAV file. + printf("Corrupted wav file.\n"); + fclose(fp); + return; + } - // Get the file size. - fseek(fp, 0, SEEK_END); - dataSize = ftell(fp) - sizeof(wavHeader); + // Get the file size. + fseek(fp, 0, SEEK_END); + dataSize = ftell(fp) - sizeof(wavHeader); - // Allocating and reading samples - data = static_cast(linearAlloc(dataSize)); - fseek(fp, 44, SEEK_SET); - fread(data, 1, dataSize, fp); - fclose(fp); - dataSize /= 2; // FIXME: 16-bit or stereo? + // Allocating and reading samples + data = static_cast(linearAlloc(dataSize)); + fseek(fp, 44, SEEK_SET); + fread(data, 1, dataSize, fp); + fclose(fp); + dataSize /= 2; // FIXME: 16-bit or stereo? - // Find the right format - u16 ndspFormat; - if (wavHeader.bits_per_sample == 8) { - ndspFormat = (wavHeader.channels == 1) ? - NDSP_FORMAT_MONO_PCM8 : - NDSP_FORMAT_STEREO_PCM8; - } else { - ndspFormat = (wavHeader.channels == 1) ? - NDSP_FORMAT_MONO_PCM16 : - NDSP_FORMAT_STEREO_PCM16; - } + // Find the right format + u16 ndspFormat; + if (wavHeader.bits_per_sample == 8) { + ndspFormat = (wavHeader.channels == 1) ? NDSP_FORMAT_MONO_PCM8 + : NDSP_FORMAT_STEREO_PCM8; + } else { + ndspFormat = (wavHeader.channels == 1) ? NDSP_FORMAT_MONO_PCM16 + : NDSP_FORMAT_STEREO_PCM16; + } - ndspChnReset(channel); - ndspChnSetInterp(channel, NDSP_INTERP_NONE); - ndspChnSetRate(channel, float(wavHeader.frequency)); - ndspChnSetFormat(channel, ndspFormat); + ndspChnReset(channel); + ndspChnSetInterp(channel, NDSP_INTERP_NONE); + ndspChnSetRate(channel, float(wavHeader.frequency)); + ndspChnSetFormat(channel, ndspFormat); - // Create and play a wav buffer - memset(&waveBuf, 0, sizeof(waveBuf)); + // Create and play a wav buffer + memset(&waveBuf, 0, sizeof(waveBuf)); - waveBuf.data_vaddr = reinterpret_cast(data); - waveBuf.nsamples = dataSize / (wavHeader.bits_per_sample >> 3); - waveBuf.looping = toloop; - waveBuf.status = NDSP_WBUF_FREE; - chnl = channel;} + waveBuf.data_vaddr = reinterpret_cast(data); + waveBuf.nsamples = dataSize / (wavHeader.bits_per_sample >> 3); + waveBuf.looping = toloop; + waveBuf.status = NDSP_WBUF_FREE; + chnl = channel; + } } sound::~sound() { - if (isndspinit){ - waveBuf.data_vaddr = 0; - waveBuf.nsamples = 0; - waveBuf.looping = false; - waveBuf.status = 0; - ndspChnWaveBufClear(chnl); + if (isndspinit) { + waveBuf.data_vaddr = 0; + waveBuf.nsamples = 0; + waveBuf.looping = false; + waveBuf.status = 0; + ndspChnWaveBufClear(chnl); - if (data) { - linearFree(data); - }} + if (data) { + linearFree(data); + } + } } void sound::play() { - if (isndspinit){ - if (!data) return; - DSP_FlushDataCache(data, dataSize); - ndspChnWaveBufAdd(chnl, &waveBuf);} + if (isndspinit) { + if (!data) + return; + DSP_FlushDataCache(data, dataSize); + ndspChnWaveBufAdd(chnl, &waveBuf); + } } void sound::stop() { - if (isndspinit){ - if (!data) return; - ndspChnWaveBufClear(chnl);} + if (isndspinit) { + if (!data) + return; + ndspChnWaveBufClear(chnl); + } } diff --git a/source/thread.cpp b/source/thread.cpp index c6dbc56..7db3968 100644 --- a/source/thread.cpp +++ b/source/thread.cpp @@ -1,81 +1,79 @@ #include namespace RenderD7 { - void Threads::Exit() - { - - } - Thread::Thread() : - m_started(false), - m_running(false) { /* do nothing */ } - - Thread::Thread(std::function t_function, RenderD7::Parameter t_parameter, bool t_autostart, bool t_detached, unsigned long long int t_stackSize) : - m_started(false), - m_running(false) { - initialize(t_function, t_parameter, t_autostart, t_detached, t_stackSize); - } - - Thread::~Thread() { - join(); - - if (m_started) threadFree(m_thread); - } - - void Thread::initialize(std::function t_function, RenderD7::Parameter t_parameter, bool t_autostart, bool t_detached, unsigned long long int t_stackSize) { - m_stackSize = t_stackSize; - m_data.m_parameter = t_parameter; - m_data.m_function = t_function; - m_data.m_running = &m_running; - - if (t_autostart) { - start(t_detached); - } - } - - void Thread::setStackSize(unsigned long long int t_stackSize) { - m_stackSize = t_stackSize; - } - - void Thread::start(bool t_detached) { - if (!m_running) { - m_started = true; - m_running = true; - s32 prio; - svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); - m_thread = threadCreate(threadFunction, &m_data, m_stackSize, prio + 1, -2, t_detached); - } - } - - void Thread::kill() { - threadDetach(m_thread); - m_running = false; - m_started = false; - } - - void Thread::join(long long unsigned int t_timeout) { - if (m_running) { - threadJoin(m_thread, t_timeout); - threadFree(m_thread); - m_running = false; - m_started = false; - } - } - - bool Thread::isRunning() { - return m_running; - } - - void Thread::sleep() { - svcSleepThread(0); - } - - void Thread::sleep(int t_milliseconds) { - svcSleepThread(1000000 * t_milliseconds); - } - - // private methods - void Thread::threadFunction(void* arg) { - RenderD7::Thread::ThreadData data = *static_cast(arg); - data.m_function(data.m_parameter); - *data.m_running = false; - } +void Threads::Exit() {} +Thread::Thread() : m_started(false), m_running(false) { /* do nothing */ } + +Thread::Thread(std::function t_function, + RenderD7::Parameter t_parameter, bool t_autostart, + bool t_detached, unsigned long long int t_stackSize) + : m_started(false), m_running(false) { + initialize(t_function, t_parameter, t_autostart, t_detached, t_stackSize); +} + +Thread::~Thread() { + join(); + + if (m_started) + threadFree(m_thread); +} + +void Thread::initialize(std::function t_function, + RenderD7::Parameter t_parameter, bool t_autostart, + bool t_detached, unsigned long long int t_stackSize) { + m_stackSize = t_stackSize; + m_data.m_parameter = t_parameter; + m_data.m_function = t_function; + m_data.m_running = &m_running; + + if (t_autostart) { + start(t_detached); + } +} + +void Thread::setStackSize(unsigned long long int t_stackSize) { + m_stackSize = t_stackSize; +} + +void Thread::start(bool t_detached) { + if (!m_running) { + m_started = true; + m_running = true; + s32 prio; + svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); + m_thread = threadCreate(threadFunction, &m_data, m_stackSize, prio + 1, -2, + t_detached); + } +} + +void Thread::kill() { + threadDetach(m_thread); + m_running = false; + m_started = false; +} + +void Thread::join(long long unsigned int t_timeout) { + if (m_running) { + threadJoin(m_thread, t_timeout); + threadFree(m_thread); + m_running = false; + m_started = false; + } +} + +bool Thread::isRunning() { return m_running; } + +void Thread::sleep() { svcSleepThread(0); } + +void Thread::sleep(int t_milliseconds) { + svcSleepThread(1000000 * t_milliseconds); +} + +// private methods +void Thread::threadFunction(void *arg) { + RenderD7::Thread::ThreadData data = + *static_cast(arg); + data.m_function(data.m_parameter); + *data.m_running = false; +} +} // namespace RenderD7