Format to LLVL

This commit is contained in:
tobid7vx 2022-11-12 23:19:41 +01:00
parent 36e5676d9f
commit 8b70d0e9b7
44 changed files with 4869 additions and 4889 deletions

View File

@ -57,6 +57,9 @@
"shared_mutex": "cpp", "shared_mutex": "cpp",
"valarray": "cpp", "valarray": "cpp",
"random": "cpp", "random": "cpp",
"cuchar": "cpp" "cuchar": "cpp",
"compare": "cpp",
"concepts": "cpp",
"numbers": "cpp"
} }
} }

View File

@ -7,29 +7,26 @@
#include <renderd7/Image.hpp> #include <renderd7/Image.hpp>
#include <renderd7/Time.hpp>
#include <renderd7/Screen.hpp> #include <renderd7/Screen.hpp>
#include <renderd7/Time.hpp>
#include <renderd7/Fonts/NFontApi.hpp> #include <renderd7/Fonts/NFontApi.hpp>
namespace RenderD7 namespace RenderD7 {
{ enum Encoder {
enum Encoder
{
BITMAP, ///< Encode Data to Bitmap BITMAP, ///< Encode Data to Bitmap
DIRECT, ///< Encode Direct to Framebuffer(No Decoder Required) DIRECT, ///< Encode Direct to Framebuffer(No Decoder Required)
C3D ///< Encode Directly to C3D_Tex (Just an Idea) C3D ///< Encode Directly to C3D_Tex (Just an Idea)
}; };
enum Decoder enum Decoder {
{
BITMAP2C3D, ///< Decode and Encode to C3D_Tex (Currently Fastest) (47,4ms) BITMAP2C3D, ///< Decode and Encode to C3D_Tex (Currently Fastest) (47,4ms)
BITMAP2PNG2C3D ///< Decode Bitmap end Convert to Png, then C3D (Very Slow) (201,4ms) BITMAP2PNG2C3D ///< Decode Bitmap end Convert to Png, then C3D (Very Slow)
}; ///< (201,4ms)
};
class BitmapPrinter class BitmapPrinter {
{ public:
public:
BitmapPrinter(int w, int h); BitmapPrinter(int w, int h);
~BitmapPrinter(); ~BitmapPrinter();
bool DecodeFile(std::string file); bool DecodeFile(std::string file);
@ -40,7 +37,7 @@ namespace RenderD7
void DrawRectFilled(int x, int y, int w, int h, 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 UsePreMap(BMP map);
void UsePrePrintMap(BitmapPrinter printmap); void UsePrePrintMap(BitmapPrinter printmap);
BMP GetBitmap(){ return bitmap; } BMP GetBitmap() { return bitmap; }
void SaveBmp(std::string name); void SaveBmp(std::string name);
void SavePng(std::string name); void SavePng(std::string name);
@ -62,22 +59,29 @@ namespace RenderD7
bool IsBenchmarkRunning() { return this->benchmark; } bool IsBenchmarkRunning() { return this->benchmark; }
void DrawDebugText(int x, int y, int t_size, u32 color, std::string text); 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); void DrawText(int x, int y, float t_size, u32 color, std::string text,
private: RenderD7::NFontApi font);
//funcs
private:
// funcs
bool Decode(Decoder deccc); bool Decode(Decoder deccc);
void DrawDebugChar(u32 posX, u32 posY, int t_size, u32 color, char character); 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); void DrawChar(int posX, int posY, float t_size, u32 color, char character,
//parameter RenderD7::NFontApi font);
// parameter
int frame = 0; int frame = 0;
RenderD7::Image renderframe; RenderD7::Image renderframe;
bool isscreen = false; bool isscreen = false;
C3D_RenderTarget* targetr; C3D_RenderTarget *targetr;
BMP bitmap = BMP(20, 20, true); //Need to Set e Predefined Bitmap. If not the System will Crash. BMP bitmap = BMP(
BMP blank = BMP(20, 20, true); //Need to Set e Predefined Bitmap. If not the System will Crash. 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.
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
//Benchmark Stuff; // Benchmark Stuff;
int testfpsd; int testfpsd;
bool benchmark = false; bool benchmark = false;
bool setupbenchmark; bool setupbenchmark;
@ -103,5 +107,5 @@ namespace RenderD7
Encoder encc = Encoder::BITMAP; Encoder encc = Encoder::BITMAP;
Decoder decc = Decoder::BITMAP2C3D; Decoder decc = Decoder::BITMAP2C3D;
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
}; };
} } // namespace RenderD7

View File

@ -1,31 +1,31 @@
#pragma once #pragma once
#include <string>
#include <unistd.h>
#include <memory>
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <sstream> #include <memory>
#include <regex> #include <regex>
#include <sstream>
#include <string>
#include <unistd.h>
#define UNPACK_RGBA(col) (uint8_t) (col >> 24), (col >> 16), (col >> 8), (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) #define UNPACK_BGRA(col) (uint8_t)(col >> 8), (col >> 16), (col >> 24), (col)
namespace RenderD7 namespace RenderD7 {
{ namespace Color {
namespace Color struct rgba {
{
struct rgba
{
uint8_t r, g, b, a; uint8_t r, g, b, a;
}; };
class RGBA{ class RGBA {
public: 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){} RGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
uint32_t toRGBA() const {return (m_r << 24) | (m_g << 16) | (m_b << 8) | m_a;} : m_r(r), m_g(g), m_b(b), m_a(a) {}
uint32_t toRGBA() const {
uint8_t m_r, m_g ,m_b, m_a; return (m_r << 24) | (m_g << 16) | (m_b << 8) | m_a;
};
std::string RGB2Hex(int r, int g, int b);
uint32_t Hex(const std::string color, uint8_t a = 255);
} }
}
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

View File

@ -1,25 +1,28 @@
#pragma once #pragma once
#include <citro3d.h>
#include <citro2d.h>
#include <3ds.h> #include <3ds.h>
#include <citro2d.h>
#include <citro3d.h>
#include <string> #include <string>
namespace RenderD7 namespace RenderD7 {
{ namespace Draw {
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 Rect(float x, float y, float w, float h, u32 color); bool Px(float x, float y, u32 color);
bool NFRect(float p1x, float p1y, float w, float h, u32 color, float scale = 1); void TextCentered(float x, float y, float size, u32 color, std::string Text,
bool Px(float x, float y, u32 color); int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr);
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,
void Text(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr); 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); void TextRight(float x, float y, float size, u32 color, std::string Text,
float GetTextWidth(float size, std::string Text, C2D_Font fnt = nullptr); int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr);
void GetTextSize(float size, float *width, float *height, std::string Text, C2D_Font fnt = nullptr); float GetTextWidth(float size, std::string Text, C2D_Font fnt = nullptr);
float GetTextHeight(float size, std::string Text, C2D_Font fnt = nullptr); void GetTextSize(float size, float *width, float *height, std::string Text,
Result LoadFont(C2D_Font &fnt, const char * Path = ""); C2D_Font fnt = nullptr);
Result UnloadFont(C2D_Font &fnt); float GetTextHeight(float size, std::string Text, C2D_Font fnt = nullptr);
bool Circle(float x, float y, float radius, u32 color); Result LoadFont(C2D_Font &fnt, const char *Path = "");
bool Image(C2D_Image img, float x, float y, float scaleX = 1.0f, float scaleY = 1.0f); 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

View File

@ -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 #pragma once
#include <string> #include <string>
#include <vector> #include <vector>
#include <physfs.h> #include <physfs.h>
#define RD7_FSYS_GETINFO(path) ({ \ #define RD7_FSYS_GETINFO(path) \
({ \
RenderD7::FileSystem::Info inf; \ RenderD7::FileSystem::Info inf; \
RenderD7::FileSystem::GetInfo(path, inf); \ RenderD7::FileSystem::GetInfo(path, inf); \
inf; \ inf; \
}) })
namespace RenderD7 namespace RenderD7 {
{ namespace FileSystem {
namespace FileSystem static constexpr auto MAX_STAMP = 0x20000000000000LL;
{
static constexpr auto MAX_STAMP = 0x20000000000000LL;
enum FileMode enum FileMode { FileMode_Open, FileMode_Read, FileMode_Write, FileMode_Closed };
{
FileMode_Open,
FileMode_Read,
FileMode_Write,
FileMode_Closed
};
enum FileType enum FileType {
{
FileType_File, FileType_File,
FileType_Directory, FileType_Directory,
FileType_SymLink, FileType_SymLink,
FileType_Other FileType_Other
}; };
struct File struct File {
{ PHYSFS_file *handle;
PHYSFS_file* handle;
FileMode mode; FileMode mode;
File() File() {
{
this->handle = nullptr; this->handle = nullptr;
this->mode = FileMode_Closed; this->mode = FileMode_Closed;
} }
int64_t GetSize() int64_t GetSize() {
{
if (this->handle == nullptr) if (this->handle == nullptr)
return 0; return 0;
return (int64_t)PHYSFS_fileLength(this->handle); return (int64_t)PHYSFS_fileLength(this->handle);
} }
}; };
struct Info struct Info {
{
int64_t size; int64_t size;
int64_t mod_time; int64_t mod_time;
FileType type; 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 ** mounts a specific directory for physfs to search in
** this is typically a main directory ** this is typically a main directory
*/ */
bool SetSource(const char* source); bool SetSource(const char *source);
/* /*
** mounts a specific directory as a "save" directory ** mounts a specific directory as a "save" directory
** if appended, it will be added to the search path ** if appended, it will be added to the search path
*/ */
bool SetIdentity(const char* name, bool append); bool SetIdentity(const char *name, bool append);
static std::string savePath; static std::string savePath;
/* gets the last physfs error */ /* gets the last physfs error */
const char* GetPhysfsError(); const char *GetPhysfsError();
/* strips any duplicate slashes */ /* strips any duplicate slashes */
std::string Normalize(const std::string& input); std::string Normalize(const std::string &input);
/* gets the user directory from physfs */ /* gets the user directory from physfs */
std::string GetUserDirectory(); std::string GetUserDirectory();
/* gets the save directory */ /* gets the save directory */
std::string GetSaveDirectory(); std::string GetSaveDirectory();
/* sets up the writing directory for physfs */ /* sets up the writing directory for physfs */
bool SetupWriteDirectory(); bool SetupWriteDirectory();
/* gets a list of files in a directory */ /* gets a list of files in a directory */
void GetDirectoryItems(const char* directory, std::vector<std::string>& items); void GetDirectoryItems(const char *directory, std::vector<std::string> &items);
/* gets the size, mod_time, and type of a file */ /* gets the size, mod_time, and type of a file */
bool GetInfo(const char* filename, Info& info); bool GetInfo(const char *filename, Info &info);
/* creates a new directory */ /* creates a new directory */
bool CreateDirectory(const char* name); bool CreateDirectory(const char *name);
bool CloseFile(File& file); bool CloseFile(File &file);
/* creates a new file */ /* creates a new file */
bool OpenFile(File& file, const char* name, FileMode mode); bool OpenFile(File &file, const char *name, FileMode mode);
/* writes to a file */ /* writes to a file */
bool WriteFile(File& file, const void* data, int64_t size); bool WriteFile(File &file, const void *data, int64_t size);
/* reads a file's content */ /* reads a file's content */
int64_t ReadFile(File& file, void* destination, int64_t size); int64_t ReadFile(File &file, void *destination, int64_t size);
} } // namespace FileSystem
} } // namespace RenderD7

View File

@ -1,16 +1,15 @@
#pragma once #pragma once
#include <bitset>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <bitset>
#include <vector> #include <vector>
#include <renderd7/external/stb_truetype.h> #include <renderd7/external/stb_truetype.h>
#define MAXUNICODE 0x10FFFF #define MAXUNICODE 0x10FFFF
namespace RenderD7 namespace RenderD7 {
{ inline int utf8_decode(const char *o) {
inline int utf8_decode(const char* o) {
static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
const unsigned char *s = (const unsigned char *)o; const unsigned char *s = (const unsigned char *)o;
unsigned int c = s[0]; unsigned int c = s[0];
@ -32,21 +31,18 @@ namespace RenderD7
s += count; /* skip continuation bytes read */ s += count; /* skip continuation bytes read */
} }
return res; return res;
} }
inline std::string IntToUtf8(int convertval) {
inline std::string IntToUtf8(int convertval){
// We only care about plane 1 right now, // We only care about plane 1 right now,
// but know that we have other options (0x10FFFF) // but know that we have other options (0x10FFFF)
// Technically UTF-8 is "limited" to 4 bytes, so it's not // Technically UTF-8 is "limited" to 4 bytes, so it's not
// Like it matters much anyways these days // Like it matters much anyways these days
if(convertval == 0) if (convertval == 0)
return " "; return " ";
if( (convertval <= 0x7F) && (convertval > 0x00) ){ if ((convertval <= 0x7F) && (convertval > 0x00)) {
std::string out("."); std::string out(".");
@ -58,7 +54,7 @@ namespace RenderD7
return out; return out;
} else if ( (convertval >= 0x80) && (convertval <= 0x07FF) ) { } else if ((convertval >= 0x80) && (convertval <= 0x07FF)) {
std::string out(".."); std::string out("..");
@ -68,7 +64,6 @@ namespace RenderD7
std::bitset<8> first(firstShift); std::bitset<8> first(firstShift);
std::bitset<8> last(secondShift); std::bitset<8> last(secondShift);
unsigned long l = first.to_ulong(); unsigned long l = first.to_ulong();
unsigned char c = static_cast<unsigned char>(l); unsigned char c = static_cast<unsigned char>(l);
out[0] = c; out[0] = c;
@ -79,8 +74,7 @@ namespace RenderD7
return out; return out;
} else if( (convertval >= 0x0800) && (convertval <= 0xFFFF) ){ } else if ((convertval >= 0x0800) && (convertval <= 0xFFFF)) {
std::string out("..."); std::string out("...");
@ -106,27 +100,26 @@ namespace RenderD7
return out; return out;
} else{ } else {
return " "; return " ";
} }
} }
#define I2U82I(val) RenderD7::utf8_decode(RenderD7::IntToUtf8(val).c_str()) #define I2U82I(val) RenderD7::utf8_decode(RenderD7::IntToUtf8(val).c_str())
class NFontApi class NFontApi {
{ public:
public:
NFontApi(); NFontApi();
~NFontApi(); ~NFontApi();
void LoadTTF(std::string path); void LoadTTF(std::string path);
unsigned char* GetGlyphBitmap(char glyph); unsigned char *GetGlyphBitmap(char glyph);
std::string GetStatus(){ return status; } std::string GetStatus() { return status; }
float GetScale() {return scale; } float GetScale() { return scale; }
int GetGlyphWidth(char glyph); int GetGlyphWidth(char glyph);
int GetGlyphHeight(char glyph); int GetGlyphHeight(char glyph);
int GetLineHeight(){ return l_h; } int GetLineHeight() { return l_h; }
int GetBaseHeight(){ return height; } int GetBaseHeight() { return height; }
private:
private:
std::string status; std::string status;
int height; int height;
@ -139,11 +132,11 @@ namespace RenderD7
int w; int w;
int h; int h;
int x0,y0,x1,y1; int x0, y0, x1, y1;
int ascent,baseline,decent,linegap; int ascent, baseline, decent, linegap;
int linespace; int linespace;
stbtt_fontinfo font; stbtt_fontinfo font;
}; };
} } // namespace RenderD7

View File

@ -7,18 +7,16 @@
#include <renderd7/bmp.hpp> #include <renderd7/bmp.hpp>
#include <renderd7/bmpconverter.hpp> #include <renderd7/bmpconverter.hpp>
#include <renderd7/external/lodepng.h>
#include <renderd7/Color.hpp>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <renderd7/Color.hpp>
#include <renderd7/external/lodepng.h>
namespace RenderD7 namespace RenderD7 {
{ /// Image Class
/// Image Class class Image {
class Image public:
{ Image() {}
public:
Image(){}
~Image(); ~Image();
void Unload(); void Unload();
@ -37,12 +35,12 @@ namespace RenderD7
bool Draw(float x, float y, float scaleX = 1.0f, float scaleY = 1.0f); bool Draw(float x, float y, float scaleX = 1.0f, float scaleY = 1.0f);
/// \brief Get The Image /// \brief Get The Image
/// \return C2D_Image /// \return C2D_Image
C2D_Image Get(){return this->img;} C2D_Image Get() { return this->img; }
void FromSheet(RenderD7::Sheet sheet, size_t index); void FromSheet(RenderD7::Sheet sheet, size_t index);
/// \param img this is the C2D_Image /// \param img this is the C2D_Image
C2D_Image img; C2D_Image img;
/// \param loadet whether the image is loadet or not /// \param loadet whether the image is loadet or not
bool loadet = false; bool loadet = false;
}; };
} } // namespace RenderD7

View File

@ -1,17 +1,17 @@
#pragma once #pragma once
#include <memory> #include <memory>
namespace RenderD7 namespace RenderD7 {
{ class Ovl {
class Ovl { public:
public: virtual ~Ovl() {}
virtual ~Ovl(){}
virtual void Draw() const = 0; virtual void Draw() const = 0;
virtual void Logic() = 0; virtual void Logic() = 0;
inline bool IsKilled() {return this->iskilled; } inline bool IsKilled() { return this->iskilled; }
inline void Kill() { iskilled = true; } inline void Kill() { iskilled = true; }
private:
private:
bool iskilled = false; bool iskilled = false;
}; };
void AddOvl(std::unique_ptr<RenderD7::Ovl> scene); void AddOvl(std::unique_ptr<RenderD7::Ovl> scene);
} } // namespace RenderD7

View File

@ -1,15 +1,13 @@
#pragma once #pragma once
#include <citro3d.h>
#include <citro2d.h> #include <citro2d.h>
#include <citro3d.h>
extern C3D_RenderTarget *Top;
extern C3D_RenderTarget *TopRight;
extern C3D_RenderTarget *Bottom;
extern C3D_RenderTarget* Top; namespace RenderD7 {
extern C3D_RenderTarget* TopRight; /// Set current RenderScreen
extern C3D_RenderTarget* Bottom; /// \param target The RenderTarget Top, Bottom
void OnScreen(C3D_RenderTarget *target);
namespace RenderD7 } // namespace RenderD7
{
/// Set current RenderScreen
/// \param target The RenderTarget Top, Bottom
void OnScreen(C3D_RenderTarget *target);
}

View File

@ -2,12 +2,10 @@
#include <citro2d.h> #include <citro2d.h>
#include <citro3d.h> #include <citro3d.h>
namespace RenderD7 namespace RenderD7 {
{ /** The Spritesheet Class */
/** The Spritesheet Class */ class Sheet {
class Sheet public:
{
public:
/// Construct sheet /// Construct sheet
Sheet(); Sheet();
// Deconstruct sheet // Deconstruct sheet
@ -19,5 +17,5 @@ namespace RenderD7
void Free(); void Free();
/// The Spritesheet /// The Spritesheet
C2D_SpriteSheet spritesheet; C2D_SpriteSheet spritesheet;
}; };
} } // namespace RenderD7

View File

@ -3,15 +3,13 @@
#include <citro2d.h> #include <citro2d.h>
#include <citro3d.h> #include <citro3d.h>
#include <renderd7/Sheet.hpp>
#include <renderd7/Image.hpp> #include <renderd7/Image.hpp>
#include <renderd7/Sheet.hpp>
namespace RenderD7 namespace RenderD7 {
{ /// Sprite Class
/// Sprite Class class Sprite {
class Sprite public:
{
public:
/// \brief Construct Sprite /// \brief Construct Sprite
Sprite(); Sprite();
/// \brief Deconstruct Sprite /// \brief Deconstruct Sprite
@ -33,8 +31,9 @@ namespace RenderD7
float getHeigh(); float getHeigh();
float getPosX(); float getPosX();
float getPosY(); float getPosY();
private:
private:
C2D_ImageTint tint; C2D_ImageTint tint;
C2D_Sprite sprite; C2D_Sprite sprite;
}; };
} } // namespace RenderD7

View File

@ -1,25 +1,25 @@
#pragma once #pragma once
#include <renderd7/Sprite.hpp>
#include <renderd7/Sheet.hpp> #include <renderd7/Sheet.hpp>
#include <renderd7/Sprite.hpp>
#include <citro2d.h> #include <citro2d.h>
#include <citro3d.h> #include <citro3d.h>
namespace RenderD7 namespace RenderD7 {
{ class SpriteSheetAnimation : public RenderD7::Sprite {
class SpriteSheetAnimation : public RenderD7::Sprite public:
{
public:
SpriteSheetAnimation(); SpriteSheetAnimation();
~SpriteSheetAnimation(); ~SpriteSheetAnimation();
void Setup(RenderD7::Sheet *sheet, size_t imagecount, size_t startimage, float frame_begin, float frame_finish); void Setup(RenderD7::Sheet *sheet, size_t imagecount, size_t startimage,
float frame_begin, float frame_finish);
void Play(float timespeed); void Play(float timespeed);
private:
private:
size_t images; size_t images;
size_t imgs = 0; size_t imgs = 0;
float D_totaltime; float D_totaltime;
RenderD7::Sheet *sheet; RenderD7::Sheet *sheet;
float time; float time;
}; };
} } // namespace RenderD7

View File

@ -1,8 +1,7 @@
#pragma once #pragma once
#include <string> #include <string>
namespace RenderD7 namespace RenderD7 {
{ std::string FormatString(std::string fmt_str, ...);
std::string FormatString(std::string fmt_str, ...); std::string GetTimeStr(void);
std::string GetTimeStr(void); } // namespace RenderD7
}

View File

@ -1,23 +1,22 @@
#pragma once #pragma once
#include <renderd7/Ovl.hpp>
#include <renderd7/Image.hpp>
#include <renderd7/BitmapPrinter.hpp> #include <renderd7/BitmapPrinter.hpp>
#include <renderd7/Color.hpp> #include <renderd7/Color.hpp>
#include <renderd7/Image.hpp>
#include <renderd7/Ovl.hpp>
#include <renderd7/Screen.hpp> #include <renderd7/Screen.hpp>
namespace RenderD7 namespace RenderD7 {
{ class Toast : public RenderD7::Ovl {
class Toast : public RenderD7::Ovl public:
{
public:
Toast(std::string head, std::string msg); Toast(std::string head, std::string msg);
void Draw(void) const override; void Draw(void) const override;
void Logic() override; void Logic() override;
private:
private:
RenderD7::BitmapPrinter toast = RenderD7::BitmapPrinter(400, 70); RenderD7::BitmapPrinter toast = RenderD7::BitmapPrinter(400, 70);
RenderD7::Image *toastrendered; RenderD7::Image *toastrendered;
std::string head, msg; std::string head, msg;
int msgposy = 240; int msgposy = 240;
int delay = 0; int delay = 0;
}; };
} } // namespace RenderD7

View File

@ -1,45 +1,50 @@
#pragma once #pragma once
#include <fstream> #include <fstream>
#include <vector>
#include <stdexcept>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#include <sstream> #include <sstream>
#include <stdexcept>
#include <vector>
using namespace std; using namespace std;
#pragma pack(push, 1) #pragma pack(push, 1)
struct BMPFileHeader { struct BMPFileHeader {
uint16_t file_type{ 0x4D42 }; // File type always BM which is 0x4D42 (stored as hex uint16_t in little endian) uint16_t file_type{0x4D42}; // File type always BM which is 0x4D42 (stored as
uint32_t file_size{ 0 }; // Size of the file (in bytes) // hex uint16_t in little endian)
uint16_t reserved1{ 0 }; // Reserved, always 0 uint32_t file_size{0}; // Size of the file (in bytes)
uint16_t reserved2{ 0 }; // Reserved, always 0 uint16_t reserved1{0}; // Reserved, always 0
uint32_t offset_data{ 0 }; // Start position of pixel data (bytes from the beginning of the file) 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 { struct BMPInfoHeader {
uint32_t size{ 0 }; // Size of this header (in bytes) uint32_t size{0}; // Size of this header (in bytes)
int32_t width{ 0 }; // width of bitmap in pixels int32_t width{0}; // width of bitmap in pixels
int32_t height{ 0 }; // height of bitmap in pixels int32_t height{
0}; // height of bitmap in pixels
// (if positive, bottom-up, with origin in lower left corner) // (if positive, bottom-up, with origin in lower left corner)
// (if negative, top-down, with origin in upper 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 planes{1}; // No. of planes for the target device, this is always 1
uint16_t bit_count{ 0 }; // No. of bits per pixel 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 compression{0}; // 0 or 3 - uncompressed. THIS PROGRAM CONSIDERS ONLY
uint32_t size_image{ 0 }; // 0 - for uncompressed images // UNCOMPRESSED BMP images
int32_t x_pixels_per_meter{ 0 }; uint32_t size_image{0}; // 0 - for uncompressed images
int32_t y_pixels_per_meter{ 0 }; int32_t x_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 int32_t y_pixels_per_meter{0};
uint32_t colors_important{ 0 }; // No. of colors used for displaying the bitmap. If 0 all colors are required 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 { struct BMPColorHeader {
uint32_t red_mask{ 0x00ff0000 }; // Bit mask for the red channel uint32_t red_mask{0x00ff0000}; // Bit mask for the red channel
uint32_t green_mask{ 0x0000ff00 }; // Bit mask for the green 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 blue_mask{0x000000ff}; // Bit mask for the blue channel
uint32_t alpha_mask{ 0xff000000 }; // Bit mask for the alpha channel uint32_t alpha_mask{0xff000000}; // Bit mask for the alpha channel
uint32_t color_space_type{ 0x73524742 }; // Default "sRGB" (0x73524742) uint32_t color_space_type{0x73524742}; // Default "sRGB" (0x73524742)
uint32_t unused[16]{ 0 }; // Unused data for sRGB color space uint32_t unused[16]{0}; // Unused data for sRGB color space
}; };
#pragma pack(pop) #pragma pack(pop)
@ -49,31 +54,33 @@ struct BMP {
BMPColorHeader bmp_color_header; BMPColorHeader bmp_color_header;
std::vector<uint8_t> data; std::vector<uint8_t> data;
BMP(const char *fname) { read(fname); }
BMP(const char *fname) {
read(fname);
}
int read(const char *fname) { int read(const char *fname) {
std::ifstream inp{ fname, std::ios_base::binary }; std::ifstream inp{fname, std::ios_base::binary};
if (inp) { if (inp) {
inp.read((char*)&file_header, sizeof(file_header)); inp.read((char *)&file_header, sizeof(file_header));
if(file_header.file_type != 0x4D42) { if (file_header.file_type != 0x4D42) {
return 50;//throw std::runtime_error("Error! Unrecognized file format."); return 50; // throw std::runtime_error("Error! Unrecognized file
// format.");
} }
inp.read((char*)&bmp_info_header, sizeof(bmp_info_header)); inp.read((char *)&bmp_info_header, sizeof(bmp_info_header));
// The BMPColorHeader is used only for transparent images // The BMPColorHeader is used only for transparent images
if(bmp_info_header.bit_count == 32) { if (bmp_info_header.bit_count == 32) {
// Check if the file has bit mask color information // Check if the file has bit mask color information
if(bmp_info_header.size >= (sizeof(BMPInfoHeader) + sizeof(BMPColorHeader))) { if (bmp_info_header.size >=
inp.read((char*)&bmp_color_header, sizeof(bmp_color_header)); (sizeof(BMPInfoHeader) + sizeof(BMPColorHeader))) {
// Check if the pixel data is stored as BGRA and if the color space type is sRGB 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); check_color_header(bmp_color_header);
} else { } else {
//std::cerr << "Error! The file \"" << fname << "\" does not seem to contain bit mask information\n"; // std::cerr << "Error! The file \"" << fname << "\" does not seem to
return 51;//throw std::runtime_error("Error! Unrecognized file format."); // contain bit mask information\n";
return 51; // throw std::runtime_error("Error! Unrecognized file
// format.");
} }
} }
@ -81,10 +88,13 @@ struct BMP {
inp.seekg(file_header.offset_data, inp.beg); inp.seekg(file_header.offset_data, inp.beg);
// Adjust the header fields for output. // Adjust the header fields for output.
// Some editors will put extra info in the image file, we only save the headers and the data. // Some editors will put extra info in the image file, we only save the
if(bmp_info_header.bit_count == 32) { // headers and the data.
if (bmp_info_header.bit_count == 32) {
bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); file_header.offset_data = sizeof(BMPFileHeader) +
sizeof(BMPInfoHeader) +
sizeof(BMPColorHeader);
} else { } else {
bmp_info_header.size = sizeof(BMPInfoHeader); bmp_info_header.size = sizeof(BMPInfoHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader); file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader);
@ -92,55 +102,64 @@ struct BMP {
file_header.file_size = file_header.offset_data; file_header.file_size = file_header.offset_data;
if (bmp_info_header.height < 0) { 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!"); 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); 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 // Here we check if we need to take into account row padding
if (bmp_info_header.width % 4 == 0) { if (bmp_info_header.width % 4 == 0) {
inp.read((char*)data.data(), data.size()); inp.read((char *)data.data(), data.size());
file_header.file_size += static_cast<uint32_t>(data.size()); file_header.file_size += static_cast<uint32_t>(data.size());
} } else {
else {
row_stride = bmp_info_header.width * bmp_info_header.bit_count / 8; row_stride = bmp_info_header.width * bmp_info_header.bit_count / 8;
uint32_t new_stride = make_stride_aligned(4); uint32_t new_stride = make_stride_aligned(4);
std::vector<uint8_t> padding_row(new_stride - row_stride); std::vector<uint8_t> padding_row(new_stride - row_stride);
for (int y = 0; y < bmp_info_header.height; ++y) { for (int y = 0; y < bmp_info_header.height; ++y) {
inp.read((char*)(data.data() + row_stride * y), row_stride); inp.read((char *)(data.data() + row_stride * y), row_stride);
inp.read((char*)padding_row.data(), padding_row.size()); inp.read((char *)padding_row.data(), padding_row.size());
} }
file_header.file_size += static_cast<uint32_t>(data.size()) + bmp_info_header.height * static_cast<uint32_t>(padding_row.size()); file_header.file_size +=
static_cast<uint32_t>(data.size()) +
bmp_info_header.height * static_cast<uint32_t>(padding_row.size());
} }
} } else {
else { return 53; // throw std::runtime_error("Unable to open the input image
return 53;//throw std::runtime_error("Unable to open the input image file "+std::string(fname)); // file "+std::string(fname));
} }
return 0; return 0;
} }
int read_mem(std::vector<unsigned char> buffer) { int read_mem(std::vector<unsigned char> buffer) {
std::stringstream inp; std::stringstream inp;
std::copy(buffer.begin(), buffer.end(),std::ostream_iterator<unsigned char>(inp,"\n")); std::copy(buffer.begin(), buffer.end(),
std::ostream_iterator<unsigned char>(inp, "\n"));
if (inp) { if (inp) {
inp.read((char*)&file_header, sizeof(file_header)); inp.read((char *)&file_header, sizeof(file_header));
if(file_header.file_type != 0x4D42) { if (file_header.file_type != 0x4D42) {
return 50;//throw std::runtime_error("Error! Unrecognized file format."); return 50; // throw std::runtime_error("Error! Unrecognized file
// format.");
} }
inp.read((char*)&bmp_info_header, sizeof(bmp_info_header)); inp.read((char *)&bmp_info_header, sizeof(bmp_info_header));
// The BMPColorHeader is used only for transparent images // The BMPColorHeader is used only for transparent images
if(bmp_info_header.bit_count == 32) { if (bmp_info_header.bit_count == 32) {
// Check if the file has bit mask color information // Check if the file has bit mask color information
if(bmp_info_header.size >= (sizeof(BMPInfoHeader) + sizeof(BMPColorHeader))) { if (bmp_info_header.size >=
inp.read((char*)&bmp_color_header, sizeof(bmp_color_header)); (sizeof(BMPInfoHeader) + sizeof(BMPColorHeader))) {
// Check if the pixel data is stored as BGRA and if the color space type is sRGB 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); check_color_header(bmp_color_header);
} else { } else {
//std::cerr << "Error! The file \"" << fname << "\" does not seem to contain bit mask information\n"; // std::cerr << "Error! The file \"" << fname << "\" does not seem to
return 51;//throw std::runtime_error("Error! Unrecognized file format."); // contain bit mask information\n";
return 51; // throw std::runtime_error("Error! Unrecognized file
// format.");
} }
} }
@ -148,10 +167,13 @@ struct BMP {
inp.seekg(file_header.offset_data, inp.beg); inp.seekg(file_header.offset_data, inp.beg);
// Adjust the header fields for output. // Adjust the header fields for output.
// Some editors will put extra info in the image file, we only save the headers and the data. // Some editors will put extra info in the image file, we only save the
if(bmp_info_header.bit_count == 32) { // headers and the data.
if (bmp_info_header.bit_count == 32) {
bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); file_header.offset_data = sizeof(BMPFileHeader) +
sizeof(BMPInfoHeader) +
sizeof(BMPColorHeader);
} else { } else {
bmp_info_header.size = sizeof(BMPInfoHeader); bmp_info_header.size = sizeof(BMPInfoHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader); file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader);
@ -159,30 +181,33 @@ struct BMP {
file_header.file_size = file_header.offset_data; file_header.file_size = file_header.offset_data;
if (bmp_info_header.height < 0) { 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!"); 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); 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 // Here we check if we need to take into account row padding
if (bmp_info_header.width % 4 == 0) { if (bmp_info_header.width % 4 == 0) {
inp.read((char*)data.data(), data.size()); inp.read((char *)data.data(), data.size());
file_header.file_size += static_cast<uint32_t>(data.size()); file_header.file_size += static_cast<uint32_t>(data.size());
} } else {
else {
row_stride = bmp_info_header.width * bmp_info_header.bit_count / 8; row_stride = bmp_info_header.width * bmp_info_header.bit_count / 8;
uint32_t new_stride = make_stride_aligned(4); uint32_t new_stride = make_stride_aligned(4);
std::vector<uint8_t> padding_row(new_stride - row_stride); std::vector<uint8_t> padding_row(new_stride - row_stride);
for (int y = 0; y < bmp_info_header.height; ++y) { for (int y = 0; y < bmp_info_header.height; ++y) {
inp.read((char*)(data.data() + row_stride * y), row_stride); inp.read((char *)(data.data() + row_stride * y), row_stride);
inp.read((char*)padding_row.data(), padding_row.size()); inp.read((char *)padding_row.data(), padding_row.size());
} }
file_header.file_size += static_cast<uint32_t>(data.size()) + bmp_info_header.height * static_cast<uint32_t>(padding_row.size()); file_header.file_size +=
static_cast<uint32_t>(data.size()) +
bmp_info_header.height * static_cast<uint32_t>(padding_row.size());
} }
} } else {
else { return 53; // throw std::runtime_error("Unable to open the input image
return 53;//throw std::runtime_error("Unable to open the input image file "+std::string(fname)); // file "+std::string(fname));
} }
return 0; return 0;
} }
@ -197,15 +222,15 @@ struct BMP {
bmp_info_header.height = height; bmp_info_header.height = height;
if (has_alpha) { if (has_alpha) {
bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); bmp_info_header.size = sizeof(BMPInfoHeader) + sizeof(BMPColorHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + sizeof(BMPColorHeader); file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) +
sizeof(BMPColorHeader);
bmp_info_header.bit_count = 32; bmp_info_header.bit_count = 32;
bmp_info_header.compression = 3; bmp_info_header.compression = 3;
row_stride = width * 4; row_stride = width * 4;
data.resize(row_stride * height); data.resize(row_stride * height);
file_header.file_size = file_header.offset_data + data.size(); file_header.file_size = file_header.offset_data + data.size();
} } else {
else {
bmp_info_header.size = sizeof(BMPInfoHeader); bmp_info_header.size = sizeof(BMPInfoHeader);
file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader); file_header.offset_data = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader);
@ -215,41 +240,40 @@ struct BMP {
data.resize(row_stride * height); data.resize(row_stride * height);
uint32_t new_stride = make_stride_aligned(4); uint32_t new_stride = make_stride_aligned(4);
file_header.file_size = file_header.offset_data + static_cast<uint32_t>(data.size()) + bmp_info_header.height * (new_stride - row_stride); file_header.file_size =
file_header.offset_data + static_cast<uint32_t>(data.size()) +
bmp_info_header.height * (new_stride - row_stride);
} }
} }
unsigned write(const char *fname) { unsigned write(const char *fname) {
std::ofstream of{ fname, std::ios_base::binary }; std::ofstream of{fname, std::ios_base::binary};
if (of) { if (of) {
if (bmp_info_header.bit_count == 32) { if (bmp_info_header.bit_count == 32) {
write_headers_and_data(of); write_headers_and_data(of);
} } else if (bmp_info_header.bit_count == 24) {
else if (bmp_info_header.bit_count == 24) {
if (bmp_info_header.width % 4 == 0) { if (bmp_info_header.width % 4 == 0) {
write_headers_and_data(of); write_headers_and_data(of);
} } else {
else {
uint32_t new_stride = make_stride_aligned(4); uint32_t new_stride = make_stride_aligned(4);
std::vector<uint8_t> padding_row(new_stride - row_stride); std::vector<uint8_t> padding_row(new_stride - row_stride);
write_headers(of); write_headers(of);
for (int y = 0; y < bmp_info_header.height; ++y) { 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 *)(data.data() + row_stride * y), row_stride);
of.write((const char*)padding_row.data(), padding_row.size()); 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 { } else {
return 54;//throw std::runtime_error("The program can treat only 24 or 32 bits per pixel BMP files"); return 55; // throw std::runtime_error("Unable to open the output image
} // file.");
}
else {
return 55;//throw std::runtime_error("Unable to open the output image file.");
} }
return 0; return 0;
} }
std::vector<unsigned char> DATA() { std::vector<unsigned char> DATA() {
@ -257,44 +281,39 @@ struct BMP {
if (ss) { if (ss) {
if (bmp_info_header.bit_count == 32) { if (bmp_info_header.bit_count == 32) {
write_headers_and_datass(ss); write_headers_and_datass(ss);
} } else if (bmp_info_header.bit_count == 24) {
else if (bmp_info_header.bit_count == 24) {
if (bmp_info_header.width % 4 == 0) { if (bmp_info_header.width % 4 == 0) {
write_headers_and_datass(ss); write_headers_and_datass(ss);
} } else {
else {
uint32_t new_stride = make_stride_aligned(4); uint32_t new_stride = make_stride_aligned(4);
std::vector<uint8_t> padding_row(new_stride - row_stride); std::vector<uint8_t> padding_row(new_stride - row_stride);
write_headersss(ss); write_headersss(ss);
for (int y = 0; y < bmp_info_header.height; ++y) { 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 *)(data.data() + row_stride * y), row_stride);
ss.write((const char*)padding_row.data(), padding_row.size()); ss.write((const char *)padding_row.data(), padding_row.size());
} }
} }
} else {
} }
else { } else {
}
}
else {
} }
std::string test11 = ss.str(); std::string test11 = ss.str();
std::vector<unsigned char> test12(test11.begin(), test11.end()); std::vector<unsigned char> test12(test11.begin(), test11.end());
return test12; 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) { 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; uint32_t channels = bmp_info_header.bit_count / 8;
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { 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) { /*if (x + w > (uint32_t)bmp_info_header.width || y + h >
(uint32_t)bmp_info_header.height) {
// //
}*/ }*/
//else{ // else{
data[channels * (y * bmp_info_header.width + x) + 0] = B; 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) + 1] = G;
data[channels * (y * bmp_info_header.width + x) + 2] = R; data[channels * (y * bmp_info_header.width + x) + 2] = R;
@ -307,7 +326,8 @@ struct BMP {
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) { 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 x0 = x1;
int y0 = this->bmp_info_header.height - y1 - h; int y0 = this->bmp_info_header.height - y1 - h;
@ -315,7 +335,8 @@ struct BMP {
uint32_t channels = bmp_info_header.bit_count / 8; uint32_t channels = bmp_info_header.bit_count / 8;
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { 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) { 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) + 0] = B;
data[channels * (y * bmp_info_header.width + x) + 1] = G; data[channels * (y * bmp_info_header.width + x) + 1] = G;
@ -328,7 +349,8 @@ struct BMP {
} }
} }
void manipulate_region(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint8_t A) { void manipulate_region(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h,
uint8_t A) {
int choice, choice2, intensity; int choice, choice2, intensity;
cout << "What color do you want to change? " << endl; cout << "What color do you want to change? " << endl;
cout << "Enter 1 for Blue, 2 for Green, 3 for Red " << endl; cout << "Enter 1 for Blue, 2 for Green, 3 for Red " << endl;
@ -338,40 +360,40 @@ struct BMP {
cin >> choice2; cin >> choice2;
cout << "Enter the intensity of the color. (From 0 to 255) " << endl; cout << "Enter the intensity of the color. (From 0 to 255) " << endl;
cin >> intensity; cin >> intensity;
if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) { if (x0 + w > (uint32_t)bmp_info_header.width ||
return;//throw std::runtime_error("The region does not fit in the image!"); 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; uint32_t channels = bmp_info_header.bit_count / 8;
if (choice==1 && choice2==1) if (choice == 1 && choice2 == 1) {
{
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl; cout << channels * (y * bmp_info_header.width + x) << endl;
//Make blue thing blue // 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) 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) + 0] = intensity;
data[channels * (y * bmp_info_header.width + x) + 1] = 0; 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) + 2] = 0;
} }
//data[channels * (y * bmp_info_header.width + x) + 0] = B; // 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) + 1] = G;
//data[channels * (y * bmp_info_header.width + x) + 2] = R; // data[channels * (y * bmp_info_header.width + x) + 2] = R;
if (channels == 4) { if (channels == 4) {
data[channels * (y * bmp_info_header.width + x) + 3] = A; data[channels * (y * bmp_info_header.width + x) + 3] = A;
} }
} }
} }
} }
if (choice == 1 && choice2==2) if (choice == 1 && choice2 == 2) {
{
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl; cout << channels * (y * bmp_info_header.width + x) << endl;
//Make blue thing green // 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) 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) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = intensity; data[channels * (y * bmp_info_header.width + x) + 1] = intensity;
data[channels * (y * bmp_info_header.width + x) + 2] = 0; data[channels * (y * bmp_info_header.width + x) + 2] = 0;
@ -382,14 +404,13 @@ struct BMP {
} }
} }
} }
if (choice == 1 && choice2==3) if (choice == 1 && choice2 == 3) {
{
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl; cout << channels * (y * bmp_info_header.width + x) << endl;
//Make blue thing red // 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) 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) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = 0; data[channels * (y * bmp_info_header.width + x) + 1] = 0;
data[channels * (y * bmp_info_header.width + x) + 2] = intensity; data[channels * (y * bmp_info_header.width + x) + 2] = intensity;
@ -400,14 +421,13 @@ struct BMP {
} }
} }
} }
if (choice == 2 && choice2==1) if (choice == 2 && choice2 == 1) {
{
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl; cout << channels * (y * bmp_info_header.width + x) << endl;
//Make green thing blue // 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) 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) + 0] = intensity;
data[channels * (y * bmp_info_header.width + x) + 1] = 0; 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) + 2] = 0;
@ -418,14 +438,13 @@ struct BMP {
} }
} }
} }
if (choice == 2 && choice2==2) if (choice == 2 && choice2 == 2) {
{
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl; cout << channels * (y * bmp_info_header.width + x) << endl;
//Make green thing green // 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) 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) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = intensity; data[channels * (y * bmp_info_header.width + x) + 1] = intensity;
data[channels * (y * bmp_info_header.width + x) + 2] = 0; data[channels * (y * bmp_info_header.width + x) + 2] = 0;
@ -436,14 +455,13 @@ struct BMP {
} }
} }
} }
if (choice == 2 && choice2==3) if (choice == 2 && choice2 == 3) {
{
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl; cout << channels * (y * bmp_info_header.width + x) << endl;
//Make green thing red // 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) 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) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = 0; data[channels * (y * bmp_info_header.width + x) + 1] = 0;
data[channels * (y * bmp_info_header.width + x) + 2] = intensity; data[channels * (y * bmp_info_header.width + x) + 2] = intensity;
@ -454,14 +472,13 @@ struct BMP {
} }
} }
} }
if (choice == 3 && choice2==1) if (choice == 3 && choice2 == 1) {
{
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl; cout << channels * (y * bmp_info_header.width + x) << endl;
//Make red thing blue // 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) 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) + 0] = intensity;
data[channels * (y * bmp_info_header.width + x) + 1] = 0; 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) + 2] = 0;
@ -472,14 +489,13 @@ struct BMP {
} }
} }
} }
if (choice == 3 && choice2==2) if (choice == 3 && choice2 == 2) {
{
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl; cout << channels * (y * bmp_info_header.width + x) << endl;
//Make red thing green // 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) 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) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = intensity; data[channels * (y * bmp_info_header.width + x) + 1] = intensity;
data[channels * (y * bmp_info_header.width + x) + 2] = 0; data[channels * (y * bmp_info_header.width + x) + 2] = 0;
@ -490,14 +506,13 @@ struct BMP {
} }
} }
} }
if (choice == 3 && choice2==3) if (choice == 3 && choice2 == 3) {
{
for (uint32_t y = y0; y < y0 + h; ++y) { for (uint32_t y = y0; y < y0 + h; ++y) {
for (uint32_t x = x0; x < x0 + w; ++x) { for (uint32_t x = x0; x < x0 + w; ++x) {
cout << channels*(y*bmp_info_header.width+x) << endl; cout << channels * (y * bmp_info_header.width + x) << endl;
//Make red thing blue // 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) 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) + 0] = 0;
data[channels * (y * bmp_info_header.width + x) + 1] = 0; data[channels * (y * bmp_info_header.width + x) + 1] = 0;
data[channels * (y * bmp_info_header.width + x) + 2] = intensity; data[channels * (y * bmp_info_header.width + x) + 2] = intensity;
@ -508,111 +523,110 @@ struct BMP {
} }
} }
} }
} }
int OrganizeAverageRed() int OrganizeAverageRed() {
{
int ColorRed[bmp_info_header.height][bmp_info_header.width]; int ColorRed[bmp_info_header.height][bmp_info_header.width];
int ColorGreen[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]; int ColorBlue[bmp_info_header.height][bmp_info_header.width];
float pixels=bmp_info_header.height*bmp_info_header.width; float pixels = bmp_info_header.height * bmp_info_header.width;
float intensity=0; float intensity = 0;
float sum=0; float sum = 0;
uint32_t channels = bmp_info_header.bit_count / 8; uint32_t channels = bmp_info_header.bit_count / 8;
cout << "The Width of the image is " << bmp_info_header.width << endl; cout << "The Width of the image is " << bmp_info_header.width << endl;
cout << "The height of the image is " << bmp_info_header.height << 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 y = 0; y < bmp_info_header.height; ++y) {
for (int x = 0; x < bmp_info_header.width; ++x) { for (int x = 0; x < bmp_info_header.width; ++x) {
//cout << channels*(y*bmp_info_header.width+x) << endl; // cout << channels*(y*bmp_info_header.width+x) << endl;
//Read red // Read red
ColorBlue[y][x]=data[channels * (y * bmp_info_header.width + x) + 0]; ColorBlue[y][x] = data[channels * (y * bmp_info_header.width + x) + 0];
ColorGreen[y][x]=data[channels * (y * bmp_info_header.width + x) + 1]; ColorGreen[y][x] = data[channels * (y * bmp_info_header.width + x) + 1];
ColorRed[y][x]=data[channels * (y * bmp_info_header.width + x) + 2]; ColorRed[y][x] = data[channels * (y * bmp_info_header.width + x) + 2];
} }
} }
for(int y=0; y<bmp_info_header.height; y++) for (int y = 0; y < bmp_info_header.height; y++) {
{ for (int x = 0; x < bmp_info_header.width; x++) {
for(int x=0; x<bmp_info_header.width; x++) sum = ColorRed[y][x] + sum -
{ ((ColorBlue[y][x]) / 2 + (ColorGreen[y][x]) / 2);
sum=ColorRed[y][x]+sum-((ColorBlue[y][x])/2+(ColorGreen[y][x])/2);
} }
} }
intensity=sum/pixels; intensity = sum / pixels;
cout << intensity << endl; cout << intensity << endl;
return intensity; return intensity;
} }
int OrganizeAverageGreen() int OrganizeAverageGreen() {
{
int ColorRed[bmp_info_header.height][bmp_info_header.width]; int ColorRed[bmp_info_header.height][bmp_info_header.width];
int ColorGreen[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]; int ColorBlue[bmp_info_header.height][bmp_info_header.width];
float pixels=bmp_info_header.height*bmp_info_header.width; float pixels = bmp_info_header.height * bmp_info_header.width;
float intensity=0; float intensity = 0;
float sum=0; float sum = 0;
uint32_t channels = bmp_info_header.bit_count / 8; uint32_t channels = bmp_info_header.bit_count / 8;
cout << "The Width of the image is " << bmp_info_header.width << endl; cout << "The Width of the image is " << bmp_info_header.width << endl;
cout << "The height of the image is " << bmp_info_header.height << 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 y = 0; y < bmp_info_header.height; ++y) {
for (int x = 0; x < bmp_info_header.width; ++x) { for (int x = 0; x < bmp_info_header.width; ++x) {
//cout << channels*(y*bmp_info_header.width+x) << endl; // cout << channels*(y*bmp_info_header.width+x) << endl;
//Read Green // Read Green
ColorBlue[y][x]=data[channels * (y * bmp_info_header.width + x) + 0]; ColorBlue[y][x] = data[channels * (y * bmp_info_header.width + x) + 0];
ColorGreen[y][x]=data[channels * (y * bmp_info_header.width + x) + 1]; ColorGreen[y][x] = data[channels * (y * bmp_info_header.width + x) + 1];
ColorRed[y][x]=data[channels * (y * bmp_info_header.width + x) + 2]; ColorRed[y][x] = data[channels * (y * bmp_info_header.width + x) + 2];
} }
} }
for(int y=0; y<bmp_info_header.height; y++) for (int y = 0; y < bmp_info_header.height; y++) {
{ for (int x = 0; x < bmp_info_header.width; x++) {
for(int x=0; x<bmp_info_header.width; x++) sum = ColorGreen[y][x] + sum -
{ ((ColorBlue[y][x]) / 2 + (ColorRed[y][x]) / 2);
sum=ColorGreen[y][x]+sum-((ColorBlue[y][x])/2+(ColorRed[y][x])/2);
} }
} }
intensity=sum/pixels; intensity = sum / pixels;
cout << intensity << endl; cout << intensity << endl;
return intensity; return intensity;
} }
int OrganizeAverageBlue() int OrganizeAverageBlue() {
{
int ColorRed[bmp_info_header.height][bmp_info_header.width]; int ColorRed[bmp_info_header.height][bmp_info_header.width];
int ColorGreen[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]; int ColorBlue[bmp_info_header.height][bmp_info_header.width];
float pixels=bmp_info_header.height*bmp_info_header.width; float pixels = bmp_info_header.height * bmp_info_header.width;
float intensity=0; float intensity = 0;
float sum=0; float sum = 0;
uint32_t channels = bmp_info_header.bit_count / 8; uint32_t channels = bmp_info_header.bit_count / 8;
cout << "The Width of the image is " << bmp_info_header.width << endl; cout << "The Width of the image is " << bmp_info_header.width << endl;
cout << "The height of the image is " << bmp_info_header.height << 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 y = 0; y < bmp_info_header.height; ++y) {
for (int x = 0; x < bmp_info_header.width; ++x) { for (int x = 0; x < bmp_info_header.width; ++x) {
//cout << channels*(y*bmp_info_header.width+x) << endl; // cout << channels*(y*bmp_info_header.width+x) << endl;
//Read Blue // Read Blue
ColorBlue[y][x]=data[channels * (y * bmp_info_header.width + x) + 0]; ColorBlue[y][x] = data[channels * (y * bmp_info_header.width + x) + 0];
ColorGreen[y][x]=data[channels * (y * bmp_info_header.width + x) + 1]; ColorGreen[y][x] = data[channels * (y * bmp_info_header.width + x) + 1];
ColorRed[y][x]=data[channels * (y * bmp_info_header.width + x) + 2]; ColorRed[y][x] = data[channels * (y * bmp_info_header.width + x) + 2];
} }
} }
for(int y=0; y<bmp_info_header.height; y++) for (int y = 0; y < bmp_info_header.height; y++) {
{ for (int x = 0; x < bmp_info_header.width; x++) {
for(int x=0; x<bmp_info_header.width; x++) sum = ColorBlue[y][x] + sum -
{ ((ColorGreen[y][x]) / 2 + (ColorRed[y][x]) / 2);
sum=ColorBlue[y][x]+sum-((ColorGreen[y][x])/2+(ColorRed[y][x])/2);
} }
} }
intensity=sum/pixels; intensity = sum / pixels;
cout << intensity << endl; cout << intensity << endl;
return intensity; return intensity;
} }
unsigned set_pixel(uint32_t x0, uint32_t y0, uint8_t B, uint8_t G, uint8_t R, uint8_t A) { unsigned set_pixel(uint32_t x0, uint32_t y0, uint8_t B, uint8_t G, uint8_t R,
if (x0 >= (uint32_t)bmp_info_header.width || y0 >= (uint32_t)bmp_info_header.height || x0 < 0 || y0 < 0) { uint8_t A) {
return 59;//throw std::runtime_error("The point is outside the image boundaries!"); 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; 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) + 0] = B;
@ -624,10 +638,13 @@ struct BMP {
return 0; return 0;
} }
void set_pixel_df(uint32_t x0, uint32_t y0, uint8_t B, uint8_t G, uint8_t R, uint8_t A) { 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; 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) { if (x0 >= (uint32_t)bmp_info_header.width ||
return;//throw std::runtime_error("The point is outside the image boundaries!"); 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; uint32_t channels = bmp_info_header.bit_count / 8;
@ -640,57 +657,67 @@ struct BMP {
} }
unsigned draw_rectangle(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, 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) { uint8_t B, uint8_t G, uint8_t R, uint8_t A,
if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) { uint8_t line_w) {
return 59;//throw std::runtime_error("The rectangle does not fit in the image!"); 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, 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, (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 + w - line_w), (y0 + line_w), line_w, (h - (2 * line_w)), B,
fill_region(x0, (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // left line 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; return 0;
} }
void draw_rectangle_df(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, 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) { uint8_t B, uint8_t G, uint8_t R, uint8_t A,
if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) { uint8_t line_w) {
return;//throw std::runtime_error("The rectangle does not fit in the image!"); 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, 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, (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 + w - line_w), (y0 + line_w), line_w, (h - (2 * line_w)),
fill_region_df(x0, (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // left line 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: private:
uint32_t row_stride{ 0 }; uint32_t row_stride{0};
void write_headers(std::ofstream &of) { void write_headers(std::ofstream &of) {
of.write((const char*)&file_header, sizeof(file_header)); of.write((const char *)&file_header, sizeof(file_header));
of.write((const char*)&bmp_info_header, sizeof(bmp_info_header)); of.write((const char *)&bmp_info_header, sizeof(bmp_info_header));
if(bmp_info_header.bit_count == 32) { if (bmp_info_header.bit_count == 32) {
of.write((const char*)&bmp_color_header, sizeof(bmp_color_header)); of.write((const char *)&bmp_color_header, sizeof(bmp_color_header));
} }
} }
void write_headers_and_data(std::ofstream &of) { void write_headers_and_data(std::ofstream &of) {
write_headers(of); write_headers(of);
of.write((const char*)data.data(), data.size()); of.write((const char *)data.data(), data.size());
} }
void write_headersss(std::stringstream &of) { void write_headersss(std::stringstream &of) {
of.write((const char*)&file_header, sizeof(file_header)); of.write((const char *)&file_header, sizeof(file_header));
of.write((const char*)&bmp_info_header, sizeof(bmp_info_header)); of.write((const char *)&bmp_info_header, sizeof(bmp_info_header));
if(bmp_info_header.bit_count == 32) { if (bmp_info_header.bit_count == 32) {
of.write((const char*)&bmp_color_header, sizeof(bmp_color_header)); of.write((const char *)&bmp_color_header, sizeof(bmp_color_header));
} }
} }
void write_headers_and_datass(std::stringstream &of) { void write_headers_and_datass(std::stringstream &of) {
write_headersss(of); write_headersss(of);
of.write((const char*)data.data(), data.size()); of.write((const char *)data.data(), data.size());
} }
// Add 1 to the row_stride until it is divisible with align_stride // Add 1 to the row_stride until it is divisible with align_stride
@ -702,17 +729,21 @@ private:
return new_stride; return new_stride;
} }
// Check if the pixel data is stored as BGRA and if the color space type is sRGB // 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) { void check_color_header(BMPColorHeader &bmp_color_header) {
BMPColorHeader expected_color_header; BMPColorHeader expected_color_header;
if(expected_color_header.red_mask != bmp_color_header.red_mask || if (expected_color_header.red_mask != bmp_color_header.red_mask ||
expected_color_header.blue_mask != bmp_color_header.blue_mask || expected_color_header.blue_mask != bmp_color_header.blue_mask ||
expected_color_header.green_mask != bmp_color_header.green_mask || expected_color_header.green_mask != bmp_color_header.green_mask ||
expected_color_header.alpha_mask != bmp_color_header.alpha_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"); 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) { if (expected_color_header.color_space_type !=
return;//throw std::runtime_error("Unexpected color space type! The program expects sRGB values"); bmp_color_header.color_space_type) {
return; // throw std::runtime_error("Unexpected color space type! The
// program expects sRGB values");
} }
} }
}; };

View File

@ -3,12 +3,14 @@
#include <iostream> #include <iostream>
namespace BitmapConverter{ namespace BitmapConverter {
//returns 0 if all went ok, non-0 if error // 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 // output image is always given in RGBA (with alpha channel), even if it's a BMP
unsigned decodeBMP(std::vector<unsigned char>& image, unsigned& w, unsigned& h, const std::vector<unsigned char>& bmp); // without alpha channel
unsigned decodeBMP(std::vector<unsigned char> &image, unsigned &w, unsigned &h,
const std::vector<unsigned char> &bmp);
std::vector<unsigned char> ConvertFile(std::string filename); std::vector<unsigned char> ConvertFile(std::string filename);
std::vector<unsigned char> ConvertData(std::vector<unsigned char> data); std::vector<unsigned char> ConvertData(std::vector<unsigned char> data);
} } // namespace BitmapConverter

View File

@ -8,134 +8,177 @@ Visit http://www.devkitpro.org
#define _debugfont_h_ #define _debugfont_h_
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
static const unsigned char debugfont[] = { static const unsigned char debugfont[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81,
0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0xbd, 0x99, 0x81, 0x7e, 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e,
0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x3c, 0x3c, 0x18, 0xff, 0xe7, 0x18, 0x3c, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x10, 0x38, 0x7c, 0xfe,
0x10, 0x38, 0x7c, 0xfe, 0xee, 0x10, 0x38, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x7c, 0x38, 0x10, 0x00, 0x3c, 0x3c, 0x18, 0xff, 0xe7, 0x18, 0x3c, 0x00,
0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0xee, 0x10, 0x38, 0x00, 0x00, 0x00, 0x18, 0x3c,
0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, 0x3c, 0x18, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff,
0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x08, 0x0c, 0x0a, 0x0a, 0x08, 0x78, 0xf0, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0xff, 0xc3, 0x99, 0xbd,
0x18, 0x14, 0x1a, 0x16, 0x72, 0xe2, 0x0e, 0x1c, 0x10, 0x54, 0x38, 0xee, 0x38, 0x54, 0x10, 0x00, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x08, 0x0c, 0x0a, 0x0a,
0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, 0x08, 0x78, 0xf0, 0x00, 0x18, 0x14, 0x1a, 0x16, 0x72, 0xe2, 0x0e, 0x1c,
0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x00, 0x1c, 0x22, 0x38, 0x44, 0x44, 0x38, 0x88, 0x70, 0x10, 0x54, 0x38, 0xee, 0x38, 0x54, 0x10, 0x00, 0x80, 0xe0, 0xf8, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x7e, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
0x18, 0x3c, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x5a, 0x3c, 0x18, 0x00, 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x66,
0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x66, 0x00, 0x66, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x00,
0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x42, 0xff, 0x42, 0x24, 0x00, 0x00, 0x1c, 0x22, 0x38, 0x44, 0x44, 0x38, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x7e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, 0x18, 0x3c, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18,
0x6c, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x5a, 0x3c, 0x18, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00,
0x10, 0x7c, 0xd0, 0x7c, 0x16, 0xfc, 0x10, 0x00, 0x00, 0x66, 0xac, 0xd8, 0x36, 0x6a, 0xcc, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
0x38, 0x4c, 0x38, 0x78, 0xce, 0xcc, 0x7a, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x42, 0xff, 0x42, 0x24, 0x00, 0x00,
0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c,
0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, 0x6c, 0x24, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
0x7c, 0xce, 0xde, 0xf6, 0xe6, 0xe6, 0x7c, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x10, 0x7c, 0xd0, 0x7c, 0x16, 0xfc, 0x10, 0x00, 0x00, 0x66, 0xac, 0xd8,
0x7c, 0xc6, 0x06, 0x1c, 0x70, 0xc6, 0xfe, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x36, 0x6a, 0xcc, 0x00, 0x38, 0x4c, 0x38, 0x78, 0xce, 0xcc, 0x7a, 0x00,
0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfe, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x60,
0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00, 0xfe, 0xc6, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc,
0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20,
0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00,
0x7c, 0x82, 0x9e, 0xa6, 0x9e, 0x80, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x7c, 0xce, 0xde, 0xf6, 0xe6, 0xe6, 0x7c, 0x00, 0x18, 0x38, 0x78, 0x18,
0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x18, 0x18, 0x7e, 0x00, 0x7c, 0xc6, 0x06, 0x1c, 0x70, 0xc6, 0xfe, 0x00,
0xfc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x1c, 0x3c, 0x6c, 0xcc,
0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xce, 0xc6, 0x7e, 0x00, 0xfe, 0x0c, 0x1e, 0x00, 0xfe, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00,
0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00, 0xfe, 0xc6, 0x0c, 0x18,
0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x30, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00,
0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x82, 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x30, 0x00, 0x00,
0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20,
0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x7e, 0x00,
0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0xc6, 0xc0, 0x7c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00,
0x7e, 0x5a, 0x5a, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, 0x7c, 0x82, 0x9e, 0xa6,
0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x82, 0x00, 0x9e, 0x80, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00,
0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x7c, 0xc6, 0xc0, 0xc0,
0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, 0xc0, 0xc6, 0x7c, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00,
0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0xfe, 0x62, 0x68, 0x78,
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x68, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xce, 0xc6, 0x7e, 0x00,
0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x3c, 0x18, 0x18, 0x18,
0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x00, 0x18, 0x18, 0x3c, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00,
0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0xf0, 0x60, 0x60, 0x60,
0x1c, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x78, 0x62, 0x66, 0xfe, 0x00, 0x82, 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6,
0x00, 0x0c, 0x00, 0x1c, 0x0c, 0x0c, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, 0xc6, 0xc6, 0x7c, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xd6, 0xd6, 0xd6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x06, 0xfc, 0x66, 0x66, 0x7c,
0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0xc6, 0xc0, 0x7c, 0x06, 0xc6, 0x7c, 0x00,
0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, 0x7e, 0x5a, 0x5a, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6,
0x00, 0x00, 0xde, 0x76, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x7c, 0x06, 0x7c, 0x00, 0xc6, 0xc6, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00,
0x10, 0x30, 0xfc, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x82, 0x00, 0xc6, 0x6c, 0x38, 0x38,
0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x38, 0x6c, 0xc6, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60,
0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x0e, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0e, 0x00, 0x60, 0x60, 0x78, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00,
0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xe0, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0x10, 0x38, 0x6c, 0xc6,
0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x70, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c,
0x0e, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x7c, 0x82, 0x38, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x00, 0x1c, 0x0c, 0x0c, 0x7c,
0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0xc0, 0x7c, 0x18, 0x70, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
0x7c, 0x82, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x1c, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x76, 0xcc,
0xe0, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xcc, 0x7c, 0x0c, 0x78, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00,
0x7c, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x0c, 0x00, 0x1c,
0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x38, 0x38, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x0c, 0x0c, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
0x0e, 0x10, 0xfe, 0x60, 0x78, 0x60, 0xfe, 0x00, 0x00, 0x00, 0x7c, 0x12, 0x7e, 0xd0, 0x7e, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0xcc, 0xfe,
0x7e, 0xc8, 0xc8, 0xfe, 0xc8, 0xc8, 0xce, 0x00, 0x7c, 0x82, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00,
0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0xe0, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xdc, 0x66,
0x7c, 0x82, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0xde, 0x76, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0,
0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x18, 0x7c, 0xd6, 0xd0, 0xd6, 0x7c, 0x18, 0x00, 0x7c, 0x06, 0x7c, 0x00, 0x10, 0x30, 0xfc, 0x30, 0x30, 0x34, 0x18, 0x00,
0x38, 0x6c, 0x60, 0xf0, 0x60, 0xf2, 0xdc, 0x00, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0xc6, 0xc6,
0xf8, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0x06, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00,
0x0e, 0x10, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x0e, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc,
0x0e, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x0e, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0xcc, 0x7c, 0x0c, 0xf8, 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00,
0x66, 0x98, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x98, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00, 0x0e, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0e, 0x00, 0x18, 0x18, 0x18, 0x00,
0x38, 0x0c, 0x3c, 0x34, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xe0, 0x00,
0x30, 0x00, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc0, 0xc8, 0xd0, 0xfe, 0x46, 0x8c, 0x1e, 0x00, 0xc6, 0xc6, 0xfe, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x70,
0xc0, 0xc8, 0xd0, 0xec, 0x5c, 0xbe, 0x0c, 0x00, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x0e, 0x10, 0x7c, 0xc6,
0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0xfe, 0xc0, 0x7c, 0x00, 0x7c, 0x82, 0x38, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0x78, 0x0c,
0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7c, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x00, 0x00, 0x7c, 0xc0, 0xc0, 0x7c, 0x18, 0x70, 0x7c, 0x82, 0x7c, 0xc6,
0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0xfe, 0xc0, 0x7c, 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0xe0, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x66, 0x00, 0x38, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x18, 0x18, 0x3c, 0x00, 0x7c, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xc6, 0x00, 0x7c, 0xc6,
0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0xfe, 0xc6, 0xc6, 0x00, 0x38, 0x38, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00,
0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x0e, 0x10, 0xfe, 0x60, 0x78, 0x60, 0xfe, 0x00, 0x00, 0x00, 0x7c, 0x12,
0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x7e, 0xd0, 0x7e, 0x00, 0x7e, 0xc8, 0xc8, 0xfe, 0xc8, 0xc8, 0xce, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x7c, 0x82, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0xc6, 0x00, 0x7c, 0xc6,
0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0xc6, 0xc6, 0x7c, 0x00, 0xe0, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x7c, 0x82, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0xcc, 0xcc,
0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0xcc, 0xcc, 0x76, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0xc6, 0x00, 0xc6, 0xc6,
0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x7c, 0x00, 0x18, 0x7c, 0xd6, 0xd0, 0xd6, 0x7c, 0x18, 0x00,
0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x38, 0x6c, 0x60, 0xf0, 0x60, 0xf2, 0xdc, 0x00, 0x66, 0x3c, 0x18, 0x7e,
0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x18, 0x7e, 0x18, 0x00, 0xf8, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0x06,
0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, 0x0e, 0x10, 0x78, 0x0c,
0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x7c, 0xcc, 0x76, 0x00, 0x0e, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x0e, 0x10, 0xcc, 0xcc,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xcc, 0x76, 0x00, 0x66, 0x98, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x66, 0x98, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00, 0x38, 0x0c, 0x3c, 0x34,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00,
0x00, 0x00, 0x74, 0xcc, 0xc8, 0xdc, 0x76, 0x00, 0x78, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xdc, 0x40, 0x30, 0x00, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xfc,
0xfe, 0x62, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x02, 0x7e, 0xec, 0x6c, 0x6c, 0x48, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00,
0xfe, 0x62, 0x30, 0x18, 0x30, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x7e, 0xd0, 0xc8, 0xc8, 0x70, 0x00, 0xc0, 0xc8, 0xd0, 0xfe, 0x46, 0x8c, 0x1e, 0x00, 0xc0, 0xc8, 0xd0, 0xec,
0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xf8, 0x80, 0x00, 0x00, 0x7e, 0xd8, 0x18, 0x18, 0x10, 0x00, 0x5c, 0xbe, 0x0c, 0x00, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x00,
0x38, 0x10, 0x7c, 0xd6, 0xd6, 0x7c, 0x10, 0x38, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
0x7c, 0xc6, 0xc6, 0xc6, 0x6c, 0x28, 0xee, 0x00, 0x3c, 0x22, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, 0x6c, 0xd8, 0x00, 0x00, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
0x00, 0x00, 0x66, 0x99, 0x99, 0x66, 0x00, 0x00, 0x00, 0x06, 0x7c, 0x9e, 0xf2, 0x7c, 0xc0, 0x00, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0xdb, 0x77, 0xdb, 0xee,
0x00, 0x00, 0x7c, 0xc0, 0xf8, 0xc0, 0x7c, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18,
0x30, 0x18, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36,
0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x00, 0x00, 0xf8, 0x18,
0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36,
0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x00, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00,
0xd8, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0xc0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x18, 0x18, 0xf8, 0x18,
0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 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); const int debugfont_size = sizeof(debugfont);

View File

@ -1,58 +1,50 @@
#ifndef INI_INI_H_ #ifndef INI_INI_H_
#define INI_INI_H_ #define INI_INI_H_
#include <string>
#include <sstream>
#include <algorithm> #include <algorithm>
#include <utility>
#include <unordered_map>
#include <vector>
#include <memory>
#include <fstream>
#include <sys/stat.h>
#include <cctype> #include <cctype>
#include <fstream>
#include <memory>
#include <sstream>
#include <string>
#include <sys/stat.h>
#include <unordered_map>
#include <utility>
#include <vector>
namespace INI namespace INI {
{ namespace INIStringUtil {
namespace INIStringUtil const char *const whitespaceDelimiters = " \t\n\r\f\v";
{ inline void trim(std::string &str) {
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(str.find_last_not_of(whitespaceDelimiters) + 1);
str.erase(0, str.find_first_not_of(whitespaceDelimiters)); str.erase(0, str.find_first_not_of(whitespaceDelimiters));
} }
#ifndef INI_CASE_SENSITIVE #ifndef INI_CASE_SENSITIVE
inline void toLower(std::string& str) inline void toLower(std::string &str) {
{
std::transform(str.begin(), str.end(), str.begin(), [](const char c) { std::transform(str.begin(), str.end(), str.begin(), [](const char c) {
return static_cast<const char>(std::tolower(c)); return static_cast<const char>(std::tolower(c));
}); });
} }
#endif #endif
inline void replace(std::string& str, std::string const& a, std::string const& b) inline void replace(std::string &str, std::string const &a,
{ std::string const &b) {
if (!a.empty()) if (!a.empty()) {
{
std::size_t pos = 0; std::size_t pos = 0;
while ((pos = str.find(a, pos)) != std::string::npos) while ((pos = str.find(a, pos)) != std::string::npos) {
{
str.replace(pos, a.size(), b); str.replace(pos, a.size(), b);
pos += b.size(); pos += b.size();
} }
} }
} }
#ifdef _WIN32 #ifdef _WIN32
const char* const endl = "\r\n"; const char *const endl = "\r\n";
#else #else
const char* const endl = "\n"; const char *const endl = "\n";
#endif #endif
}; }; // namespace INIStringUtil
template<typename T> template <typename T> class INIMap {
class INIMap private:
{
private:
using T_DataIndexMap = std::unordered_map<std::string, std::size_t>; using T_DataIndexMap = std::unordered_map<std::string, std::size_t>;
using T_DataItem = std::pair<std::string, T>; using T_DataItem = std::pair<std::string, T>;
using T_DataContainer = std::vector<T_DataItem>; using T_DataContainer = std::vector<T_DataItem>;
@ -61,33 +53,29 @@ namespace INI
T_DataIndexMap dataIndexMap; T_DataIndexMap dataIndexMap;
T_DataContainer data; T_DataContainer data;
inline std::size_t setEmpty(std::string& key) inline std::size_t setEmpty(std::string &key) {
{
std::size_t index = data.size(); std::size_t index = data.size();
dataIndexMap[key] = index; dataIndexMap[key] = index;
data.emplace_back(key, T()); data.emplace_back(key, T());
return index; return index;
} }
public: public:
using const_iterator = typename T_DataContainer::const_iterator; using const_iterator = typename T_DataContainer::const_iterator;
INIMap() { } INIMap() {}
INIMap(INIMap const& other) INIMap(INIMap const &other) {
{
std::size_t data_size = other.data.size(); std::size_t data_size = other.data.size();
for (std::size_t i = 0; i < data_size; ++i) for (std::size_t i = 0; i < data_size; ++i) {
{ auto const &key = other.data[i].first;
auto const& key = other.data[i].first; auto const &obj = other.data[i].second;
auto const& obj = other.data[i].second;
data.emplace_back(key, obj); data.emplace_back(key, obj);
} }
dataIndexMap = T_DataIndexMap(other.dataIndexMap); dataIndexMap = T_DataIndexMap(other.dataIndexMap);
} }
T& operator[](std::string key) T &operator[](std::string key) {
{
INIStringUtil::trim(key); INIStringUtil::trim(key);
#ifndef INI_CASE_SENSITIVE #ifndef INI_CASE_SENSITIVE
INIStringUtil::toLower(key); INIStringUtil::toLower(key);
@ -97,70 +85,57 @@ namespace INI
std::size_t index = (hasIt) ? it->second : setEmpty(key); std::size_t index = (hasIt) ? it->second : setEmpty(key);
return data[index].second; return data[index].second;
} }
T get(std::string key) const T get(std::string key) const {
{
INIStringUtil::trim(key); INIStringUtil::trim(key);
#ifndef INI_CASE_SENSITIVE #ifndef INI_CASE_SENSITIVE
INIStringUtil::toLower(key); INIStringUtil::toLower(key);
#endif #endif
auto it = dataIndexMap.find(key); auto it = dataIndexMap.find(key);
if (it == dataIndexMap.end()) if (it == dataIndexMap.end()) {
{
return T(); return T();
} }
return T(data[it->second].second); return T(data[it->second].second);
} }
bool has(std::string key) const bool has(std::string key) const {
{
INIStringUtil::trim(key); INIStringUtil::trim(key);
#ifndef INI_CASE_SENSITIVE #ifndef INI_CASE_SENSITIVE
INIStringUtil::toLower(key); INIStringUtil::toLower(key);
#endif #endif
return (dataIndexMap.count(key) == 1); return (dataIndexMap.count(key) == 1);
} }
void set(std::string key, T obj) void set(std::string key, T obj) {
{
INIStringUtil::trim(key); INIStringUtil::trim(key);
#ifndef INI_CASE_SENSITIVE #ifndef INI_CASE_SENSITIVE
INIStringUtil::toLower(key); INIStringUtil::toLower(key);
#endif #endif
auto it = dataIndexMap.find(key); auto it = dataIndexMap.find(key);
if (it != dataIndexMap.end()) if (it != dataIndexMap.end()) {
{
data[it->second].second = obj; data[it->second].second = obj;
} } else {
else
{
dataIndexMap[key] = data.size(); dataIndexMap[key] = data.size();
data.emplace_back(key, obj); data.emplace_back(key, obj);
} }
} }
void set(T_MultiArgs const& multiArgs) void set(T_MultiArgs const &multiArgs) {
{ for (auto const &it : multiArgs) {
for (auto const& it : multiArgs) auto const &key = it.first;
{ auto const &obj = it.second;
auto const& key = it.first;
auto const& obj = it.second;
set(key, obj); set(key, obj);
} }
} }
bool remove(std::string key) bool remove(std::string key) {
{
INIStringUtil::trim(key); INIStringUtil::trim(key);
#ifndef INI_CASE_SENSITIVE #ifndef INI_CASE_SENSITIVE
INIStringUtil::toLower(key); INIStringUtil::toLower(key);
#endif #endif
auto it = dataIndexMap.find(key); auto it = dataIndexMap.find(key);
if (it != dataIndexMap.end()) if (it != dataIndexMap.end()) {
{
std::size_t index = it->second; std::size_t index = it->second;
data.erase(data.begin() + index); data.erase(data.begin() + index);
dataIndexMap.erase(it); dataIndexMap.erase(it);
for (auto& it2 : dataIndexMap) for (auto &it2 : dataIndexMap) {
{ auto &vi = it2.second;
auto& vi = it2.second; if (vi > index) {
if (vi > index)
{
vi--; vi--;
} }
} }
@ -168,58 +143,46 @@ namespace INI
} }
return false; return false;
} }
void clear() void clear() {
{
data.clear(); data.clear();
dataIndexMap.clear(); dataIndexMap.clear();
} }
std::size_t size() const std::size_t size() const { return data.size(); }
{
return data.size();
}
const_iterator begin() const { return data.begin(); } const_iterator begin() const { return data.begin(); }
const_iterator end() const { return data.end(); } const_iterator end() const { return data.end(); }
}; };
using INIStructure = INIMap<INIMap<std::string>>; using INIStructure = INIMap<INIMap<std::string>>;
namespace INIParser namespace INIParser {
{ using T_ParseValues = std::pair<std::string, std::string>;
using T_ParseValues = std::pair<std::string, std::string>;
enum class PDataType : char enum class PDataType : char {
{
PDATA_NONE, PDATA_NONE,
PDATA_COMMENT, PDATA_COMMENT,
PDATA_SECTION, PDATA_SECTION,
PDATA_KEYVALUE, PDATA_KEYVALUE,
PDATA_UNKNOWN PDATA_UNKNOWN
}; };
inline PDataType parseLine(std::string line, T_ParseValues& parseData) inline PDataType parseLine(std::string line, T_ParseValues &parseData) {
{
parseData.first.clear(); parseData.first.clear();
parseData.second.clear(); parseData.second.clear();
INIStringUtil::trim(line); INIStringUtil::trim(line);
if (line.empty()) if (line.empty()) {
{
return PDataType::PDATA_NONE; return PDataType::PDATA_NONE;
} }
char firstCharacter = line[0]; char firstCharacter = line[0];
if (firstCharacter == ';') if (firstCharacter == ';') {
{
return PDataType::PDATA_COMMENT; return PDataType::PDATA_COMMENT;
} }
if (firstCharacter == '[') if (firstCharacter == '[') {
{
auto commentAt = line.find_first_of(';'); auto commentAt = line.find_first_of(';');
if (commentAt != std::string::npos) if (commentAt != std::string::npos) {
{
line = line.substr(0, commentAt); line = line.substr(0, commentAt);
} }
auto closingBracketAt = line.find_last_of(']'); auto closingBracketAt = line.find_last_of(']');
if (closingBracketAt != std::string::npos) if (closingBracketAt != std::string::npos) {
{
auto section = line.substr(1, closingBracketAt - 1); auto section = line.substr(1, closingBracketAt - 1);
INIStringUtil::trim(section); INIStringUtil::trim(section);
parseData.first = section; parseData.first = section;
@ -229,8 +192,7 @@ namespace INI
auto lineNorm = line; auto lineNorm = line;
INIStringUtil::replace(lineNorm, "\\=", " "); INIStringUtil::replace(lineNorm, "\\=", " ");
auto equalsAt = lineNorm.find_first_of('='); auto equalsAt = lineNorm.find_first_of('=');
if (equalsAt != std::string::npos) if (equalsAt != std::string::npos) {
{
auto key = line.substr(0, equalsAt); auto key = line.substr(0, equalsAt);
INIStringUtil::trim(key); INIStringUtil::trim(key);
INIStringUtil::replace(key, "\\=", "="); INIStringUtil::replace(key, "\\=", "=");
@ -241,21 +203,19 @@ namespace INI
return PDataType::PDATA_KEYVALUE; return PDataType::PDATA_KEYVALUE;
} }
return PDataType::PDATA_UNKNOWN; return PDataType::PDATA_UNKNOWN;
} }
}; }; // namespace INIParser
class INIReader class INIReader {
{ public:
public:
using T_LineData = std::vector<std::string>; using T_LineData = std::vector<std::string>;
using T_LineDataPtr = std::shared_ptr<T_LineData>; using T_LineDataPtr = std::shared_ptr<T_LineData>;
private: private:
std::ifstream fileReadStream; std::ifstream fileReadStream;
T_LineDataPtr lineData; T_LineDataPtr lineData;
T_LineData readFile() T_LineData readFile() {
{
std::string fileContents; std::string fileContents;
fileReadStream.seekg(0, std::ios::end); fileReadStream.seekg(0, std::ios::end);
fileContents.resize(fileReadStream.tellg()); fileContents.resize(fileReadStream.tellg());
@ -264,23 +224,19 @@ namespace INI
fileReadStream.read(&fileContents[0], fileSize); fileReadStream.read(&fileContents[0], fileSize);
fileReadStream.close(); fileReadStream.close();
T_LineData output; T_LineData output;
if (fileSize == 0) if (fileSize == 0) {
{
return output; return output;
} }
std::string buffer; std::string buffer;
buffer.reserve(50); buffer.reserve(50);
for (std::size_t i = 0; i < fileSize; ++i) for (std::size_t i = 0; i < fileSize; ++i) {
{ char &c = fileContents[i];
char& c = fileContents[i]; if (c == '\n') {
if (c == '\n')
{
output.emplace_back(buffer); output.emplace_back(buffer);
buffer.clear(); buffer.clear();
continue; continue;
} }
if (c != '\0' && c != '\r') if (c != '\0' && c != '\r') {
{
buffer += c; buffer += c;
} }
} }
@ -288,45 +244,36 @@ namespace INI
return output; return output;
} }
public: public:
INIReader(std::string const& filename, bool keepLineData = false) INIReader(std::string const &filename, bool keepLineData = false) {
{
fileReadStream.open(filename, std::ios::in | std::ios::binary); fileReadStream.open(filename, std::ios::in | std::ios::binary);
if (keepLineData) if (keepLineData) {
{
lineData = std::make_shared<T_LineData>(); lineData = std::make_shared<T_LineData>();
} }
} }
~INIReader() { } ~INIReader() {}
bool operator>>(INIStructure& data) bool operator>>(INIStructure &data) {
{ if (!fileReadStream.is_open()) {
if (!fileReadStream.is_open())
{
return false; return false;
} }
T_LineData fileLines = readFile(); T_LineData fileLines = readFile();
std::string section; std::string section;
bool inSection = false; bool inSection = false;
INIParser::T_ParseValues parseData; INIParser::T_ParseValues parseData;
for (auto const& line : fileLines) for (auto const &line : fileLines) {
{
auto parseResult = INIParser::parseLine(line, parseData); auto parseResult = INIParser::parseLine(line, parseData);
if (parseResult == INIParser::PDataType::PDATA_SECTION) if (parseResult == INIParser::PDataType::PDATA_SECTION) {
{
inSection = true; inSection = true;
data[section = parseData.first]; data[section = parseData.first];
} } else if (inSection &&
else if (inSection && parseResult == INIParser::PDataType::PDATA_KEYVALUE) parseResult == INIParser::PDataType::PDATA_KEYVALUE) {
{ auto const &key = parseData.first;
auto const& key = parseData.first; auto const &value = parseData.second;
auto const& value = parseData.second;
data[section][key] = value; data[section][key] = value;
} }
if (lineData && parseResult != INIParser::PDataType::PDATA_UNKNOWN) if (lineData && parseResult != INIParser::PDataType::PDATA_UNKNOWN) {
{ if (parseResult == INIParser::PDataType::PDATA_KEYVALUE && !inSection) {
if (parseResult == INIParser::PDataType::PDATA_KEYVALUE && !inSection)
{
continue; continue;
} }
lineData->emplace_back(line); lineData->emplace_back(line);
@ -334,90 +281,69 @@ namespace INI
} }
return true; return true;
} }
T_LineDataPtr getLines() T_LineDataPtr getLines() { return lineData; }
{ };
return lineData;
}
};
class INIGenerator class INIGenerator {
{ private:
private:
std::ofstream fileWriteStream; std::ofstream fileWriteStream;
public: public:
bool prettyPrint = false; bool prettyPrint = false;
INIGenerator(std::string const& filename) INIGenerator(std::string const &filename) {
{
fileWriteStream.open(filename, std::ios::out | std::ios::binary); fileWriteStream.open(filename, std::ios::out | std::ios::binary);
} }
~INIGenerator() { } ~INIGenerator() {}
bool operator<<(INIStructure const& data) bool operator<<(INIStructure const &data) {
{ if (!fileWriteStream.is_open()) {
if (!fileWriteStream.is_open())
{
return false; return false;
} }
if (!data.size()) if (!data.size()) {
{
return true; return true;
} }
auto it = data.begin(); auto it = data.begin();
for (;;) for (;;) {
{ auto const &section = it->first;
auto const& section = it->first; auto const &collection = it->second;
auto const& collection = it->second; fileWriteStream << "[" << section << "]";
fileWriteStream if (collection.size()) {
<< "["
<< section
<< "]";
if (collection.size())
{
fileWriteStream << INIStringUtil::endl; fileWriteStream << INIStringUtil::endl;
auto it2 = collection.begin(); auto it2 = collection.begin();
for (;;) for (;;) {
{
auto key = it2->first; auto key = it2->first;
INIStringUtil::replace(key, "=", "\\="); INIStringUtil::replace(key, "=", "\\=");
auto value = it2->second; auto value = it2->second;
INIStringUtil::trim(value); INIStringUtil::trim(value);
fileWriteStream fileWriteStream << key << ((prettyPrint) ? " = " : "=") << value;
<< key if (++it2 == collection.end()) {
<< ((prettyPrint) ? " = " : "=")
<< value;
if (++it2 == collection.end())
{
break; break;
} }
fileWriteStream << INIStringUtil::endl; fileWriteStream << INIStringUtil::endl;
} }
} }
if (++it == data.end()) if (++it == data.end()) {
{
break; break;
} }
fileWriteStream << INIStringUtil::endl; fileWriteStream << INIStringUtil::endl;
if (prettyPrint) if (prettyPrint) {
{
fileWriteStream << INIStringUtil::endl; fileWriteStream << INIStringUtil::endl;
} }
} }
return true; return true;
} }
}; };
class INIWriter class INIWriter {
{ private:
private:
using T_LineData = std::vector<std::string>; using T_LineData = std::vector<std::string>;
using T_LineDataPtr = std::shared_ptr<T_LineData>; using T_LineDataPtr = std::shared_ptr<T_LineData>;
std::string filename; std::string filename;
T_LineData getLazyOutput(T_LineDataPtr const& lineData, INIStructure& data, INIStructure& original) T_LineData getLazyOutput(T_LineDataPtr const &lineData, INIStructure &data,
{ INIStructure &original) {
T_LineData output; T_LineData output;
INIParser::T_ParseValues parseData; INIParser::T_ParseValues parseData;
std::string sectionCurrent; std::string sectionCurrent;
@ -426,67 +352,49 @@ namespace INI
bool discardNextEmpty = false; bool discardNextEmpty = false;
bool writeNewKeys = false; bool writeNewKeys = false;
std::size_t lastKeyLine = 0; std::size_t lastKeyLine = 0;
for (auto line = lineData->begin(); line != lineData->end(); ++line) for (auto line = lineData->begin(); line != lineData->end(); ++line) {
{ if (!writeNewKeys) {
if (!writeNewKeys)
{
auto parseResult = INIParser::parseLine(*line, parseData); auto parseResult = INIParser::parseLine(*line, parseData);
if (parseResult == INIParser::PDataType::PDATA_SECTION) if (parseResult == INIParser::PDataType::PDATA_SECTION) {
{ if (parsingSection) {
if (parsingSection)
{
writeNewKeys = true; writeNewKeys = true;
parsingSection = false; parsingSection = false;
--line; --line;
continue; continue;
} }
sectionCurrent = parseData.first; sectionCurrent = parseData.first;
if (data.has(sectionCurrent)) if (data.has(sectionCurrent)) {
{
parsingSection = true; parsingSection = true;
continueToNextSection = false; continueToNextSection = false;
discardNextEmpty = false; discardNextEmpty = false;
output.emplace_back(*line); output.emplace_back(*line);
lastKeyLine = output.size(); lastKeyLine = output.size();
} } else {
else
{
continueToNextSection = true; continueToNextSection = true;
discardNextEmpty = true; discardNextEmpty = true;
continue; continue;
} }
} } else if (parseResult == INIParser::PDataType::PDATA_KEYVALUE) {
else if (parseResult == INIParser::PDataType::PDATA_KEYVALUE) if (continueToNextSection) {
{
if (continueToNextSection)
{
continue; continue;
} }
if (data.has(sectionCurrent)) if (data.has(sectionCurrent)) {
{ auto &collection = data[sectionCurrent];
auto& collection = data[sectionCurrent]; auto const &key = parseData.first;
auto const& key = parseData.first; auto const &value = parseData.second;
auto const& value = parseData.second; if (collection.has(key)) {
if (collection.has(key))
{
auto outputValue = collection[key]; auto outputValue = collection[key];
if (value == outputValue) if (value == outputValue) {
{
output.emplace_back(*line); output.emplace_back(*line);
} } else {
else
{
INIStringUtil::trim(outputValue); INIStringUtil::trim(outputValue);
auto lineNorm = *line; auto lineNorm = *line;
INIStringUtil::replace(lineNorm, "\\=", " "); INIStringUtil::replace(lineNorm, "\\=", " ");
auto equalsAt = lineNorm.find_first_of('='); auto equalsAt = lineNorm.find_first_of('=');
auto valueAt = lineNorm.find_first_not_of( auto valueAt = lineNorm.find_first_not_of(
INIStringUtil::whitespaceDelimiters, INIStringUtil::whitespaceDelimiters, equalsAt + 1);
equalsAt + 1
);
std::string outputLine = line->substr(0, valueAt); std::string outputLine = line->substr(0, valueAt);
if (prettyPrint && equalsAt + 1 == valueAt) if (prettyPrint && equalsAt + 1 == valueAt) {
{
outputLine += " "; outputLine += " ";
} }
outputLine += outputValue; outputLine += outputValue;
@ -495,98 +403,72 @@ namespace INI
lastKeyLine = output.size(); lastKeyLine = output.size();
} }
} }
} } else {
else if (discardNextEmpty && line->empty()) {
{
if (discardNextEmpty && line->empty())
{
discardNextEmpty = false; discardNextEmpty = false;
} } else if (parseResult != INIParser::PDataType::PDATA_UNKNOWN) {
else if (parseResult != INIParser::PDataType::PDATA_UNKNOWN)
{
output.emplace_back(*line); output.emplace_back(*line);
} }
} }
} }
if (writeNewKeys || std::next(line) == lineData->end()) if (writeNewKeys || std::next(line) == lineData->end()) {
{
T_LineData linesToAdd; T_LineData linesToAdd;
if (data.has(sectionCurrent) && original.has(sectionCurrent)) if (data.has(sectionCurrent) && original.has(sectionCurrent)) {
{ auto const &collection = data[sectionCurrent];
auto const& collection = data[sectionCurrent]; auto const &collectionOriginal = original[sectionCurrent];
auto const& collectionOriginal = original[sectionCurrent]; for (auto const &it : collection) {
for (auto const& it : collection)
{
auto key = it.first; auto key = it.first;
if (collectionOriginal.has(key)) if (collectionOriginal.has(key)) {
{
continue; continue;
} }
auto value = it.second; auto value = it.second;
INIStringUtil::replace(key, "=", "\\="); INIStringUtil::replace(key, "=", "\\=");
INIStringUtil::trim(value); INIStringUtil::trim(value);
linesToAdd.emplace_back( linesToAdd.emplace_back(key + ((prettyPrint) ? " = " : "=") +
key + ((prettyPrint) ? " = " : "=") + value value);
);
} }
} }
if (!linesToAdd.empty()) if (!linesToAdd.empty()) {
{ output.insert(output.begin() + lastKeyLine, linesToAdd.begin(),
output.insert( linesToAdd.end());
output.begin() + lastKeyLine,
linesToAdd.begin(),
linesToAdd.end()
);
} }
if (writeNewKeys) if (writeNewKeys) {
{
writeNewKeys = false; writeNewKeys = false;
--line; --line;
} }
} }
} }
for (auto const& it : data) for (auto const &it : data) {
{ auto const &section = it.first;
auto const& section = it.first; if (original.has(section)) {
if (original.has(section))
{
continue; continue;
} }
if (prettyPrint && output.size() > 0 && !output.back().empty()) if (prettyPrint && output.size() > 0 && !output.back().empty()) {
{
output.emplace_back(); output.emplace_back();
} }
output.emplace_back("[" + section + "]"); output.emplace_back("[" + section + "]");
auto const& collection = it.second; auto const &collection = it.second;
for (auto const& it2 : collection) for (auto const &it2 : collection) {
{
auto key = it2.first; auto key = it2.first;
auto value = it2.second; auto value = it2.second;
INIStringUtil::replace(key, "=", "\\="); INIStringUtil::replace(key, "=", "\\=");
INIStringUtil::trim(value); INIStringUtil::trim(value);
output.emplace_back( output.emplace_back(key + ((prettyPrint) ? " = " : "=") + value);
key + ((prettyPrint) ? " = " : "=") + value
);
} }
} }
return output; return output;
} }
public: public:
bool prettyPrint = false; bool prettyPrint = false;
INIWriter(std::string const& filename) INIWriter(std::string const &filename) : filename(filename) {}
: filename(filename) ~INIWriter() {}
{
}
~INIWriter() { }
bool operator<<(INIStructure& data) bool operator<<(INIStructure &data) {
{
struct stat buf; struct stat buf;
bool fileExists = (stat(filename.c_str(), &buf) == 0); bool fileExists = (stat(filename.c_str(), &buf) == 0);
if (!fileExists) if (!fileExists) {
{
INIGenerator generator(filename); INIGenerator generator(filename);
generator.prettyPrint = prettyPrint; generator.prettyPrint = prettyPrint;
return generator << data; return generator << data;
@ -596,27 +478,21 @@ namespace INI
bool readSuccess = false; bool readSuccess = false;
{ {
INIReader reader(filename, true); INIReader reader(filename, true);
if ((readSuccess = reader >> originalData)) if ((readSuccess = reader >> originalData)) {
{
lineData = reader.getLines(); lineData = reader.getLines();
} }
} }
if (!readSuccess) if (!readSuccess) {
{
return false; return false;
} }
T_LineData output = getLazyOutput(lineData, data, originalData); T_LineData output = getLazyOutput(lineData, data, originalData);
std::ofstream fileWriteStream(filename, std::ios::out | std::ios::binary); std::ofstream fileWriteStream(filename, std::ios::out | std::ios::binary);
if (fileWriteStream.is_open()) if (fileWriteStream.is_open()) {
{ if (output.size()) {
if (output.size())
{
auto line = output.begin(); auto line = output.begin();
for (;;) for (;;) {
{
fileWriteStream << *line; fileWriteStream << *line;
if (++line == output.end()) if (++line == output.end()) {
{
break; break;
} }
fileWriteStream << INIStringUtil::endl; fileWriteStream << INIStringUtil::endl;
@ -626,54 +502,44 @@ namespace INI
} }
return false; return false;
} }
}; };
class INIFile class INIFile {
{ private:
private:
std::string filename; std::string filename;
public: public:
INIFile(std::string const& filename) INIFile(std::string const &filename) : filename(filename) {}
: filename(filename)
{ }
~INIFile() { } ~INIFile() {}
bool read(INIStructure& data) const bool read(INIStructure &data) const {
{ if (data.size()) {
if (data.size())
{
data.clear(); data.clear();
} }
if (filename.empty()) if (filename.empty()) {
{
return false; return false;
} }
INIReader reader(filename); INIReader reader(filename);
return reader >> data; return reader >> data;
} }
bool generate(INIStructure const& data, bool pretty = false) const bool generate(INIStructure const &data, bool pretty = false) const {
{ if (filename.empty()) {
if (filename.empty())
{
return false; return false;
} }
INIGenerator generator(filename); INIGenerator generator(filename);
generator.prettyPrint = pretty; generator.prettyPrint = pretty;
return generator << data; return generator << data;
} }
bool write(INIStructure& data, bool pretty = false) const bool write(INIStructure &data, bool pretty = false) const {
{ if (filename.empty()) {
if (filename.empty())
{
return false; return false;
} }
INIWriter writer(filename); INIWriter writer(filename);
writer.prettyPrint = pretty; writer.prettyPrint = pretty;
return writer << data; return writer << data;
} }
}; };
} } // namespace INI
#endif #endif

View File

@ -1,16 +1,15 @@
#pragma once #pragma once
#include <string>
#include <renderd7/external/json.hpp> #include <renderd7/external/json.hpp>
#include <string>
/// RenderD7::Lang /// RenderD7::Lang
namespace RenderD7::Lang namespace RenderD7::Lang {
{ /// Get the 3ds System Language
/// Get the 3ds System Language std::string getSys();
std::string getSys(); /// Get a translated string
/// Get a translated string /// \param key The Key so the code can find your string
/// \param key The Key so the code can find your string std::string get(const std::string &key);
std::string get(const std::string &key); /// Load the lang file from dir structure en/app.json for sample
/// Load the lang file from dir structure en/app.json for sample /// \param lang the folder name en, fr, de ... . I prefer geSys()
/// \param lang the folder name en, fr, de ... . I prefer geSys() void load(const std::string &lang);
void load(const std::string &lang); } // namespace RenderD7::Lang
} /// RenderD7::Lang

View File

@ -6,9 +6,8 @@
#include <unistd.h> #include <unistd.h>
/** Log Class */ /** Log Class */
class Log class Log {
{ public:
public:
/** Construct */ /** Construct */
Log(); Log();
/** Deconstruct */ /** Deconstruct */
@ -23,8 +22,9 @@ class Log
std::string logDate(void); std::string logDate(void);
/// Format to logstyle /// Format to logstyle
/// \param fmt_str the formatted style /// \param fmt_str the formatted style
std::string format(const std::string& fmt_str, ...); std::string format(const std::string &fmt_str, ...);
private:
private:
/// \param filename the name of the logfile /// \param filename the name of the logfile
std::string filename; std::string filename;
}; };

View File

@ -1,60 +1,58 @@
#pragma once #pragma once
#include <tuple> #include <tuple>
namespace RenderD7{ namespace RenderD7 {
class Parameter class Parameter {
{ private:
private:
using id = size_t; using id = size_t;
template<typename T> template <typename T> struct type {
struct type { static void id() { } }; static void id() {}
};
template<typename T> template <typename T> static id type_id() {
static id type_id() { return reinterpret_cast<id>(&type<T>::id); } return reinterpret_cast<id>(&type<T>::id);
}
template<typename T> template <typename T> using decay = typename std::decay<T>::type;
using decay = typename std::decay<T>::type;
template<typename T> template <typename T>
using none = typename std::enable_if<!std::is_same<Parameter, T>::value>::type; using none =
typename std::enable_if<!std::is_same<Parameter, T>::value>::type;
struct base struct base {
{ virtual ~base() {}
virtual ~base() { }
virtual bool is(id) const = 0; virtual bool is(id) const = 0;
virtual base *copy() const = 0; virtual base *copy() const = 0;
} *p = nullptr; } *p = nullptr;
template<typename T> template <typename T> struct data : base, std::tuple<T> {
struct data : base, std::tuple<T>
{
using std::tuple<T>::tuple; using std::tuple<T>::tuple;
T &get() & { return std::get<0>(*this); } T &get() & { return std::get<0>(*this); }
T const &get() const& { return std::get<0>(*this); } T const &get() const & { return std::get<0>(*this); }
bool is(id i) const override { return i == type_id<T>(); } bool is(id i) const override { return i == type_id<T>(); }
base *copy() const override { return new data{get()}; } base *copy() const override { return new data{get()}; }
}; };
template<typename T> template <typename T> T &stat() { return static_cast<data<T> &>(*p).get(); }
T &stat() { return static_cast<data<T>&>(*p).get(); }
template<typename T> template <typename T> T const &stat() const {
T const &stat() const { return static_cast<data<T> const&>(*p).get(); } return static_cast<data<T> const &>(*p).get();
}
template<typename T> template <typename T> T &dyn() { return dynamic_cast<data<T> &>(*p).get(); }
T &dyn() { return dynamic_cast<data<T>&>(*p).get(); }
template<typename T> template <typename T> T const &dyn() const {
T const &dyn() const { return dynamic_cast<data<T> const&>(*p).get(); } return dynamic_cast<data<T> const &>(*p).get();
}
public: public:
/** /**
* @brief Default constructor * @brief Default constructor
*/ */
Parameter() { } Parameter() {}
/** /**
* @brief Destructs the Parameter * @brief Destructs the Parameter
@ -71,42 +69,50 @@ namespace RenderD7{
* @brief Const copy constructor * @brief Const copy constructor
* @param s The Parameter to copy * @param s The Parameter to copy
*/ */
Parameter(Parameter const &s) : p{s.p->copy()} { } Parameter(Parameter const &s) : p{s.p->copy()} {}
/** /**
* @brief Initializes the Parameter with the given value * @brief Initializes the Parameter with the given value
* @param x The value to initialize the Parameter with * @param x The value to initialize the Parameter with
*/ */
template<typename T, typename U = decay<T>, typename = none<U>> template <typename T, typename U = decay<T>, typename = none<U>>
Parameter(T &&x) : p{new data<U>{std::forward<T>(x)}} { } Parameter(T &&x) : p{new data<U>{std::forward<T>(x)}} {}
/** /**
* @brief Overloads the assignment operator * @brief Overloads the assignment operator
* @param s The value to set the Parameter to * @param s The value to set the Parameter to
*/ */
Parameter &operator=(Parameter s) { swap(*this, s); return *this; } 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 * @brief Clears the Parameter
*/ */
void clear() { delete p; p = nullptr; } void clear() {
delete p;
p = nullptr;
}
/** /**
* @brief Checks whether the Parameter is the given type * @brief Checks whether the Parameter is the given type
* @tparam T The type to check * @tparam T The type to check
* @return Whether the Parameter has the given type or not * @return Whether the Parameter has the given type or not
*/ */
template<typename T> template <typename T> bool is() const {
bool is() const { return p ? p->is(type_id<T>()) : false; } return p ? p->is(type_id<T>()) : false;
}
/** /**
* @brief Returns the value of the Parameter * @brief Returns the value of the Parameter
* @tparam T The type of the Parameter * @tparam T The type of the Parameter
* @return The value 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. * @warning If the type of the Parameter doesn't match the type of it's stored
* value, it will result in undefined behaviour.
*/ */
template<typename T> T &get() & { return stat<T>(); } template <typename T> T &get() & { return stat<T>(); }
}; };
} } // namespace RenderD7

View File

@ -1,54 +1,63 @@
#pragma once #pragma once
#include <3ds.h> #include <3ds.h>
#include <algorithm>
#include <citro2d.h> #include <citro2d.h>
#include <citro3d.h> #include <citro3d.h>
#include <memory>
#include <stack>
#include <string>
#include <functional>
#include <map>
#include <vector>
#include <dirent.h>
#include <unistd.h>
#include <stdio.h>
#include <cstring> #include <cstring>
#include <random> #include <dirent.h>
#include <sys/stat.h>
#include <algorithm>
#include <iostream>
#include <filesystem> #include <filesystem>
#include <functional>
#include <iostream>
#include <locale> #include <locale>
#include <map>
#include <memory>
#include <random>
#include <stack>
#include <stdio.h>
#include <string>
#include <sys/stat.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#include <vector>
#include <codecvt> #include <codecvt>
#include <renderd7/external/lodepng.h>
#include <renderd7/lang.hpp>
#include <renderd7/parameter.hpp>
#include <renderd7/thread.hpp>
#include <renderd7/ini.hpp>
#include <renderd7/stringtool.hpp>
#include <renderd7/bmp.hpp>
#include <renderd7/bmpconverter.hpp>
#include <renderd7/Toast.hpp>
#include <renderd7/Ovl.hpp>
#include <renderd7/BitmapPrinter.hpp> #include <renderd7/BitmapPrinter.hpp>
#include <renderd7/Color.hpp>
#include <renderd7/Draw.hpp>
#include <renderd7/Image.hpp> #include <renderd7/Image.hpp>
#include <renderd7/Ovl.hpp>
#include <renderd7/Screen.hpp>
#include <renderd7/Sheet.hpp>
#include <renderd7/Sprite.hpp> #include <renderd7/Sprite.hpp>
#include <renderd7/SpriteAnimation.hpp> #include <renderd7/SpriteAnimation.hpp>
#include <renderd7/Sheet.hpp>
#include <renderd7/Color.hpp>
#include <renderd7/Time.hpp> #include <renderd7/Time.hpp>
#include <renderd7/Screen.hpp> #include <renderd7/Toast.hpp>
#include <renderd7/Draw.hpp> #include <renderd7/bmp.hpp>
#include <renderd7/bmpconverter.hpp>
#include <renderd7/external/lodepng.h>
#include <renderd7/ini.hpp>
#include <renderd7/lang.hpp>
#include <renderd7/parameter.hpp>
#include <renderd7/stringtool.hpp>
#include <renderd7/thread.hpp>
extern "C"
{ extern "C" {
#include <renderd7/external/fs.h> #include <renderd7/external/fs.h>
} }
#define RENDERD7VSTRING "0.8.0" #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 #define DEFAULT_CENTER 0.5f
/*extern C3D_RenderTarget* Top; /*extern C3D_RenderTarget* Top;
@ -63,51 +72,38 @@ extern touchPosition d7_touch;
extern std::string dspststus; extern std::string dspststus;
/// RenderD7 /// RenderD7
namespace RenderD7 namespace RenderD7 {
{ float GetDeltaTime();
float GetDeltaTime(); enum kbd { SWKBD, BKBD };
enum kbd{ enum kbd_type { NUMPAD, STANDARD };
SWKBD, struct TObject {
BKBD int x; // Position X
}; int y; // Position Y
enum kbd_type int w; // Button Width
{ int h; // Button Height
NUMPAD, std::string text = ""; // Text
STANDARD float correctx = 0; // Correct X Position
}; float correcty = 0; // Correct Y Position
struct TObject float txtsize = 0.7f; // Set Text Size
{ };
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 { class Scene {
public: public:
static std::stack<std::unique_ptr<Scene>> scenes; static std::stack<std::unique_ptr<Scene>> scenes;
virtual ~Scene() {} virtual ~Scene() {}
virtual void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) = 0; virtual void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) = 0;
virtual void Draw() const = 0; virtual void Draw() const = 0;
//virtual void Ovl() const = 0; // virtual void Ovl() const = 0;
static void Load(std::unique_ptr<Scene> scene, bool fade = false); static void Load(std::unique_ptr<Scene> scene, bool fade = false);
static void Back(); static void Back();
static void doDraw(); static void doDraw();
static void doLogic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch); static void doLogic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch);
//static void HandleOvl(); // static void HandleOvl();
}; };
class RSettings : public RenderD7::Scene class RSettings : public RenderD7::Scene {
{ private:
private: enum RState { RSETTINGS, RINFO };
enum RState {
RSETTINGS,
RINFO
};
RenderD7::RSettings::RState m_state = RenderD7::RSettings::RState::RSETTINGS; RenderD7::RSettings::RState m_state = RenderD7::RSettings::RState::RSETTINGS;
std::string rd7srstate = "false"; std::string rd7srstate = "false";
@ -119,9 +115,7 @@ namespace RenderD7
std::string mtcola = "255"; std::string mtcola = "255";
std::string mttxtcola = "255"; std::string mttxtcola = "255";
std::vector<RenderD7::TObject> buttons = {
std::vector<RenderD7::TObject> buttons =
{
{20, 35, 120, 35, "RD7SR", -11, 10}, {20, 35, 120, 35, "RD7SR", -11, 10},
{20, 85, 120, 35, "MT_CSV", -15, 9}, {20, 85, 120, 35, "MT_CSV", -15, 9},
{20, 135, 120, 35, "MT_OVL", -19, 10}, {20, 135, 120, 35, "MT_OVL", -19, 10},
@ -129,142 +123,147 @@ namespace RenderD7
{180, 35, 120, 35, "MTSCREEN", -29, 10}, {180, 35, 120, 35, "MTSCREEN", -29, 10},
{180, 85, 120, 35, "DSPERR", -13, 10}, {180, 85, 120, 35, "DSPERR", -13, 10},
{180, 135, 120, 35, "INFO", 2, 10}, {180, 135, 120, 35, "INFO", 2, 10},
{180, 185, 120, 35, "", -13, 10} {180, 185, 120, 35, "", -13, 10}};
};
public: public:
RSettings(); RSettings();
void Draw(void) const override; void Draw(void) const override;
~RSettings(); ~RSettings();
void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) override; void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) override;
}; };
void LoadSettings(); void LoadSettings();
class DSP_NF : public RenderD7::Ovl class DSP_NF : public RenderD7::Ovl {
{ public:
public:
DSP_NF(); DSP_NF();
void Draw(void) const override; void Draw(void) const override;
void Logic() override; void Logic() override;
private:
private:
int msgposy = 240; int msgposy = 240;
int delay = 0; 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
int GetRandomInt(int b, int e); namespace Convert {
void DrawMetrikOvl(); inline float StringtoFloat(std::string inp) { return std::atof(inp.c_str()); }
bool DrawImageFromSheet(RenderD7::Sheet* sheet, size_t index, float x, float y, float scaleX = 1.0, float scaleY = 1.0); inline int StringtoInt(std::string inp) { return std::atoi(inp.c_str()); }
namespace Error inline bool FloatToBool(float inp) {
{ if (inp == 1)
void DisplayError(std::string toptext, std::string errortext, int timesec = 3); return true;
void DisplayFatalError(std::string toptext, std::string errortext); else
} return false;
namespace Init }
{ } // namespace Convert
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 struct DirContent {
{
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 name;
std::string path; std::string path;
bool isDir; bool isDir;
}; };
namespace FS namespace FS {
{ bool FileExist(const std::string &path);
bool FileExist(const std::string& path); }
}
bool IsNdspInit(); bool IsNdspInit();
void SetupLog(void); void SetupLog(void);
std::string GetFramerate(); std::string GetFramerate();
bool MainLoop(); bool MainLoop();
void ExitApp(); void ExitApp();
void ClearTextBufs(void); void ClearTextBufs(void);
std::string Kbd(int lenght, SwkbdType tp); std::string Kbd(int lenght, SwkbdType tp);
void FrameEnd(); void FrameEnd();
void ToggleRD7SR(); void ToggleRD7SR();
bool IsRD7SR(); bool IsRD7SR();
struct TLBtn {
int x; // Position X
int y; // Position Y
int w; // Button Width
int h; // Button Height
};
struct TLBtn struct ScrollList1 {
{
int x; //Position X
int y; //Position Y
int w; //Button Width
int h; //Button Height
};
struct ScrollList1
{
std::string Text = ""; std::string Text = "";
}; };
struct ScrollList2 struct ScrollList2 {
{
float x; float x;
float y; float y;
float w; float w;
float h; float h;
std::string Text = ""; std::string Text = "";
}; };
/*enum ListType /*enum ListType
{ {
ONE, ONE,
TWO TWO
};*/ };*/
void DrawList1(RenderD7::ScrollList1 &l, float txtsize, C3D_RenderTarget *t); void DrawList1(RenderD7::ScrollList1 &l, float txtsize, C3D_RenderTarget *t);
void DrawTObjects(std::vector<RenderD7::TObject> tobjects, u32 color, u32 txtcolor, int selection = -1, u32 selbgcolor = RenderD7::Color::Hex("#2D98AF"), u32 selcolor = RenderD7::Color::Hex("#000000")); void DrawTObjects(std::vector<RenderD7::TObject> tobjects, u32 color,
void DrawSTObject(std::vector<RenderD7::TObject> tobject, int tobjectindex, u32 color, u32 txtcolor); u32 txtcolor, int selection = -1,
bool touchTObj(touchPosition touch, RenderD7::TObject button); u32 selbgcolor = RenderD7::Color::Hex("#2D98AF"),
bool touchTLBtn(touchPosition touch, RenderD7::TLBtn button); u32 selcolor = RenderD7::Color::Hex("#000000"));
void DrawTLBtns(std::vector<RenderD7::TLBtn> btns, u32 color, int selection = -1, u32 selbgcolor = RenderD7::Color::Hex("#2D98AF"), u32 selcolor = RenderD7::Color::Hex("#000000")); void DrawSTObject(std::vector<RenderD7::TObject> 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<RenderD7::TLBtn> btns, u32 color,
int selection = -1,
u32 selbgcolor = RenderD7::Color::Hex("#2D98AF"),
u32 selcolor = RenderD7::Color::Hex("#000000"));
struct Checkbox struct Checkbox {
{
float x, y, s; float x, y, s;
bool is_chexked = false; bool is_chexked = false;
u32 outcol, incol, chcol; u32 outcol, incol, chcol;
}; };
void DrawCheckbox(Checkbox box); void DrawCheckbox(Checkbox box);
class Console class Console {
{ public:
public:
Console(); Console();
Console(int x, int y, int w, int h, u8 a = 255); 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, 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}); 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); void On(C3D_RenderTarget *t_cscreen);
bool Update(); bool Update();
~Console(); ~Console();
private:
private:
std::vector<std::string> m_lines; std::vector<std::string> m_lines;
int x, y, w, h; int x, y, w, h;
std::string m_name = ""; std::string m_name = "";
@ -274,9 +273,10 @@ namespace RenderD7
RenderD7::Color::rgba color = {255, 255, 255, 255}; RenderD7::Color::rgba color = {255, 255, 255, 255};
RenderD7::Color::rgba outlinecol = {222, 222, 222, 255}; RenderD7::Color::rgba outlinecol = {222, 222, 222, 255};
RenderD7::Color::rgba barcolor = {0, 0, 0, 255}; RenderD7::Color::rgba barcolor = {0, 0, 0, 255};
}; };
void GetDirContentsExt(std::vector<RenderD7::DirContent> &dircontent, const std::vector<std::string> &extensions); void GetDirContentsExt(std::vector<RenderD7::DirContent> &dircontent,
void GetDirContents(std::vector<RenderD7::DirContent> &dircontent); const std::vector<std::string> &extensions);
void GetDirContents(std::vector<RenderD7::DirContent> &dircontent);
} /// RenderD7 } // namespace RenderD7

View File

@ -10,7 +10,7 @@ public:
/// \param path Path to the .wav file /// \param path Path to the .wav file
/// \param channel the channel 1-23 /// \param channel the channel 1-23
/// \param toloop true:loop the sound, false: don't loop /// \param toloop true:loop the sound, false: don't loop
sound(const std::string& path, int channel = 1, bool toloop = false); sound(const std::string &path, int channel = 1, bool toloop = false);
/** deconstruct the sound */ /** deconstruct the sound */
~sound(); ~sound();
/** play the sound */ /** play the sound */
@ -22,7 +22,6 @@ private:
/// \param dataSize the Size of the filedata /// \param dataSize the Size of the filedata
u32 dataSize; u32 dataSize;
ndspWaveBuf waveBuf; ndspWaveBuf waveBuf;
u8* data = NULL; u8 *data = NULL;
int chnl; int chnl;
}; };

View File

@ -1,44 +1,40 @@
#pragma once #pragma once
#include <string>
#include <iostream>
#include <iomanip> #include <iomanip>
#include <iostream>
#include <string>
namespace RenderD7 namespace RenderD7 {
{ inline bool NameIsEndingWith(const std::string &name,
inline bool NameIsEndingWith(const std::string &name, const std::vector<std::string> &extensions) const std::vector<std::string> &extensions) {
{ if (name.substr(0, 2) == "._")
if (name.substr(0, 2) == "._") return false; 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++) { for (int i = 0; i < (int)extensions.size(); i++) {
const std::string ext = extensions.at(i); const std::string ext = extensions.at(i);
if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0) return true; if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0)
return true;
} }
return false; return false;
}
} }
template<class T> } // namespace RenderD7
T GetFileName(T const & path, T const & delims = "/\\") template <class T> T GetFileName(T const &path, T const &delims = "/\\") {
{
return path.substr(path.find_last_of(delims) + 1); return path.substr(path.find_last_of(delims) + 1);
} }
template<class T> template <class T> T remove_ext(T const &filename) {
T remove_ext(T const & filename)
{
typename T::size_type const p(filename.find_last_of('.')); typename T::size_type const p(filename.find_last_of('.'));
return p > 0 && p != T::npos ? filename.substr(0, p) : filename; return p > 0 && p != T::npos ? filename.substr(0, p) : filename;
} }
template< typename T > template <typename T> std::string Int_To_Hex(T i) {
std::string Int_To_Hex( T i )
{
std::stringstream stream; std::stringstream stream;
stream << "0x" stream << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex
<< std::setfill ('0') << std::setw(sizeof(T)*2) << i;
<< std::hex << i;
return stream.str(); return stream.str();
} }

View File

@ -2,35 +2,34 @@
#include <3ds.h> #include <3ds.h>
#include <atomic> #include <atomic>
#include <functional> #include <functional>
#include <string>
#include <renderd7/parameter.hpp> #include <renderd7/parameter.hpp>
#include <string>
using CTRU_Thread = Thread; using CTRU_Thread = Thread;
#define THREAD_STACK_SIZE 0x1000 #define THREAD_STACK_SIZE 0x1000
namespace RenderD7 { namespace RenderD7 {
namespace Threads namespace Threads {
{ inline bool threadrunning = false;
inline bool threadrunning = false;
struct Thread struct Thread {
{
Handle handle; Handle handle;
void (*ep)(void); void (*ep)(void);
bool finished; bool finished;
void* stacktop; void *stacktop;
}; };
bool Create(); bool Create();
bool Join(); bool Join();
void Exit(); void Exit();
} } // namespace Threads
class Thread { class Thread {
public: public:
/** /**
* @brief Default constructor * @brief Default constructor
* @note This should only be called when calling m3d::Thread::initialize() before calling m3d::Thread::start() * @note This should only be called when calling m3d::Thread::initialize()
* before calling m3d::Thread::start()
*/ */
Thread(); Thread();
@ -40,11 +39,18 @@ namespace RenderD7 {
* @param t_parameter The parameter to pass to the function * @param t_parameter The parameter to pass to the function
* @param t_autostart Whether the thread should start instantly * @param t_autostart Whether the thread should start instantly
* @param t_detached Whether the thread starts detached or not * @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) * @param t_stackSize The stacksize allocated for the thread in bytes (rounded
* @note t_function needs to be of type `void` and take one (and only one) parameter of type m3d::Parameter * to multiples of 8 bytes)
* @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 * @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<void(RenderD7::Parameter)> t_function, RenderD7::Parameter t_parameter = nullptr, bool t_autostart = false, bool t_detached = false, unsigned long long int t_stackSize = 4 * 1024); Thread(std::function<void(RenderD7::Parameter)> 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 * @brief Destructs the thread
@ -57,15 +63,24 @@ namespace RenderD7 {
* @param t_parameter The parameter to pass to the function * @param t_parameter The parameter to pass to the function
* @param t_autostart Whether the thread should start instantly * @param t_autostart Whether the thread should start instantly
* @param t_detached Whether the thread starts detached or not * @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) * @param t_stackSize The stacksize allocated for the thread in bytes (rounded
* @note t_function needs to be of type `void` and take one (and only one) parameter of type m3d::Parameter * to multiples of 8 bytes)
* @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 * @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<void(RenderD7::Parameter)> t_function, RenderD7::Parameter t_parameter = nullptr, bool t_autostart = false, bool t_detached = false, unsigned long long int t_stackSize = 4 * 1024); void initialize(std::function<void(RenderD7::Parameter)> t_function,
RenderD7::Parameter t_parameter = nullptr,
bool t_autostart = false, bool t_detached = false,
unsigned long long int t_stackSize = 4 * 1024);
/** /**
* @brief Sets the size of the stack that gets allocated for the next thread that get's started * @brief Sets the size of the stack that gets allocated for the next thread
* @param t_stackSize The allocated space in bytes (rounded to multiples of 8 bytes) * 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); void setStackSize(unsigned long long int t_stackSize);
@ -91,7 +106,9 @@ namespace RenderD7 {
/** /**
* @brief Puts the thread to sleep * @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. * 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(); static void sleep();
@ -101,19 +118,19 @@ namespace RenderD7 {
*/ */
static void sleep(int t_milliseconds); static void sleep(int t_milliseconds);
private: private:
struct ThreadData { struct ThreadData {
RenderD7::Parameter m_parameter; RenderD7::Parameter m_parameter;
std::function<void(RenderD7::Parameter)> m_function; std::function<void(RenderD7::Parameter)> m_function;
std::atomic<bool>* m_running; std::atomic<bool> *m_running;
}; };
static void threadFunction(void* t_arg); static void threadFunction(void *t_arg);
/* data */ /* data */
int m_priority, m_stackSize; int m_priority, m_stackSize;
bool m_started; bool m_started;
std::atomic<bool> m_running; std::atomic<bool> m_running;
RenderD7::Thread::ThreadData m_data; RenderD7::Thread::ThreadData m_data;
CTRU_Thread m_thread; CTRU_Thread m_thread;
}; };
} } // namespace RenderD7

View File

@ -1,17 +1,18 @@
#include <renderd7/Clock.hpp> #include <renderd7/Clock.hpp>
namespace rnd7{ namespace rnd7 {
enum class TweenType : int {Position = 1, Color, Alpha}; 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}; enum class TweenState : int { Playing = 1, Stopped };
class Tween class Tween {
{ public:
public:
Tween(float from, float to, float duration, TweenLoop loop, TweenState state); Tween(float from, float to, float duration, TweenLoop loop, TweenState state);
};
}; } // namespace rnd7
}

View File

@ -6,70 +6,66 @@
extern bool shouldbe_disabled; extern bool shouldbe_disabled;
extern std::string csvpc; extern std::string csvpc;
RenderD7::BitmapPrinter::BitmapPrinter(int w, int h) RenderD7::BitmapPrinter::BitmapPrinter(int w, int h) {
{
BMP newmap(w, h, true); BMP newmap(w, h, true);
bitmap = newmap; bitmap = newmap;
//renderframe.LoadPFromBuffer(BitmapConverter::ConvertData(bitmap.DATA())); // renderframe.LoadPFromBuffer(BitmapConverter::ConvertData(bitmap.DATA()));
blank = newmap; blank = newmap;
} }
RenderD7::BitmapPrinter::~BitmapPrinter() RenderD7::BitmapPrinter::~BitmapPrinter() {
{ if (this->renderframe.loadet)
if(this->renderframe.loadet) this->renderframe.Unload(); this->renderframe.Unload();
} }
bool RenderD7::BitmapPrinter::DecodeFile(std::string file) bool RenderD7::BitmapPrinter::DecodeFile(std::string file) {
{
unsigned error = bitmap.read(file.c_str()); unsigned error = bitmap.read(file.c_str());
if (error) if (error) {
{ RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("BitmapPrinter", "Error Code: " + std::to_string(error))); "BitmapPrinter", "Error Code: " + std::to_string(error)));
return false; return false;
} }
return true; return true;
} }
void RenderD7::BitmapPrinter::DrawPixel(int x, int y, u8 b, u8 g, u8 r, u8 a) void RenderD7::BitmapPrinter::DrawPixel(int x, int y, u8 b, u8 g, u8 r, u8 a) {
{ unsigned error =
unsigned error = bitmap.set_pixel(x, bitmap.bmp_info_header.height - y, b, g, r, a); bitmap.set_pixel(x, bitmap.bmp_info_header.height - y, b, g, r, a);
if (error) if (error) {
{ RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("BitmapPrinter->Pixel", "Error Code: " + std::to_string(error))); "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) 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); unsigned error = bitmap.draw_rectangle(
if (error) x, bitmap.bmp_info_header.height - y - h, w, h, b, g, r, a, line_w);
{ if (error) {
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("BitmapPrinter->Rect", "Error Code: " + std::to_string(error))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"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) 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); unsigned error = bitmap.fill_region(x, bitmap.bmp_info_header.height - h - y,
if (error) w, h, b, g, r, a);
{ if (error) {
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("BitmapPrinter->RectF", "Error Code: " + std::to_string(error))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"BitmapPrinter->RectF", "Error Code: " + std::to_string(error)));
} }
} }
void RenderD7::BitmapPrinter::SaveBmp(std::string name) void RenderD7::BitmapPrinter::SaveBmp(std::string name) {
{ if (!RenderD7::NameIsEndingWith(name, {"bmp"})) {
if(!RenderD7::NameIsEndingWith(name, {"bmp"}))
{
name += ".bmp"; name += ".bmp";
} }
bitmap.write(name.c_str()); bitmap.write(name.c_str());
} }
void RenderD7::BitmapPrinter::SavePng(std::string name) void RenderD7::BitmapPrinter::SavePng(std::string name) {
{ if (!RenderD7::NameIsEndingWith(name, {"png"})) {
if(!RenderD7::NameIsEndingWith(name, {"png"}))
{
name += ".png"; name += ".png";
} }
std::vector<unsigned char> ImageBuffer; std::vector<unsigned char> ImageBuffer;
@ -77,115 +73,99 @@ void RenderD7::BitmapPrinter::SavePng(std::string name)
lodepng::save_file(ImageBuffer, name); lodepng::save_file(ImageBuffer, name);
} }
void RenderD7::BitmapPrinter::CreateScreen(C3D_RenderTarget *target) void RenderD7::BitmapPrinter::CreateScreen(C3D_RenderTarget *target) {
{
isscreen = true; isscreen = true;
targetr = target; targetr = target;
if (target == Top) if (target == Top) {
{
bitmap = BMP(400, 240, true); bitmap = BMP(400, 240, true);
blank = BMP(400, 240, true); blank = BMP(400, 240, true);
} }
if (target == TopRight) if (target == TopRight) {
{
bitmap = BMP(400, 240, true); bitmap = BMP(400, 240, true);
blank = BMP(400, 240, true); blank = BMP(400, 240, true);
} }
if (target == Bottom) if (target == Bottom) {
{
bitmap = BMP(320, 240, true); bitmap = BMP(320, 240, true);
blank = BMP(320, 240, true); blank = BMP(320, 240, true);
} }
renderframe.LoadPFromBuffer(BitmapConverter::ConvertData(bitmap.DATA())); renderframe.LoadPFromBuffer(BitmapConverter::ConvertData(bitmap.DATA()));
} }
bool RenderD7::BitmapPrinter::DrawScreenDirectF(int framerate) bool RenderD7::BitmapPrinter::DrawScreenDirectF(int framerate) {
{
bool updtt = false; bool updtt = false;
if (isscreen) if (isscreen) {
{ if (frame == (60 / framerate)) {
if(frame == (60/framerate)){
RenderD7::OnScreen(targetr); RenderD7::OnScreen(targetr);
if(renderframe.loadet) renderframe.Unload(); if (renderframe.loadet)
renderframe.Unload();
this->Decode(decc); this->Decode(decc);
frame = 0; frame = 0;
updtt = true; updtt = true;
} }
if(renderframe.loadet) renderframe.Draw(0, 0); if (renderframe.loadet)
renderframe.Draw(0, 0);
frame++; frame++;
} }
return updtt; return updtt;
} }
bool RenderD7::BitmapPrinter::DrawScreenDirect() bool RenderD7::BitmapPrinter::DrawScreenDirect() {
{
bool updtt = false; bool updtt = false;
if (isscreen) if (isscreen) {
{
RenderD7::OnScreen(targetr); RenderD7::OnScreen(targetr);
if(renderframe.loadet) renderframe.Unload(); if (renderframe.loadet)
renderframe.Unload();
this->Decode(decc); this->Decode(decc);
updtt = true; updtt = true;
if(renderframe.loadet) renderframe.Draw(0, 0); if (renderframe.loadet)
renderframe.Draw(0, 0);
} }
return updtt; return updtt;
} }
RenderD7::Image RenderD7::BitmapPrinter::GetImage() RenderD7::Image RenderD7::BitmapPrinter::GetImage() {
{
RenderD7::Image img; RenderD7::Image img;
img.LoadFromBitmap(bitmap); img.LoadFromBitmap(bitmap);
return img; return img;
} }
void RenderD7::BitmapPrinter::UsePreMap(BMP map) void RenderD7::BitmapPrinter::UsePreMap(BMP map) { bitmap = map; }
{ void RenderD7::BitmapPrinter::UsePrePrintMap(BitmapPrinter printmap) {
bitmap = map;
}
void RenderD7::BitmapPrinter::UsePrePrintMap(BitmapPrinter printmap)
{
bitmap = printmap.GetBitmap(); bitmap = printmap.GetBitmap();
} }
void RenderD7::BitmapPrinter::Clear(u8 b, u8 g, u8 r, u8 a) void RenderD7::BitmapPrinter::Clear(u8 b, u8 g, u8 r, u8 a) {
{ bitmap.fill_region(0, 0, bitmap.bmp_info_header.width,
bitmap.fill_region(0, 0, bitmap.bmp_info_header.width, bitmap.bmp_info_header.height, b, g, r, a); bitmap.bmp_info_header.height, b, g, r, a);
}
void RenderD7::BitmapPrinter::ClearBlank()
{
bitmap = blank;
} }
void RenderD7::BitmapPrinter::ClearBlank() { bitmap = blank; }
void RenderD7::BitmapPrinter::DrawScreenF(int framerate) void RenderD7::BitmapPrinter::DrawScreenF(int framerate) {
{ if (isscreen) {
if (isscreen) if (frame == (60 / framerate)) {
{
if(frame == (60/framerate)){
RenderD7::OnScreen(targetr); RenderD7::OnScreen(targetr);
frame = 0; frame = 0;
} }
if(renderframe.loadet) renderframe.Draw(0, 0); if (renderframe.loadet)
renderframe.Draw(0, 0);
frame++; frame++;
} }
} }
void RenderD7::BitmapPrinter::DrawScreen() void RenderD7::BitmapPrinter::DrawScreen() {
{ if (isscreen) {
if (isscreen)
{
RenderD7::OnScreen(targetr); RenderD7::OnScreen(targetr);
if(renderframe.loadet) renderframe.Draw(0, 0); if (renderframe.loadet)
renderframe.Draw(0, 0);
} }
} }
bool RenderD7::BitmapPrinter::UpdateScreenF(int framerate) bool RenderD7::BitmapPrinter::UpdateScreenF(int framerate) {
{
bool updtt = false; bool updtt = false;
if (isscreen) if (isscreen) {
{ if (frame == (60 / framerate)) {
if(frame == (60/framerate)){ if (renderframe.loadet)
if(renderframe.loadet) renderframe.Unload(); renderframe.Unload();
//renderframe.LoadFromBitmap(bitmap); // renderframe.LoadFromBitmap(bitmap);
this->Decode(decc); this->Decode(decc);
frame = 0; frame = 0;
updtt = true; updtt = true;
@ -194,12 +174,11 @@ bool RenderD7::BitmapPrinter::UpdateScreenF(int framerate)
} }
return updtt; return updtt;
} }
bool RenderD7::BitmapPrinter::UpdateScreen() bool RenderD7::BitmapPrinter::UpdateScreen() {
{
bool updtt = false; bool updtt = false;
if (isscreen) if (isscreen) {
{ if (renderframe.loadet)
if(renderframe.loadet) renderframe.Unload(); renderframe.Unload();
this->Decode(decc); this->Decode(decc);
updtt = true; updtt = true;
} }
@ -208,60 +187,63 @@ bool RenderD7::BitmapPrinter::UpdateScreen()
#define TICKS_PER_MSEC 268111.856 #define TICKS_PER_MSEC 268111.856
void RenderD7::BitmapPrinter::Benchmark() void RenderD7::BitmapPrinter::Benchmark() {
{ if (setupbenchmark) {
if(setupbenchmark)
{
frametime = 0; frametime = 0;
renderedframes = 0; renderedframes = 0;
timer = 0; timer = 0;
setupbenchmark = false; setupbenchmark = false;
lastTime = svcGetSystemTick(); lastTime = svcGetSystemTick();
} }
if(benchmark) if (benchmark) {
{ if (timer >= 60) {
if(timer >= 60)
{
std::string renderedf = std::to_string(renderedframes); std::string renderedf = std::to_string(renderedframes);
std::string avgdtt = std::to_string(mhdtt); std::string avgdtt = std::to_string(mhdtt);
float alldtt = 0; float alldtt = 0;
for (size_t i = 1; i < hdttt.size(); i++) for (size_t i = 1; i < hdttt.size(); i++) {
{
alldtt += hdttt[i]; alldtt += hdttt[i];
} }
float alldtt2 = 0; float alldtt2 = 0;
for (size_t i = 0; i < hdttt2.size(); i++) for (size_t i = 0; i < hdttt2.size(); i++) {
{
alldtt2 += hdttt2[i]; alldtt2 += hdttt2[i];
} }
float alldtt3 = 0; float alldtt3 = 0;
for (size_t i = 0; i < hdttt3.size(); i++) for (size_t i = 0; i < hdttt3.size(); i++) {
{
alldtt3 += hdttt3[i]; alldtt3 += hdttt3[i];
} }
int allfps = 0; int allfps = 0;
for (size_t f = 1; f < fpscountc.size(); f++) for (size_t f = 1; f < fpscountc.size(); f++) {
{
allfps += fpscountc[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));
std::string avgcpu = std::to_string((alldtt/(float)hdttt.size()-1)); std::string resultt =
std::string avgcpu2 = std::to_string(((alldtt2/(float)hdttt2.size())*1000)); "TestMode: " + std::to_string(testfpsd) + "fps" +
std::string avgcpu3 = std::to_string(((alldtt3/(float)hdttt3.size())*1000)); "\nRendered Frames: " + renderedf + "\nMax Cpu Time: " + avgdtt +
std::string avgfps = std::to_string((allfps/(int)fpscountc.size()-1)); "\nAvg Cpu Time: " + avgcpu + "\nAvg Fps: " + avgfps +
"\nAvg EncodeTime: " + avgcpu2 + "ms/f\nAvg DecodeTime: " + avgcpu3 +
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"; "ms\n";
this->ClearBlank(); this->ClearBlank();
this->DrawRectFilled(0, 0, this->bitmap.bmp_info_header.width, this->bitmap.bmp_info_header.height, 0, 0, 0, 255); 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); this->DrawDebugText(0, 0, 0, RenderD7::Color::Hex("#ffffff"), resultt);
std::string outname = csvpc + "/benchmark_" + RenderD7::GetTimeStr() + ".png"; std::string outname =
csvpc + "/benchmark_" + RenderD7::GetTimeStr() + ".png";
this->SavePng(outname); this->SavePng(outname);
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("Benchmark", "Saved to: \n" + outname)); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"Benchmark", "Saved to: \n" + outname));
benchmark = false; benchmark = false;
} }
uint64_t currentTime = svcGetSystemTick(); uint64_t currentTime = svcGetSystemTick();
dtt = ((float)(currentTime / (float)TICKS_PER_MSEC) - (float)(lastTime / (float)TICKS_PER_MSEC)) / 1000.f; dtt = ((float)(currentTime / (float)TICKS_PER_MSEC) -
(float)(lastTime / (float)TICKS_PER_MSEC)) /
1000.f;
lastTime = currentTime; lastTime = currentTime;
lastTime = currentTime; lastTime = currentTime;
frameCounter++; frameCounter++;
@ -273,55 +255,72 @@ void RenderD7::BitmapPrinter::Benchmark()
} }
uint64_t lastTime2 = svcGetSystemTick(); uint64_t lastTime2 = svcGetSystemTick();
this->ClearBlank(); this->ClearBlank();
this->DrawRectFilled(0, 0, this->bitmap.bmp_info_header.width, this->bitmap.bmp_info_header.width, 255, 255, 255, 255); this->DrawRectFilled(0, 0, this->bitmap.bmp_info_header.width,
this->DrawRect(5, 5, this->bitmap.bmp_info_header.width - 10, this->bitmap.bmp_info_header.height - 10, 5, 0, 0, 0, 0); this->bitmap.bmp_info_header.width, 255, 255, 255,
//this->DrawDebugText(20, 20, 0, RenderD7::Color::Hex("#ffffff"), "Fps: " + std::to_string(fps)); 255);
this->DrawDebugText(0, 0, 0.5f, RenderD7::Color::Hex("#ff0000"), "Time: " + std::to_string(timer)); this->DrawRect(5, 5, this->bitmap.bmp_info_header.width - 10,
this->DrawDebugText(0, 10, 0.5f, RenderD7::Color::Hex("#ff0000"), "Fps: " + std::to_string(fps)); this->bitmap.bmp_info_header.height - 10, 5, 0, 0, 0, 0);
this->DrawDebugText(0, 20, 0.5f, RenderD7::Color::Hex("#ff0000"), "dt: " + std::to_string(dtt)); // this->DrawDebugText(20, 20, 0, RenderD7::Color::Hex("#ffffff"), "Fps: " +
this->DrawDebugText(0, 30, 0.5f, RenderD7::Color::Hex("#ff0000"), "MaxEncodeTime: " + std::to_string(mdtt2*1000) + "ms/f"); // std::to_string(fps));
this->DrawDebugText(0, 40, 0.5f, RenderD7::Color::Hex("#ff0000"), "MaxDecodeTime: " + std::to_string(mdtt3*1000) + "ms"); 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(); uint64_t currentTime2 = svcGetSystemTick();
dtt2 = ((float)(currentTime2 / (float)TICKS_PER_MSEC) - (float)(lastTime2 / (float)TICKS_PER_MSEC)) / 1000.f; dtt2 = ((float)(currentTime2 / (float)TICKS_PER_MSEC) -
(float)(lastTime2 / (float)TICKS_PER_MSEC)) /
1000.f;
hdttt2.push_back(dtt2); hdttt2.push_back(dtt2);
lastTime2 = svcGetSystemTick(); lastTime2 = svcGetSystemTick();
bool updgg = this->UpdateScreenF(testfps); bool updgg = this->UpdateScreenF(testfps);
currentTime2 = svcGetSystemTick(); currentTime2 = svcGetSystemTick();
dtt3 = ((float)(currentTime2 / (float)TICKS_PER_MSEC) - (float)(lastTime2 / (float)TICKS_PER_MSEC)) / 1000.f; dtt3 = ((float)(currentTime2 / (float)TICKS_PER_MSEC) -
if(updgg) hdttt3.push_back(dtt3); (float)(lastTime2 / (float)TICKS_PER_MSEC)) /
if (!shouldbe_disabled) this->DrawScreen(); 1000.f;
if (updgg)
hdttt3.push_back(dtt3);
if (!shouldbe_disabled)
this->DrawScreen();
renderedframes++; renderedframes++;
if(mdtt2 < dtt2) if (mdtt2 < dtt2) {
{
mdtt2 = dtt2; mdtt2 = dtt2;
} }
if(mdtt3 < dtt3 && updgg) if (mdtt3 < dtt3 && updgg) {
{
mdtt3 = dtt3; mdtt3 = dtt3;
} }
timer+= 1*dtt; timer += 1 * dtt;
float hdtt = C3D_GetProcessingTime(); float hdtt = C3D_GetProcessingTime();
hdttt.push_back(hdtt); hdttt.push_back(hdtt);
fpscountc.push_back(fps); fpscountc.push_back(fps);
if(mhdtt < hdtt) if (mhdtt < hdtt) {
{
mhdtt = C3D_GetProcessingTime(); mhdtt = C3D_GetProcessingTime();
} }
/*if (!shouldbe_disabled) /*if (!shouldbe_disabled)
{ {
RenderD7::OnScreen(Bottom); RenderD7::OnScreen(Bottom);
RenderD7::DrawText(0, 0, 0.5f, RenderD7::Color::Hex("#ff0000"), "Time: " + std::to_string(timer)); RenderD7::DrawText(0, 0, 0.5f, RenderD7::Color::Hex("#ff0000"),
RenderD7::DrawText(0, 20, 0.5f, RenderD7::Color::Hex("#ff0000"), "Fps: " + std::to_string(fps)); "Time: " + std::to_string(timer)); RenderD7::DrawText(0, 20, 0.5f,
RenderD7::DrawText(0, 40, 0.5f, RenderD7::Color::Hex("#ff0000"), "dt: " + std::to_string(dtt)); RenderD7::Color::Hex("#ff0000"), "Fps: " + std::to_string(fps));
RenderD7::DrawText(0, 60, 0.5f, RenderD7::Color::Hex("#ff0000"), "MaxRenderTime: " + std::to_string(mdtt2*1000) + "ms/f"); RenderD7::DrawText(0, 40, 0.5f, RenderD7::Color::Hex("#ff0000"),
RenderD7::DrawText(0, 80, 0.5f, RenderD7::Color::Hex("#ff0000"), "MaxConvertTime: " + std::to_string(mdtt3*1000) + "ms"); "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) void RenderD7::BitmapPrinter::SetupBenchmark(int framerate) {
{
benchmark = true; benchmark = true;
setupbenchmark = true; setupbenchmark = true;
this->testfps = framerate; this->testfps = framerate;
@ -330,58 +329,59 @@ void RenderD7::BitmapPrinter::SetupBenchmark(int framerate)
#include <renderd7/debugfont.h> #include <renderd7/debugfont.h>
void RenderD7::BitmapPrinter::DrawDebugChar(u32 posX, u32 posY, int t_size, u32 color, char character) void RenderD7::BitmapPrinter::DrawDebugChar(u32 posX, u32 posY, int t_size,
{ u32 color, char character) {
bool isscale = (t_size > 1) ? true : false; bool isscale = (t_size > 1) ? true : false;
for(u32 y = 0; y < 8; y++) for (u32 y = 0; y < 8; y++) {
{
char charPos = debugfont[character * 8 + y]; char charPos = debugfont[character * 8 + y];
for(u32 x = 0; x < 8; x++) for (u32 x = 0; x < 8; x++)
if(((charPos >> (7 - x)) & 1) == 1) if (((charPos >> (7 - x)) & 1) == 1) {
{ if (!isscale)
if (!isscale) DrawPixel((int)posX + x + 1, (int)posY + y + 1, UNPACK_BGRA(color)); 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)); 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) void RenderD7::BitmapPrinter::DrawChar(int posX, int posY, float t_size,
{ u32 color, char character,
for(int y = 0; y < font.GetGlyphHeight(character); y++) RenderD7::NFontApi font) {
{ for (int y = 0; y < font.GetGlyphHeight(character); y++) {
for(int x = 0; x < font.GetGlyphWidth(character); x++) for (int x = 0; x < font.GetGlyphWidth(character); x++) {
{ DrawPixel(posX + x + 1, posY + y + 1, 255, 255, 255,
DrawPixel(posX + x + 1, posY + y + 1, 255, 255, 255, font.GetGlyphBitmap(character)[((y * font.GetGlyphWidth(character) + x) * 1)]); font.GetGlyphBitmap(
if(((font.GetGlyphBitmap(character)[font.GetGlyphHeight(character) + y] >> (font.GetGlyphWidth(character - 1) - x)) & 1) == 1) 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++) }
// for(int y = 0; y < font.GetGlyphHeight(character) *
// font.GetGlyphWidth(character); y++)
//{ //{
// DrawPixel(posX + x + 1, posY + y + 1, UNPACK_BGRA(color)); // DrawPixel(posX + x + 1, posY + y + 1, UNPACK_BGRA(color));
//} //}
} }
#define SPACING_Y 10 #define SPACING_Y 10
#define SPACING_X 8 #define SPACING_X 8
void RenderD7::BitmapPrinter::DrawDebugText(int x, int y, int t_size, u32 color, std::string text) void RenderD7::BitmapPrinter::DrawDebugText(int x, int y, int t_size, u32 color,
{ std::string text) {
if (t_size < 1) if (t_size < 1) {
{
t_size = 1; t_size = 1;
} }
for(u32 i = 0, line_i = 0; i < strlen(text.c_str()); i++) for (u32 i = 0, line_i = 0; i < strlen(text.c_str()); i++)
switch(text[i]) switch (text[i]) {
{
case '\n': case '\n':
y += (SPACING_Y*t_size); y += (SPACING_Y * t_size);
line_i = 0; line_i = 0;
break; break;
@ -390,31 +390,32 @@ void RenderD7::BitmapPrinter::DrawDebugText(int x, int y, int t_size, u32 color,
break; break;
default: default:
//Make sure we never get out of the screen // 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)) if (line_i >= (((u32)this->bitmap.bmp_info_header.width) - (u32)x) /
{ (SPACING_X * t_size)) {
y += (SPACING_Y*t_size); y += (SPACING_Y * t_size);
line_i = 1; //Little offset so we know the same text continues line_i = 1; // Little offset so we know the same text continues
if(text[i] == ' ') break; //Spaces at the start look weird if (text[i] == ' ')
break; // Spaces at the start look weird
} }
this->DrawDebugChar((u32)x + line_i * (SPACING_X*t_size), (u32)y, t_size, color, text[i]); this->DrawDebugChar((u32)x + line_i * (SPACING_X * t_size), (u32)y,
t_size, color, text[i]);
line_i++; line_i++;
break; break;
} }
} }
void RenderD7::BitmapPrinter::DrawText(int x, int y, float t_size, u32 color, std::string text, RenderD7::NFontApi font) void RenderD7::BitmapPrinter::DrawText(int x, int y, float t_size, u32 color,
{ std::string text,
if (t_size < 1) RenderD7::NFontApi font) {
{ if (t_size < 1) {
t_size = 1; t_size = 1;
} }
for(u32 i = 0, line_i = 0; i < strlen(text.c_str()); i++) for (u32 i = 0, line_i = 0; i < strlen(text.c_str()); i++)
switch(text[i]) switch (text[i]) {
{
case '\n': case '\n':
y += (font.GetLineHeight()); y += (font.GetLineHeight());
line_i = 0; line_i = 0;
@ -425,30 +426,30 @@ void RenderD7::BitmapPrinter::DrawText(int x, int y, float t_size, u32 color, st
break; break;
default: default:
//Make sure we never get out of the screen // 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]))) if (line_i >= (((u32)this->bitmap.bmp_info_header.width) - (u32)x) /
{ (u32)(font.GetGlyphWidth(text[i]))) {
y += (SPACING_Y*t_size); y += (SPACING_Y * t_size);
line_i = 1; //Little offset so we know the same text continues line_i = 1; // Little offset so we know the same text continues
if(text[i] == ' ') break; //Spaces at the start look weird if (text[i] == ' ')
break; // Spaces at the start look weird
} }
this->DrawChar(x + line_i * (font.GetGlyphWidth(text[i])), y, t_size, color, text[i], font); this->DrawChar(x + line_i * (font.GetGlyphWidth(text[i])), y, t_size,
color, text[i], font);
line_i++; line_i++;
break; break;
} }
} }
bool RenderD7::BitmapPrinter::Decode(Decoder deccc) bool RenderD7::BitmapPrinter::Decode(Decoder deccc) {
{
bool res = false; bool res = false;
switch (deccc) switch (deccc) {
{
case Decoder::BITMAP2PNG2C3D: case Decoder::BITMAP2PNG2C3D:
renderframe.LoadPFromBuffer(BitmapConverter::ConvertData(this->bitmap.DATA())); renderframe.LoadPFromBuffer(
BitmapConverter::ConvertData(this->bitmap.DATA()));
res = true; res = true;
break; break;
case Decoder::BITMAP2C3D: case Decoder::BITMAP2C3D:

View File

@ -1,10 +1,13 @@
#include <renderd7/Color.hpp> #include <renderd7/Color.hpp>
#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) uint32_t RenderD7::Color::Hex(const std::string color, uint8_t a) {
{ if (color.length() < 7 ||
if (color.length() < 7 || std::regex_search(color.substr(1), std::regex("[^0-9A-Fa-f]"))) { // invalid color. std::regex_search(color.substr(1),
std::regex("[^0-9A-Fa-f]"))) { // invalid color.
return RenderD7::Color::Hex("#000000", 0); return RenderD7::Color::Hex("#000000", 0);
} }
int r = std::stoi(color.substr(1, 2), nullptr, 16); int r = std::stoi(color.substr(1, 2), nullptr, 16);
@ -13,10 +16,9 @@ uint32_t RenderD7::Color::Hex(const std::string color, uint8_t a)
return RGBA8(r, g, b, a); return RGBA8(r, g, b, a);
} }
std::string RenderD7::Color::RGB2Hex(int r, int g, int b) std::string RenderD7::Color::RGB2Hex(int r, int g, int b) {
{
std::stringstream ss; std::stringstream ss;
ss << "#"; ss << "#";
ss << std::hex << (r << 16 | g << 8 | b ); ss << std::hex << (r << 16 | g << 8 | b);
return ss.str(); return ss.str();
} }

View File

@ -4,17 +4,17 @@ extern C2D_TextBuf TextBuf;
extern C2D_Font Font; extern C2D_Font Font;
extern bool currentScreen; extern bool currentScreen;
bool RenderD7::Draw::Rect(float x, float y, float w, float h, u32 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); return C2D_DrawRectSolid(x, y, 0.5f, w, h, color);
} }
bool RenderD7::Draw::Px(float x, float y, u32 color) bool RenderD7::Draw::Px(float x, float y, u32 color) {
{
return C2D_DrawRectSolid(x, y, 0.5f, 1, 1, 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) { 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; float lineHeight, widthScale;
// Check for the lineHeight. // Check for the lineHeight.
@ -25,56 +25,81 @@ void RenderD7::Draw::TextCentered(float x, float y, float size, u32 color, std::
} }
int line = 0; int line = 0;
while(Text.find('\n') != Text.npos) { while (Text.find('\n') != Text.npos) {
if (maxWidth == 0) { if (maxWidth == 0) {
// Do the widthScale. // Do the widthScale.
if (fnt != nullptr) { if (fnt != nullptr) {
widthScale = RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt); widthScale = RenderD7::Draw::GetTextWidth(
size, Text.substr(0, Text.find('\n')), fnt);
} else { } else {
widthScale = RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n'))); widthScale =
RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')));
} }
} else { } else {
// Do the widthScale 2. // Do the widthScale 2.
if (fnt != nullptr) { if (fnt != nullptr) {
widthScale = std::min((float)maxWidth, RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt)); widthScale = std::min((float)maxWidth,
RenderD7::Draw::GetTextWidth(
size, Text.substr(0, Text.find('\n')), fnt));
} else { } else {
widthScale = std::min((float)maxWidth, RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')))); widthScale = std::min((float)maxWidth,
RenderD7::Draw::GetTextWidth(
size, Text.substr(0, Text.find('\n'))));
} }
} }
if (fnt != nullptr) { 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); RenderD7::Draw::Text((currentScreen ? 200 : 160) + x - (widthScale / 2),
y + (lineHeight * line), size, color,
Text.substr(0, Text.find('\n')), maxWidth, maxHeight,
fnt);
} else { } else {
RenderD7::Draw::Text((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight); 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); Text = Text.substr(Text.find('\n') + 1);
line++; line++;
} }
if (maxWidth == 0) { if (maxWidth == 0) {
// Do the next WidthScale. // Do the next WidthScale.
if (fnt != nullptr) { if (fnt != nullptr) {
widthScale = RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt); widthScale = RenderD7::Draw::GetTextWidth(
size, Text.substr(0, Text.find('\n')), fnt);
} else { } else {
widthScale = RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n'))); widthScale =
RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')));
} }
} else { } else {
// And again. // And again.
if (fnt != nullptr) { if (fnt != nullptr) {
widthScale = std::min((float)maxWidth, RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt)); widthScale = std::min((float)maxWidth,
RenderD7::Draw::GetTextWidth(
size, Text.substr(0, Text.find('\n')), fnt));
} else { } else {
widthScale = std::min((float)maxWidth, RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')))); widthScale = std::min(
(float)maxWidth,
RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n'))));
} }
} }
if (fnt != nullptr) { 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); RenderD7::Draw::Text((currentScreen ? 200 : 160) + x - (widthScale / 2),
y + (lineHeight * line), size, color,
Text.substr(0, Text.find('\n')), maxWidth, maxHeight,
fnt);
} else { } else {
RenderD7::Draw::Text((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight); 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. // 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) { 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; C2D_Text c2d_text;
if (fnt != nullptr) { if (fnt != nullptr) {
@ -90,25 +115,39 @@ void RenderD7::Draw::Text(float x, float y, float size, u32 color, std::string T
heightScale = size; heightScale = size;
} else { } else {
if (fnt != nullptr) { if (fnt != nullptr) {
heightScale = std::min(size, size*(maxHeight/RenderD7::Draw::GetTextHeight(size, Text, fnt))); heightScale = std::min(
size,
size * (maxHeight / RenderD7::Draw::GetTextHeight(size, Text, fnt)));
} else { } else {
heightScale = std::min(size, size*(maxHeight/RenderD7::Draw::GetTextHeight(size, Text))); heightScale = std::min(
size, size * (maxHeight / RenderD7::Draw::GetTextHeight(size, Text)));
} }
} }
if (maxWidth == 0) { if (maxWidth == 0) {
C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, size, heightScale, color); C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, size, heightScale,
color);
} else { } else {
if (fnt != nullptr) { 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); C2D_DrawText(
&c2d_text, C2D_WithColor, x, y, 0.5f,
std::min(size, size * (maxWidth / RenderD7::Draw::GetTextWidth(
size, Text, fnt))),
heightScale, color);
} else { } else {
C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, std::min(size, size*(maxWidth/RenderD7::Draw::GetTextWidth(size, Text))), heightScale, color); 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) void RenderD7::Draw::TextRight(float x, float y, float size, u32 color,
{ std::string Text, int maxWidth, int maxHeight,
RenderD7::Draw::Text(x - RenderD7::Draw::GetTextWidth(size, Text, fnt), y, size, color, Text, maxWidth, maxHeight, fnt); 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. // Get String or Text Width.
float RenderD7::Draw::GetTextWidth(float size, std::string Text, C2D_Font fnt) { float RenderD7::Draw::GetTextWidth(float size, std::string Text, C2D_Font fnt) {
@ -122,7 +161,8 @@ float RenderD7::Draw::GetTextWidth(float size, std::string Text, C2D_Font fnt) {
} }
// Get String or Text Size. // Get String or Text Size.
void RenderD7::Draw::GetTextSize(float size, float *width, float *height, std::string Text, C2D_Font fnt) { void RenderD7::Draw::GetTextSize(float size, float *width, float *height,
std::string Text, C2D_Font fnt) {
C2D_Text c2d_text; C2D_Text c2d_text;
if (fnt != nullptr) { if (fnt != nullptr) {
C2D_TextFontParse(&c2d_text, fnt, TextBuf, Text.c_str()); C2D_TextFontParse(&c2d_text, fnt, TextBuf, Text.c_str());
@ -132,9 +172,9 @@ void RenderD7::Draw::GetTextSize(float size, float *width, float *height, std::s
C2D_TextGetDimensions(&c2d_text, size, size, width, height); C2D_TextGetDimensions(&c2d_text, size, size, width, height);
} }
// Get String or Text Height. // Get String or Text Height.
float RenderD7::Draw::GetTextHeight(float size, std::string Text, C2D_Font fnt) { float RenderD7::Draw::GetTextHeight(float size, std::string Text,
C2D_Font fnt) {
float height = 0; float height = 0;
if (fnt != nullptr) { if (fnt != nullptr) {
GetTextSize(size, NULL, &height, Text.c_str(), fnt); GetTextSize(size, NULL, &height, Text.c_str(), fnt);
@ -144,7 +184,7 @@ float RenderD7::Draw::GetTextHeight(float size, std::string Text, C2D_Font fnt)
return height; return height;
} }
Result RenderD7::Draw::LoadFont(C2D_Font &fnt, const char* Path) { Result RenderD7::Draw::LoadFont(C2D_Font &fnt, const char *Path) {
fnt = C2D_FontLoad(Path); // Only load if found. fnt = C2D_FontLoad(Path); // Only load if found.
return 0; return 0;
} }
@ -157,21 +197,20 @@ Result RenderD7::Draw::UnloadFont(C2D_Font &fnt) {
return 0; return 0;
} }
bool RenderD7::Draw::Circle(float x, float y, float radius, u32 color) bool RenderD7::Draw::Circle(float x, float y, float radius, u32 color) {
{
return C2D_DrawCircleSolid(x, y, 0.5f, radius, 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) 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); 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) 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(p1x, p1y, color, w, p1y, color, scale, 1);
C2D_DrawLine(w, p1y, color,w, h, 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(w, h, color, p1x, h, color, scale, 1);
C2D_DrawLine(p1x, h, color,p1x, p1y, color, scale, 1); C2D_DrawLine(p1x, h, color, p1x, p1y, color, scale, 1);
return true; return true;
} }

View File

@ -1,23 +1,20 @@
#include <renderd7/FileSystem.hpp>
#include <3ds.h> #include <3ds.h>
#include <cstring> #include <cstring>
//Debugging #include <renderd7/FileSystem.hpp>
// Debugging
#include <memory> #include <memory>
#include <renderd7/Ovl.hpp> #include <renderd7/Ovl.hpp>
#include <renderd7/Toast.hpp> #include <renderd7/Toast.hpp>
const char* RenderD7::FileSystem::GetPhysfsError() const char *RenderD7::FileSystem::GetPhysfsError() {
{
return PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()); return PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode());
} }
std::string RenderD7::FileSystem::Normalize(const std::string& input) std::string RenderD7::FileSystem::Normalize(const std::string &input) {
{
std::string out; std::string out;
bool seenSep = false, isSep = false; bool seenSep = false, isSep = false;
for (size_t i = 0; i < input.size(); ++i) for (size_t i = 0; i < input.size(); ++i) {
{
isSep = (input[i] == '/'); isSep = (input[i] == '/');
if (!isSep || !seenSep) if (!isSep || !seenSep)
@ -29,45 +26,43 @@ std::string RenderD7::FileSystem::Normalize(const std::string& input)
return out; return out;
} }
void RenderD7::FileSystem::Initialize() void RenderD7::FileSystem::Initialize() { RenderD7::FileSystem::savePath = ""; }
{
RenderD7::FileSystem::savePath = "";
}
int RenderD7::FileSystem::Init(const char* argv) int RenderD7::FileSystem::Init(const char *argv) {
{
int res = PHYSFS_init(argv); int res = PHYSFS_init(argv);
if (res != 1) if (res != 1) {
{ RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); "PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
} }
return res; return res;
} }
bool RenderD7::FileSystem::SetSource(const char* source) bool RenderD7::FileSystem::SetSource(const char *source) {
{
if (!PHYSFS_isInit()) if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
std::string searchPath = source; std::string searchPath = source;
if (!PHYSFS_mount(searchPath.c_str(), NULL, 1)) if (!PHYSFS_mount(searchPath.c_str(), NULL, 1))
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
return true; return true;
} }
bool RenderD7::FileSystem::SetIdentity(const char* name, bool append) bool RenderD7::FileSystem::SetIdentity(const char *name, bool append) {
{
if (!PHYSFS_isInit()) if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
std::string old = RenderD7::FileSystem::savePath; std::string old = RenderD7::FileSystem::savePath;
RenderD7::FileSystem::savePath = RenderD7::FileSystem::Normalize(RenderD7::FileSystem::GetUserDirectory() + "/save/" + name); RenderD7::FileSystem::savePath = RenderD7::FileSystem::Normalize(
RenderD7::FileSystem::GetUserDirectory() + "/save/" + name);
printf("Save Path set to %s\n", savePath.c_str()); printf("Save Path set to %s\n", savePath.c_str());
if (!old.empty()) if (!old.empty())
@ -81,28 +76,30 @@ bool RenderD7::FileSystem::SetIdentity(const char* name, bool append)
return true; return true;
} }
std::string RenderD7::FileSystem::GetSaveDirectory() std::string RenderD7::FileSystem::GetSaveDirectory() {
{ return RenderD7::FileSystem::Normalize(
return RenderD7::FileSystem::Normalize(RenderD7::FileSystem::GetUserDirectory() + "/save"); RenderD7::FileSystem::GetUserDirectory() + "/save");
} }
bool RenderD7::FileSystem::SetupWriteDirectory() bool RenderD7::FileSystem::SetupWriteDirectory() {
{
if (!PHYSFS_isInit()) if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
if (RenderD7::FileSystem::savePath.empty()) if (RenderD7::FileSystem::savePath.empty())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", "Path is Empty")); RenderD7::AddOvl(
std::make_unique<RenderD7::Toast>("PHYSFS-Error", "Path is Empty"));
return false; return false;
std::string tmpWritePath = RenderD7::FileSystem::savePath; std::string tmpWritePath = RenderD7::FileSystem::savePath;
std::string tmpDirectoryPath = RenderD7::FileSystem::savePath; std::string tmpDirectoryPath = RenderD7::FileSystem::savePath;
if (RenderD7::FileSystem::savePath.find(RenderD7::FileSystem::GetUserDirectory()) == 0) if (RenderD7::FileSystem::savePath.find(
{ RenderD7::FileSystem::GetUserDirectory()) == 0) {
tmpWritePath = RenderD7::FileSystem::GetUserDirectory(); tmpWritePath = RenderD7::FileSystem::GetUserDirectory();
tmpDirectoryPath = savePath.substr(RenderD7::FileSystem::GetUserDirectory().length()); tmpDirectoryPath =
savePath.substr(RenderD7::FileSystem::GetUserDirectory().length());
/* strip leading '/' characters from the path we want to create */ /* strip leading '/' characters from the path we want to create */
size_t startPosition = tmpDirectoryPath.find_first_not_of('/'); size_t startPosition = tmpDirectoryPath.find_first_not_of('/');
@ -111,33 +108,41 @@ bool RenderD7::FileSystem::SetupWriteDirectory()
tmpDirectoryPath = tmpDirectoryPath.substr(startPosition); tmpDirectoryPath = tmpDirectoryPath.substr(startPosition);
} }
if (!PHYSFS_setWriteDir(tmpWritePath.c_str())) if (!PHYSFS_setWriteDir(tmpWritePath.c_str())) {
{
printf("Failed to set write dir to %s\n", tmpWritePath.c_str()); printf("Failed to set write dir to %s\n", tmpWritePath.c_str());
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FormatString("Failed to set write dir to %s\n", tmpWritePath.c_str()))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Failed to set write dir to %s\n",
tmpWritePath.c_str())));
return false; return false;
} }
if (!RenderD7::FileSystem::CreateDirectory(tmpDirectoryPath.c_str())) if (!RenderD7::FileSystem::CreateDirectory(tmpDirectoryPath.c_str())) {
{
printf("Failed to create dir %s\n", tmpDirectoryPath.c_str()); printf("Failed to create dir %s\n", tmpDirectoryPath.c_str());
/* clear the write directory in case of error */ /* clear the write directory in case of error */
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FormatString("Failed to create dir %s\n", tmpDirectoryPath.c_str()))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FormatString("Failed to create dir %s\n",
tmpDirectoryPath.c_str())));
PHYSFS_setWriteDir(nullptr); PHYSFS_setWriteDir(nullptr);
return false; return false;
} }
if (!PHYSFS_setWriteDir(savePath.c_str())) if (!PHYSFS_setWriteDir(savePath.c_str())) {
{
printf("Failed to set write dir to %s\n", savePath.c_str()); printf("Failed to set write dir to %s\n", savePath.c_str());
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FormatString("Failed to set write dir to %s\n", savePath.c_str()))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Failed to set write dir to %s\n",
savePath.c_str())));
return false; return false;
} }
if (!PHYSFS_mount(savePath.c_str(), nullptr, 0)) if (!PHYSFS_mount(savePath.c_str(), nullptr, 0)) {
{ printf("Failed to mount write dir (%s)\n",
printf("Failed to mount write dir (%s)\n", RenderD7::FileSystem::GetPhysfsError()); RenderD7::FileSystem::GetPhysfsError());
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FormatString("Failed to mount write dir (%s)\n", RenderD7::FileSystem::GetPhysfsError()))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Failed to mount write dir (%s)\n",
RenderD7::FileSystem::GetPhysfsError())));
/* clear the write directory in case of error */ /* clear the write directory in case of error */
PHYSFS_setWriteDir(nullptr); PHYSFS_setWriteDir(nullptr);
return false; return false;
@ -146,24 +151,27 @@ bool RenderD7::FileSystem::SetupWriteDirectory()
return true; return true;
} }
std::string RenderD7::FileSystem::GetUserDirectory() std::string RenderD7::FileSystem::GetUserDirectory() {
{ return RenderD7::FileSystem::Normalize(
return RenderD7::FileSystem::Normalize(PHYSFS_getPrefDir("npi-d7", "renderd7")); PHYSFS_getPrefDir("npi-d7", "renderd7"));
} }
bool RenderD7::FileSystem::GetInfo(const char* filename, RenderD7::FileSystem::Info& info) bool RenderD7::FileSystem::GetInfo(const char *filename,
{ RenderD7::FileSystem::Info &info) {
if (!PHYSFS_isInit()) if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
PHYSFS_Stat stat = {}; PHYSFS_Stat stat = {};
if (!PHYSFS_stat(filename, &stat)) if (!PHYSFS_stat(filename, &stat))
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
info.mod_time = std::min<int64_t>(stat.modtime, RenderD7::FileSystem::MAX_STAMP); info.mod_time =
std::min<int64_t>(stat.modtime, RenderD7::FileSystem::MAX_STAMP);
info.size = std::min<int64_t>(stat.filesize, RenderD7::FileSystem::MAX_STAMP); info.size = std::min<int64_t>(stat.filesize, RenderD7::FileSystem::MAX_STAMP);
if (stat.filetype == PHYSFS_FILETYPE_REGULAR) if (stat.filetype == PHYSFS_FILETYPE_REGULAR)
@ -178,56 +186,63 @@ bool RenderD7::FileSystem::GetInfo(const char* filename, RenderD7::FileSystem::I
return true; return true;
} }
void RenderD7::FileSystem::GetDirectoryItems(const char* path, std::vector<std::string>& items) void RenderD7::FileSystem::GetDirectoryItems(const char *path,
{ std::vector<std::string> &items) {
if (!PHYSFS_isInit()) if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return; return;
char** results = PHYSFS_enumerateFiles(path); char **results = PHYSFS_enumerateFiles(path);
if (results == nullptr) if (results == nullptr)
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return; return;
for (char** item = results; *item != 0; item++) for (char **item = results; *item != 0; item++)
items.push_back(*item); items.push_back(*item);
PHYSFS_freeList(results); PHYSFS_freeList(results);
} }
bool RenderD7::FileSystem::OpenFile(File& file, const char* name, FileMode mode) bool RenderD7::FileSystem::OpenFile(File &file, const char *name,
{ FileMode mode) {
if (mode == FileMode_Closed) if (mode == FileMode_Closed)
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
if (!PHYSFS_isInit()) if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
if (file.handle) if (file.handle)
RenderD7::FileSystem::CloseFile(file); RenderD7::FileSystem::CloseFile(file);
if (mode == FileMode_Read && !PHYSFS_exists(name)) if (mode == FileMode_Read && !PHYSFS_exists(name)) {
{
printf("Could not open file %s, does not exist.\n", name); printf("Could not open file %s, does not exist.\n", name);
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FormatString("Could not open file %s, does not exist.\n", name))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Could not open file %s, does not exist.\n",
name)));
return false; return false;
} }
if ((mode == FileMode_Write) && if ((mode == FileMode_Write) &&
(PHYSFS_getWriteDir() == nullptr && RenderD7::FileSystem::SetupWriteDirectory())) (PHYSFS_getWriteDir() == nullptr &&
{ RenderD7::FileSystem::SetupWriteDirectory())) {
printf("Could not set write directory.\n"); printf("Could not set write directory.\n");
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FormatString("Could not set write directory.\n"))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Could not set write directory.\n")));
return false; return false;
} }
PHYSFS_getLastErrorCode(); PHYSFS_getLastErrorCode();
switch (mode) switch (mode) {
{
case FileMode_Read: case FileMode_Read:
file.handle = PHYSFS_openRead(name); file.handle = PHYSFS_openRead(name);
break; break;
@ -238,15 +253,16 @@ bool RenderD7::FileSystem::OpenFile(File& file, const char* name, FileMode mode)
break; break;
} }
if (!file.handle) if (!file.handle) {
{ const char *error = RenderD7::FileSystem::GetPhysfsError();
const char* error = RenderD7::FileSystem::GetPhysfsError();
if (error == nullptr) if (error == nullptr)
error = "unknown error"; error = "unknown error";
printf("Could not open file %s (%s)\n", name, error); printf("Could not open file %s (%s)\n", name, error);
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FormatString("Could not open file %s (%s)\n", name, error))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Could not open file %s (%s)\n", name, error)));
return false; return false;
} }
@ -256,8 +272,7 @@ bool RenderD7::FileSystem::OpenFile(File& file, const char* name, FileMode mode)
return true; return true;
} }
bool RenderD7::FileSystem::CloseFile(File& file) bool RenderD7::FileSystem::CloseFile(File &file) {
{
if (file.handle == nullptr || !PHYSFS_close(file.handle)) if (file.handle == nullptr || !PHYSFS_close(file.handle))
return false; return false;
@ -266,57 +281,62 @@ bool RenderD7::FileSystem::CloseFile(File& file)
return true; return true;
} }
bool RenderD7::FileSystem::CreateDirectory(const char* name) bool RenderD7::FileSystem::CreateDirectory(const char *name) {
{
if (!PHYSFS_isInit()) if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
if (PHYSFS_getWriteDir() == nullptr && !RenderD7::FileSystem::SetupWriteDirectory()) if (PHYSFS_getWriteDir() == nullptr &&
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); !RenderD7::FileSystem::SetupWriteDirectory())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
if (!PHYSFS_mkdir(name)) if (!PHYSFS_mkdir(name))
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
return true; return true;
} }
int64_t RenderD7::FileSystem::ReadFile(File& file, void* destination, int64_t size) int64_t RenderD7::FileSystem::ReadFile(File &file, void *destination,
{ int64_t size) {
if (!file.handle || file.mode != FileMode_Read) if (!file.handle || file.mode != FileMode_Read) {
{
printf("File is not opened for reading.\n"); printf("File is not opened for reading.\n");
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", "File is not opened for reading.\n")); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", "File is not opened for reading.\n"));
return 0; return 0;
} }
if (size > file.GetSize()) if (size > file.GetSize())
size = file.GetSize(); size = file.GetSize();
else if (size < 0) else if (size < 0) {
{
printf("Invalid read size %lld\n", size); printf("Invalid read size %lld\n", size);
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FormatString("Invalid read size %lld\n", size))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Invalid read size %lld\n", size)));
return 0; return 0;
} }
return PHYSFS_readBytes(file.handle, destination, (PHYSFS_uint64)size); return PHYSFS_readBytes(file.handle, destination, (PHYSFS_uint64)size);
} }
bool RenderD7::FileSystem::WriteFile(File& file, const void* data, int64_t size) bool RenderD7::FileSystem::WriteFile(File &file, const void *data,
{ int64_t size) {
if (!file.handle || file.mode != FileMode_Write) if (!file.handle || file.mode != FileMode_Write) {
{
printf("File is not opened for writing.\n"); printf("File is not opened for writing.\n");
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", "File is not opened for writing.\n")); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", "File is not opened for writing.\n"));
return false; return false;
} }
int64_t written = PHYSFS_writeBytes(file.handle, data, (PHYSFS_uint64)size); int64_t written = PHYSFS_writeBytes(file.handle, data, (PHYSFS_uint64)size);
if (written != size){ if (written != size) {
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError())); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false; return false;
} }

View File

@ -14,7 +14,8 @@ static u32 GetNextPowerOf2(u32 v) {
return (v >= 64 ? v : 64); return (v >= 64 ? v : 64);
} }
static bool C3DTexToC2DImage(C2D_Image *texture, u32 width, u32 height, u8 *buf) { static bool C3DTexToC2DImage(C2D_Image *texture, u32 width, u32 height,
u8 *buf) {
if (width >= 1024 || height >= 1024) if (width >= 1024 || height >= 1024)
return false; return false;
@ -43,18 +44,23 @@ static bool C3DTexToC2DImage(C2D_Image *texture, u32 width, u32 height, u8 *buf)
u32 h_pow2 = GetNextPowerOf2(subtex->height); u32 h_pow2 = GetNextPowerOf2(subtex->height);
subtex->left = 0.f; subtex->left = 0.f;
subtex->top = 1.f; subtex->top = 1.f;
subtex->right = (subtex->width /static_cast<float>(w_pow2)); subtex->right = (subtex->width / static_cast<float>(w_pow2));
subtex->bottom = (1.0 - (subtex->height / static_cast<float>(h_pow2))); subtex->bottom = (1.0 - (subtex->height / static_cast<float>(h_pow2)));
C3D_TexInit(tex, static_cast<u16>(w_pow2), static_cast<u16>(h_pow2), GPU_RGBA8); C3D_TexInit(tex, static_cast<u16>(w_pow2), static_cast<u16>(h_pow2),
GPU_RGBA8);
C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST); C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST);
std::memset(tex->data, 0, tex->size); std::memset(tex->data, 0, tex->size);
for (u32 x = 0; x < subtex->width; x++) { for (u32 x = 0; x < subtex->width; x++) {
for (u32 y = 0; y < subtex->height; y++) { 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 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; u32 src_pos = (y * subtex->width + x) * 4;
std::memcpy(&(static_cast<u8 *>(tex->data))[dst_pos], &(static_cast<u8 *>(buf))[src_pos], 4); std::memcpy(&(static_cast<u8 *>(tex->data))[dst_pos],
&(static_cast<u8 *>(buf))[src_pos], 4);
} }
} }
@ -69,51 +75,48 @@ static bool C3DTexToC2DImage(C2D_Image *texture, u32 width, u32 height, u8 *buf)
return false; return false;
} }
extern "C" extern "C" {
{ #include <renderd7/external/libnsbmp/libnsbmp.h>
#include <renderd7/external/libnsbmp/libnsbmp.h>
} }
static const u32 BYTES_PER_PIXEL = 4; static const u32 BYTES_PER_PIXEL = 4;
#define MAX_IMAGE_BYTES (48 * 1024 * 1024) #define MAX_IMAGE_BYTES (48 * 1024 * 1024)
namespace LIBBMP { namespace LIBBMP {
static void *bitmap_create(int width, int height, [[maybe_unused]] unsigned int state) { static void *bitmap_create(int width, int height,
[[maybe_unused]] unsigned int state) {
/* ensure a stupidly large (>50Megs or so) bitmap is not created */ /* ensure a stupidly large (>50Megs or so) bitmap is not created */
if ((static_cast<long long>(width) * static_cast<long long>(height)) > (MAX_IMAGE_BYTES/BYTES_PER_PIXEL)) if ((static_cast<long long>(width) * static_cast<long long>(height)) >
(MAX_IMAGE_BYTES / BYTES_PER_PIXEL))
return nullptr; return nullptr;
return std::calloc(width * height, BYTES_PER_PIXEL); return std::calloc(width * height, BYTES_PER_PIXEL);
}
static unsigned char *bitmap_get_buffer(void *bitmap) {
assert(bitmap);
return static_cast<unsigned char *>(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);
}
} }
static unsigned char *bitmap_get_buffer(void *bitmap) {
assert(bitmap);
return static_cast<unsigned char *>(bitmap);
}
unsigned Image_to_C3D(C2D_Image img, const std::vector<unsigned char>& bmpc) { 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<unsigned char> &bmpc) {
bmp_bitmap_callback_vt bitmap_callbacks = { bmp_bitmap_callback_vt bitmap_callbacks = {
LIBBMP::bitmap_create, LIBBMP::bitmap_create, LIBBMP::bitmap_destroy, LIBBMP::bitmap_get_buffer,
LIBBMP::bitmap_destroy, LIBBMP::bitmap_get_bpp};
LIBBMP::bitmap_get_buffer,
LIBBMP::bitmap_get_bpp
};
bmp_result code = BMP_OK; bmp_result code = BMP_OK;
bmp_image bmp; bmp_image bmp;
bmp_create(&bmp, &bitmap_callbacks); bmp_create(&bmp, &bitmap_callbacks);
code = bmp_analyse(&bmp, bmpc.size(), (u8*)bmpc.data()); code = bmp_analyse(&bmp, bmpc.size(), (u8 *)bmpc.data());
if (code != BMP_OK) { if (code != BMP_OK) {
bmp_finalise(&bmp); bmp_finalise(&bmp);
return 1; return 1;
@ -132,34 +135,34 @@ unsigned Image_to_C3D(C2D_Image img, const std::vector<unsigned char>& bmpc) {
return 3; return 3;
} }
} }
C2D_Image* texture = new C2D_Image(); C2D_Image *texture = new C2D_Image();
bool ret = C3DTexToC2DImage(texture, static_cast<u32>(bmp.width), static_cast<u32>(bmp.height), static_cast<u8 *>(bmp.bitmap)); bool ret = C3DTexToC2DImage(texture, static_cast<u32>(bmp.width),
static_cast<u32>(bmp.height),
static_cast<u8 *>(bmp.bitmap));
bmp_finalise(&bmp); bmp_finalise(&bmp);
delete texture; delete texture;
if (!ret) if (!ret) {
{
return 4; return 4;
} }
return 0; return 0;
} }
void RenderD7::Image::LoadPng(const std::string path) void RenderD7::Image::LoadPng(const std::string path) {
{ if (usedbgmsg) {
if (usedbgmsg) // RenderD7::Msg::Display("RenderD7", "Loading Png:" + path, Top);
{
//RenderD7::Msg::Display("RenderD7", "Loading Png:" + path, Top);
} }
std::vector<u8> ImageBuffer; std::vector<u8> ImageBuffer;
unsigned width, height; unsigned width, height;
if (loadet) if (loadet) {
{
C3D_TexDelete(this->img.tex); C3D_TexDelete(this->img.tex);
loadet = false; loadet = false;
} }
lodepng::decode(ImageBuffer, width, height, path); lodepng::decode(ImageBuffer, width, height, path);
this->img.tex = new C3D_Tex; 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)}); 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_TexInit(this->img.tex, 1024, 1024, GPU_RGBA8);
C3D_TexSetFilter(this->img.tex, GPU_LINEAR, GPU_LINEAR); C3D_TexSetFilter(this->img.tex, GPU_LINEAR, GPU_LINEAR);
@ -169,36 +172,39 @@ void RenderD7::Image::LoadPng(const std::string path)
for (u32 x = 0; x < width && x < 1024; x++) { for (u32 x = 0; x < width && x < 1024; x++) {
for (u32 y = 0; y < height && y < 1024; y++) { for (u32 y = 0; y < height && y < 1024; y++) {
const u32 dstPos = ((((y >> 3) * (1024 >> 3) + (x >> 3)) << 6) + const u32 dstPos = ((((y >> 3) * (1024 >> 3) + (x >> 3)) << 6) +
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) | ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) |
((x & 4) << 2) | ((y & 4) << 3))) * 4; ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) *
4;
const u32 srcPos = (y * width + x) * 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 + 0] =
((uint8_t *)this->img.tex->data)[dstPos + 1] = ImageBuffer.data()[srcPos + 2]; ImageBuffer.data()[srcPos + 3];
((uint8_t *)this->img.tex->data)[dstPos + 2] = ImageBuffer.data()[srcPos + 1]; ((uint8_t *)this->img.tex->data)[dstPos + 1] =
((uint8_t *)this->img.tex->data)[dstPos + 3] = ImageBuffer.data()[srcPos + 0]; 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; loadet = true;
} }
RenderD7::Image::~Image() 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<u8> &buffer)
{
std::vector<u8> ImageBuffer;
if (loadet) 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<u8> &buffer) {
std::vector<u8> ImageBuffer;
if (loadet) {
C3D_TexDelete(this->img.tex); C3D_TexDelete(this->img.tex);
loadet = false; loadet = false;
} }
@ -206,7 +212,9 @@ void RenderD7::Image::LoadPFromBuffer(const std::vector<u8> &buffer)
lodepng::decode(ImageBuffer, width, height, buffer); lodepng::decode(ImageBuffer, width, height, buffer);
img.tex = new C3D_Tex; 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)}); 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_TexInit(img.tex, 512, 512, GPU_RGBA8);
C3D_TexSetFilter(img.tex, GPU_LINEAR, GPU_LINEAR); C3D_TexSetFilter(img.tex, GPU_LINEAR, GPU_LINEAR);
@ -216,8 +224,9 @@ void RenderD7::Image::LoadPFromBuffer(const std::vector<u8> &buffer)
for (u32 x = 0; x < width && x < 512; x++) { for (u32 x = 0; x < width && x < 512; x++) {
for (u32 y = 0; y < height && y < 512; y++) { for (u32 y = 0; y < height && y < 512; y++) {
const u32 dstPos = ((((y >> 3) * (512 >> 3) + (x >> 3)) << 6) + const u32 dstPos = ((((y >> 3) * (512 >> 3) + (x >> 3)) << 6) +
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) | ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) |
((x & 4) << 2) | ((y & 4) << 3))) * 4; ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) *
4;
const u32 srcPos = (y * width + x) * 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 + 0] = ImageBuffer.data()[srcPos + 3];
@ -228,28 +237,24 @@ void RenderD7::Image::LoadPFromBuffer(const std::vector<u8> &buffer)
} }
} }
void RenderD7::Image::FromSheet(RenderD7::Sheet sheet, size_t index) void RenderD7::Image::FromSheet(RenderD7::Sheet sheet, size_t index) {}
{
} bool RenderD7::Image::Draw(float x, float y, float scaleX, float scaleY) {
if (loadet)
bool RenderD7::Image::Draw(float x, float y, float scaleX, float scaleY) return C2D_DrawImageAt(this->img, x, y, 0.5f, nullptr, scaleX, scaleY);
{
if(loadet) return C2D_DrawImageAt(this->img, x, y, 0.5f, nullptr, scaleX, scaleY);
return false; return false;
} }
void RenderD7::Image::LoadFromBitmap(BMP bitmap) void RenderD7::Image::LoadFromBitmap(BMP bitmap) {
{
loadet = false; loadet = false;
unsigned error = Image_to_C3D(this->img, bitmap.DATA()); unsigned error = Image_to_C3D(this->img, bitmap.DATA());
if (error == 0) if (error == 0) {
{
this->loadet = true; this->loadet = true;
} }
if(error) { if (error) {
std::cout << "BMP decoding error " << error << std::endl; std::cout << "BMP decoding error " << error << std::endl;
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("Bmp - Error", "Code: " + std::to_string(error))); RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"Bmp - Error", "Code: " + std::to_string(error)));
} }
} }

View File

@ -1,76 +1,66 @@
#include <renderd7/Fonts/NFontApi.hpp> #include <renderd7/Fonts/NFontApi.hpp>
#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation #define STB_TRUETYPE_IMPLEMENTATION // force following include to generate
// implementation
#include <renderd7/external/stb_truetype.h> #include <renderd7/external/stb_truetype.h>
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
#include <renderd7/external/stb_image_write.h> #include <renderd7/external/stb_image_write.h>
RenderD7::NFontApi::NFontApi() RenderD7::NFontApi::NFontApi() {}
{
} RenderD7::NFontApi::~NFontApi() {}
RenderD7::NFontApi::~NFontApi() void RenderD7::NFontApi::LoadTTF(std::string path) {
{
}
void RenderD7::NFontApi::LoadTTF(std::string path)
{
/////READ FILE /////READ FILE
unsigned char* buffer; unsigned char *buffer;
long size = 0; long size = 0;
FILE *ttf__ = fopen(path.c_str(), "rb"); FILE *ttf__ = fopen(path.c_str(), "rb");
fseek(ttf__, 0, SEEK_END); fseek(ttf__, 0, SEEK_END);
size = ftell(ttf__); size = ftell(ttf__);
fseek(ttf__, 0, SEEK_SET); fseek(ttf__, 0, SEEK_SET);
buffer = (unsigned char*)malloc(size); buffer = (unsigned char *)malloc(size);
fread(buffer, size, 1, ttf__); fread(buffer, size, 1, ttf__);
fclose(ttf__); fclose(ttf__);
/////Setup Font /////Setup Font
if (!stbtt_InitFont(&font, buffer, 0)) if (!stbtt_InitFont(&font, buffer, 0)) {
{
printf("failed\n"); printf("failed\n");
status+="failed\n"; status += "failed\n";
return; return;
} }
status+="success!\n"; status += "success!\n";
b_h = 128; b_h = 128;
b_w = 512; b_w = 512;
l_h = 24; /* line height */ l_h = 24; /* line height */
scale = stbtt_ScaleForPixelHeight(&font, l_h); scale = stbtt_ScaleForPixelHeight(&font, l_h);
stbtt_GetFontVMetrics(&font, &ascent,&decent,&linegap); stbtt_GetFontVMetrics(&font, &ascent, &decent, &linegap);
linespace = scale * (ascent - decent + linegap); linespace = scale * (ascent - decent + linegap);
baseline = (int) (ascent*scale); baseline = (int)(ascent * scale);
height = (int) ((ascent - decent)*scale); height = (int)((ascent - decent) * scale);
} }
unsigned char* RenderD7::NFontApi::GetGlyphBitmap(char glyph) unsigned char *RenderD7::NFontApi::GetGlyphBitmap(char glyph) {
{ // stbtt_GetGlyphBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1);
//stbtt_GetGlyphBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1);
stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1);
w = x1-x0; w = x1 - x0;
h = y1-y0; h = y1 - y0;
unsigned char* bitmap; unsigned char *bitmap;
bitmap = stbtt_GetCodepointBitmap(&font, scale, scale, glyph, &w, &h, 0, 0); bitmap = stbtt_GetCodepointBitmap(&font, scale, scale, glyph, &w, &h, 0, 0);
return bitmap; return bitmap;
} }
int RenderD7::NFontApi::GetGlyphHeight(char glyph) int RenderD7::NFontApi::GetGlyphHeight(char glyph) {
{
stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1);
w = x1-x0; w = x1 - x0;
h = y1-y0; h = y1 - y0;
return h; return h;
} }
int RenderD7::NFontApi::GetGlyphWidth(char glyph) int RenderD7::NFontApi::GetGlyphWidth(char glyph) {
{
stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1); stbtt_GetCodepointBitmapBox(&font, glyph, scale, scale, &x0, &y0, &x1, &y1);
w = x1-x0; w = x1 - x0;
h = y1-y0; h = y1 - y0;
return w; return w;
} }

View File

@ -2,8 +2,7 @@
extern bool currentScreen; extern bool currentScreen;
void RenderD7::OnScreen(C3D_RenderTarget *target) void RenderD7::OnScreen(C3D_RenderTarget *target) {
{
C2D_SceneBegin(target); C2D_SceneBegin(target);
currentScreen = (target == Top || target == TopRight) ? 1 : 0; currentScreen = (target == Top || target == TopRight) ? 1 : 0;
} }

View File

@ -1,21 +1,15 @@
#include <renderd7/Sheet.hpp> #include <renderd7/Sheet.hpp>
RenderD7::Sheet::Sheet() RenderD7::Sheet::Sheet() {
{
// //
} }
RenderD7::Sheet::~Sheet() RenderD7::Sheet::~Sheet() {
{
// //
} }
Result RenderD7::Sheet::Load(const char *path) Result RenderD7::Sheet::Load(const char *path) {
{
this->spritesheet = C2D_SpriteSheetLoad(path); this->spritesheet = C2D_SpriteSheetLoad(path);
return 0; return 0;
} }
void RenderD7::Sheet::Free() void RenderD7::Sheet::Free() { C2D_SpriteSheetFree(this->spritesheet); }
{
C2D_SpriteSheetFree(this->spritesheet);
}

View File

@ -1,60 +1,36 @@
#include <renderd7/Sprite.hpp> #include <renderd7/Sprite.hpp>
RenderD7::Sprite::Sprite() RenderD7::Sprite::Sprite() {
{
//
}
RenderD7::Sprite::~Sprite()
{
// //
} }
void RenderD7::Sprite::FromSheet(RenderD7::Sheet *sheet, size_t index) RenderD7::Sprite::~Sprite() {
{ //
}
void RenderD7::Sprite::FromSheet(RenderD7::Sheet *sheet, size_t index) {
C2D_SpriteFromSheet(&this->sprite, sheet->spritesheet, index); C2D_SpriteFromSheet(&this->sprite, sheet->spritesheet, index);
} }
bool RenderD7::Sprite::Draw() bool RenderD7::Sprite::Draw() { return C2D_DrawSprite(&this->sprite); }
{ void RenderD7::Sprite::SetCenter(float x, float y) {
return C2D_DrawSprite(&this->sprite);
}
void RenderD7::Sprite::SetCenter(float x, float y)
{
C2D_SpriteSetCenter(&this->sprite, x, y); C2D_SpriteSetCenter(&this->sprite, x, y);
} }
void RenderD7::Sprite::SetPos(float x, float y) void RenderD7::Sprite::SetPos(float x, float y) {
{
C2D_SpriteSetPos(&this->sprite, x, y); C2D_SpriteSetPos(&this->sprite, x, y);
} }
void RenderD7::Sprite::SetRotation(float rotation) void RenderD7::Sprite::SetRotation(float rotation) {
{
C2D_SpriteSetRotation(&this->sprite, rotation); C2D_SpriteSetRotation(&this->sprite, rotation);
} }
void RenderD7::Sprite::Rotate(float speed) void RenderD7::Sprite::Rotate(float speed) {
{
C2D_SpriteRotateDegrees(&this->sprite, speed); C2D_SpriteRotateDegrees(&this->sprite, speed);
} }
float RenderD7::Sprite::getHeigh() float RenderD7::Sprite::getHeigh() { return this->sprite.params.pos.h; }
{ float RenderD7::Sprite::getWidth() { return this->sprite.params.pos.w; }
return this->sprite.params.pos.h; float RenderD7::Sprite::getPosX() { return this->sprite.params.pos.x; }
} float RenderD7::Sprite::getPosY() { return this->sprite.params.pos.y; }
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) void RenderD7::Sprite::FromImage(RenderD7::Image *img) {
{
C2D_SpriteFromImage(&this->sprite, img->img); C2D_SpriteFromImage(&this->sprite, img->img);
} }
void RenderD7::Sprite::SetScale(float x, float y) void RenderD7::Sprite::SetScale(float x, float y) {
{
C2D_SpriteScale(&this->sprite, x, y); C2D_SpriteScale(&this->sprite, x, y);
} }

View File

@ -3,17 +3,17 @@
extern Log renderd7log; extern Log renderd7log;
RenderD7::SpriteSheetAnimation::SpriteSheetAnimation() RenderD7::SpriteSheetAnimation::SpriteSheetAnimation() {
{
renderd7log.Write("SpriteSheetAnimation createt!"); 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) void RenderD7::SpriteSheetAnimation::Setup(RenderD7::Sheet *sheet,
{ size_t imagecount, size_t startimage,
float frame_begin,
float frame_finish) {
D_totaltime = frame_begin; D_totaltime = frame_begin;
renderd7log.Write("frame_begin success"); renderd7log.Write("frame_begin success");
this->images = imagecount; this->images = imagecount;
@ -24,18 +24,15 @@ void RenderD7::SpriteSheetAnimation::Setup(RenderD7::Sheet *sheet, size_t imagec
renderd7log.Write("frame_finish success"); renderd7log.Write("frame_finish success");
RenderD7::SpriteSheetAnimation::FromSheet(this->sheet, startimage); RenderD7::SpriteSheetAnimation::FromSheet(this->sheet, startimage);
} }
void RenderD7::SpriteSheetAnimation::Play(float timespeed) void RenderD7::SpriteSheetAnimation::Play(float timespeed) {
{
D_totaltime += timespeed; D_totaltime += timespeed;
if (D_totaltime >= time) if (D_totaltime >= time) {
{
D_totaltime -= time; D_totaltime -= time;
imgs++; imgs++;
if (imgs == images) if (imgs == images) {
{
imgs = 0; imgs = 0;
} }
} }
RenderD7::SpriteSheetAnimation::FromSheet(sheet, imgs); RenderD7::SpriteSheetAnimation::FromSheet(sheet, imgs);
//RenderD7::SpriteSheetAnimation::Draw(); // RenderD7::SpriteSheetAnimation::Draw();
} }

View File

@ -1,31 +1,30 @@
#include <renderd7/Time.hpp>
#include <memory>
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <unistd.h>
#include <fstream> #include <fstream>
#include <memory>
#include <renderd7/Time.hpp>
#include <stdarg.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <string> #include <string>
#include <time.h>
#include <unistd.h>
std::string RenderD7::FormatString(std::string fmt_str, ...) {
std::string RenderD7::FormatString(std::string fmt_str, ...)
{
va_list ap; va_list ap;
char* fp = NULL; char *fp = NULL;
va_start(ap, fmt_str); va_start(ap, fmt_str);
vasprintf(&fp, fmt_str.c_str(), ap); vasprintf(&fp, fmt_str.c_str(), ap);
va_end(ap); va_end(ap);
std::unique_ptr<char, decltype(free)*> formatted(fp, free); std::unique_ptr<char, decltype(free) *> formatted(fp, free);
return std::string(formatted.get()); return std::string(formatted.get());
} }
std::string RenderD7::GetTimeStr(void) std::string RenderD7::GetTimeStr(void) {
{
time_t unixTime; time_t unixTime;
struct tm timeStruct; struct tm timeStruct;
time(&unixTime); time(&unixTime);
localtime_r(&unixTime, &timeStruct); localtime_r(&unixTime, &timeStruct);
return FormatString("%04i-%02i-%02i_%02i-%02i-%02i", timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, timeStruct.tm_mday, return FormatString("%04i-%02i-%02i_%02i-%02i-%02i",
timeStruct.tm_hour, timeStruct.tm_min, timeStruct.tm_sec); timeStruct.tm_year + 1900, timeStruct.tm_mon + 1,
timeStruct.tm_mday, timeStruct.tm_hour, timeStruct.tm_min,
timeStruct.tm_sec);
} }

View File

@ -1,37 +1,38 @@
#include <renderd7/Toast.hpp>
#include <renderd7/Draw.hpp> #include <renderd7/Draw.hpp>
#include <renderd7/Toast.hpp>
RenderD7::Toast::Toast(std::string head, std::string msg) RenderD7::Toast::Toast(std::string head, std::string msg) {
{
this->head = head; this->head = head;
this->msg = msg; this->msg = msg;
/*this->toast = RenderD7::BitmapPrinter(400, 70); /*this->toast = RenderD7::BitmapPrinter(400, 70);
this->toast.ClearBlank(); this->toast.ClearBlank();
this->toast.DrawRectFilled(0, 0, 400, 70, 40, 40, 40, 255); this->toast.DrawRectFilled(0, 0, 400, 70, 40, 40, 40, 255);
this->toast.DrawRectFilled(0, 0, 400, 25, 70, 70, 70, 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, 5, 0, RenderD7::Color::Hex("#ffffff"),
this->toast.DrawDebugText(4, 40, 0, RenderD7::Color::Hex("#ffffff"), this->msg); this->head); this->toast.DrawDebugText(4, 40, 0,
RenderD7::Color::Hex("#ffffff"), this->msg);
this->toastrendered->LoadPFromBuffer(BitmapConverter::ConvertData(toast.GetBitmap().DATA()));*/ this->toastrendered->LoadPFromBuffer(BitmapConverter::ConvertData(toast.GetBitmap().DATA()));*/
} }
void RenderD7::Toast::Draw(void) const void RenderD7::Toast::Draw(void) const {
{
RenderD7::OnScreen(Top); RenderD7::OnScreen(Top);
RenderD7::Draw::Rect(0, msgposy, 400, 70, RenderD7::Color::Hex("#111111")); RenderD7::Draw::Rect(0, msgposy, 400, 70, RenderD7::Color::Hex("#111111"));
RenderD7::Draw::Rect(0, msgposy, 400, 25, RenderD7::Color::Hex("#222222")); 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 + 3, 0.7f, RenderD7::Color::Hex("#ffffff"),
RenderD7::Draw::Text(2, msgposy+30, 0.6f, RenderD7::Color::Hex("#ffffff"), msg); head);
//toastrendered->Draw(0, msgposy); RenderD7::Draw::Text(2, msgposy + 30, 0.6f, RenderD7::Color::Hex("#ffffff"),
msg);
// toastrendered->Draw(0, msgposy);
} }
void RenderD7::Toast::Logic() void RenderD7::Toast::Logic() {
{ this->delay++ /*=1*(int)RenderD7::GetDeltaTime()*/;
this->delay++/*=1*(int)RenderD7::GetDeltaTime()*/; if (msgposy > 170 && delay < 2 * 60)
if (msgposy > 170 && delay < 2*60) msgposy--/*=(int)RenderD7::GetDeltaTime()*/; msgposy-- /*=(int)RenderD7::GetDeltaTime()*/;
if (delay >= 5*60) if (delay >= 5 * 60) {
{ msgposy++ /*=(int)RenderD7::GetDeltaTime*/;
msgposy++/*=(int)RenderD7::GetDeltaTime*/; if (msgposy > 400)
if(msgposy > 400) this->Kill(); this->Kill();
} }
} }

View File

@ -1,29 +1,36 @@
#include <renderd7/bmpconverter.hpp> #include <renderd7/bmpconverter.hpp>
namespace BitmapConverter{ namespace BitmapConverter {
//returns 0 if all went ok, non-0 if error // 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 // output image is always given in RGBA (with alpha channel), even if it's a BMP
unsigned decodeBMP(std::vector<unsigned char>& image, unsigned& w, unsigned& h, const std::vector<unsigned char>& bmp) { // without alpha channel
static const unsigned MINHEADER = 54; //minimum BMP header size unsigned decodeBMP(std::vector<unsigned char> &image, unsigned &w, unsigned &h,
const std::vector<unsigned char> &bmp) {
static const unsigned MINHEADER = 54; // minimum BMP header size
if(bmp.size() < MINHEADER) return -1; if (bmp.size() < MINHEADER)
if(bmp[0] != 'B' || bmp[1] != 'M') return 1; //It's not a BMP file if it doesn't start with marker 'BM' return -1;
unsigned pixeloffset = bmp[10] + 256 * bmp[11]; //where the pixel data starts if (bmp[0] != 'B' || bmp[1] != 'M')
//read width and height from BMP header 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; w = bmp[18] + bmp[19] * 256;
h = bmp[22] + bmp[23] * 256; h = bmp[22] + bmp[23] * 256;
//read number of channels from BMP header // 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. if (bmp[28] != 24 && bmp[28] != 32)
return 2; // only 24-bit and 32-bit BMPs are supported.
unsigned numChannels = bmp[28] / 8; unsigned numChannels = bmp[28] / 8;
//The amount of scanline bytes is width of image times channels, with extra bytes added if needed // The amount of scanline bytes is width of image times channels, with extra
//to make it a multiple of 4 bytes. // bytes added if needed to make it a multiple of 4 bytes.
unsigned scanlineBytes = w * numChannels; 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; 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); image.resize(w * h * 4);
@ -34,22 +41,23 @@ unsigned decodeBMP(std::vector<unsigned char>& image, unsigned& w, unsigned& h,
-each scanline has padding bytes to make it a multiple of 4 if needed -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. The 2D for loop below does all these 3 conversions at once.
*/ */
for(unsigned y = 0; y < h; y++) for (unsigned y = 0; y < h; y++)
for(unsigned x = 0; x < w; x++) { for (unsigned x = 0; x < w; x++) {
//pixel start byte position in the BMP // pixel start byte position in the BMP
unsigned bmpos = pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x; unsigned bmpos =
//pixel start byte position in the new raw image pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x;
// pixel start byte position in the new raw image
unsigned newpos = 4 * y * w + 4 * x; unsigned newpos = 4 * y * w + 4 * x;
if(numChannels == 3) { if (numChannels == 3) {
image[newpos + 0] = bmp[bmpos + 2]; //R image[newpos + 0] = bmp[bmpos + 2]; // R
image[newpos + 1] = bmp[bmpos + 1]; //G image[newpos + 1] = bmp[bmpos + 1]; // G
image[newpos + 2] = bmp[bmpos + 0]; //B image[newpos + 2] = bmp[bmpos + 0]; // B
image[newpos + 3] = 255; //A image[newpos + 3] = 255; // A
} else { } else {
image[newpos + 0] = bmp[bmpos + 2]; //R image[newpos + 0] = bmp[bmpos + 2]; // R
image[newpos + 1] = bmp[bmpos + 1]; //G image[newpos + 1] = bmp[bmpos + 1]; // G
image[newpos + 2] = bmp[bmpos + 0]; //B image[newpos + 2] = bmp[bmpos + 0]; // B
image[newpos + 3] = bmp[bmpos + 3]; //A image[newpos + 3] = bmp[bmpos + 3]; // A
} }
} }
return 0; return 0;
@ -64,21 +72,19 @@ std::vector<unsigned char> ConvertFile(std::string filename) {
unsigned w, h; unsigned w, h;
unsigned error = BitmapConverter::decodeBMP(image, w, h, bmp); unsigned error = BitmapConverter::decodeBMP(image, w, h, bmp);
if(error) { if (error) {
std::cout << "BMP decoding error " << error << std::endl; std::cout << "BMP decoding error " << error << std::endl;
} }
std::vector<unsigned char> png; std::vector<unsigned char> png;
error = lodepng::encode(png, image, w, h); error = lodepng::encode(png, image, w, h);
if(error) { if (error) {
std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl; std::cout << "PNG encoding error " << error << ": "
<< lodepng_error_text(error) << std::endl;
} }
return png; return png;
} }
std::vector<unsigned char> ConvertData(std::vector<unsigned char> data) { std::vector<unsigned char> ConvertData(std::vector<unsigned char> data) {
@ -87,20 +93,18 @@ std::vector<unsigned char> ConvertData(std::vector<unsigned char> data) {
unsigned w, h; unsigned w, h;
unsigned error = BitmapConverter::decodeBMP(image, w, h, data); unsigned error = BitmapConverter::decodeBMP(image, w, h, data);
if(error) { if (error) {
std::cout << "BMP decoding error " << error << std::endl; std::cout << "BMP decoding error " << error << std::endl;
} }
std::vector<unsigned char> png; std::vector<unsigned char> png;
error = lodepng::encode(png, image, w, h); error = lodepng::encode(png, image, w, h);
if(error) { if (error) {
std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl; std::cout << "PNG encoding error " << error << ": "
<< lodepng_error_text(error) << std::endl;
} }
return png; return png;
}
} }
} // namespace BitmapConverter

View File

@ -1,17 +1,16 @@
#include <3ds.h>
#include <renderd7/lang.hpp> #include <renderd7/lang.hpp>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <3ds.h> #include <unistd.h>
static nlohmann::json appJson; static nlohmann::json appJson;
std::string RenderD7::Lang::getSys() std::string RenderD7::Lang::getSys() {
{
u8 language = 1; u8 language = 1;
CFGU_GetSystemLanguage(&language); CFGU_GetSystemLanguage(&language);
switch(language) { switch (language) {
case 0: case 0:
return "jp"; // Japanese return "jp"; // Japanese
break; break;
@ -64,12 +63,12 @@ std::string RenderD7::Lang::getSys()
return "en"; // Fall back to English if missing return "en"; // Fall back to English if missing
break; break;
} }
} }
std::string RenderD7::Lang::get(const std::string &key) { 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<const std::string&>(); return appJson.at(key).get_ref<const std::string &>();
} }
void RenderD7::Lang::load(const std::string &lang) { void RenderD7::Lang::load(const std::string &lang) {
@ -82,7 +81,7 @@ void RenderD7::Lang::load(const std::string &lang) {
fclose(values); fclose(values);
} }
if (appJson.is_discarded()) if (appJson.is_discarded())
appJson = { }; appJson = {};
return; return;
} else { } else {
@ -92,7 +91,7 @@ void RenderD7::Lang::load(const std::string &lang) {
fclose(values); fclose(values);
} }
if (appJson.is_discarded()) if (appJson.is_discarded())
appJson = { }; appJson = {};
return; return;
} }
} }

View File

@ -2,51 +2,42 @@
#include <memory> #include <memory>
std::string Log::format(const std::string& fmt_str, ...) std::string Log::format(const std::string &fmt_str, ...) {
{
va_list ap; va_list ap;
char* fp = NULL; char *fp = NULL;
va_start(ap, fmt_str); va_start(ap, fmt_str);
vasprintf(&fp, fmt_str.c_str(), ap); vasprintf(&fp, fmt_str.c_str(), ap);
va_end(ap); va_end(ap);
std::unique_ptr<char, decltype(free)*> formatted(fp, free); std::unique_ptr<char, decltype(free) *> formatted(fp, free);
return std::string(formatted.get()); return std::string(formatted.get());
} }
std::string Log::logDate(void) std::string Log::logDate(void) {
{
time_t unixTime; time_t unixTime;
struct tm timeStruct; struct tm timeStruct;
time(&unixTime); time(&unixTime);
localtime_r(&unixTime, &timeStruct); localtime_r(&unixTime, &timeStruct);
return format("%04i-%02i-%02i_%02i-%02i-%02i", timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, timeStruct.tm_mday, return format("%04i-%02i-%02i_%02i-%02i-%02i", timeStruct.tm_year + 1900,
timeStruct.tm_hour, timeStruct.tm_min, timeStruct.tm_sec); 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) {
void Log::Init(const char *filename)
{
printf("%s\n", filename); printf("%s\n", filename);
std::string fn = filename; std::string fn = filename;
std::string name = fn + ".txt"; std::string name = fn + ".txt";
this->filename = name.c_str(); this->filename = name.c_str();
if ((access(name.c_str(), F_OK) == 0)) if ((access(name.c_str(), F_OK) == 0)) {
{
} } else {
else FILE *logfile = fopen((name.c_str()), "w");
{
FILE* logfile = fopen((name.c_str()), "w");
fclose(logfile); fclose(logfile);
} }
} }
void Log::Write(std::string debug_text) void Log::Write(std::string debug_text) {
{
printf("%s\n", debug_text.c_str()); printf("%s\n", debug_text.c_str());
std::ofstream logFile; std::ofstream logFile;
logFile.open((this->filename), std::ofstream::app); logFile.open((this->filename), std::ofstream::app);
@ -57,7 +48,4 @@ void Log::Write(std::string debug_text)
logFile << writeDebug << std::endl; logFile << writeDebug << std::endl;
logFile.close(); logFile.close();
} }
Log::~Log() Log::~Log() {}
{
}

File diff suppressed because it is too large Load Diff

View File

@ -25,13 +25,13 @@ typedef struct _WavHeader {
} WavHeader; } WavHeader;
static_assert(sizeof(WavHeader) == 44, "WavHeader size is not 44 bytes."); static_assert(sizeof(WavHeader) == 44, "WavHeader size is not 44 bytes.");
sound::sound(const string& path, int channel, bool toloop) { sound::sound(const string &path, int channel, bool toloop) {
if (isndspinit){ if (isndspinit) {
ndspSetOutputMode(NDSP_OUTPUT_STEREO); ndspSetOutputMode(NDSP_OUTPUT_STEREO);
ndspSetOutputCount(2); // Num of buffers ndspSetOutputCount(2); // Num of buffers
// Reading wav file // Reading wav file
FILE* fp = fopen(path.c_str(), "rb"); FILE *fp = fopen(path.c_str(), "rb");
if (!fp) { if (!fp) {
printf("Could not open the WAV file: %s\n", path.c_str()); printf("Could not open the WAV file: %s\n", path.c_str());
@ -48,7 +48,7 @@ sound::sound(const string& path, int channel, bool toloop) {
} }
// Verify the header. // Verify the header.
static const char RIFF_magic[4] = {'R','I','F','F'}; static const char RIFF_magic[4] = {'R', 'I', 'F', 'F'};
if (memcmp(wavHeader.magic, RIFF_magic, sizeof(wavHeader.magic)) != 0) { if (memcmp(wavHeader.magic, RIFF_magic, sizeof(wavHeader.magic)) != 0) {
// Incorrect magic number. // Incorrect magic number.
printf("Wrong file format.\n"); printf("Wrong file format.\n");
@ -70,7 +70,7 @@ sound::sound(const string& path, int channel, bool toloop) {
dataSize = ftell(fp) - sizeof(wavHeader); dataSize = ftell(fp) - sizeof(wavHeader);
// Allocating and reading samples // Allocating and reading samples
data = static_cast<u8*>(linearAlloc(dataSize)); data = static_cast<u8 *>(linearAlloc(dataSize));
fseek(fp, 44, SEEK_SET); fseek(fp, 44, SEEK_SET);
fread(data, 1, dataSize, fp); fread(data, 1, dataSize, fp);
fclose(fp); fclose(fp);
@ -79,13 +79,11 @@ sound::sound(const string& path, int channel, bool toloop) {
// Find the right format // Find the right format
u16 ndspFormat; u16 ndspFormat;
if (wavHeader.bits_per_sample == 8) { if (wavHeader.bits_per_sample == 8) {
ndspFormat = (wavHeader.channels == 1) ? ndspFormat = (wavHeader.channels == 1) ? NDSP_FORMAT_MONO_PCM8
NDSP_FORMAT_MONO_PCM8 : : NDSP_FORMAT_STEREO_PCM8;
NDSP_FORMAT_STEREO_PCM8;
} else { } else {
ndspFormat = (wavHeader.channels == 1) ? ndspFormat = (wavHeader.channels == 1) ? NDSP_FORMAT_MONO_PCM16
NDSP_FORMAT_MONO_PCM16 : : NDSP_FORMAT_STEREO_PCM16;
NDSP_FORMAT_STEREO_PCM16;
} }
ndspChnReset(channel); ndspChnReset(channel);
@ -96,15 +94,16 @@ sound::sound(const string& path, int channel, bool toloop) {
// Create and play a wav buffer // Create and play a wav buffer
memset(&waveBuf, 0, sizeof(waveBuf)); memset(&waveBuf, 0, sizeof(waveBuf));
waveBuf.data_vaddr = reinterpret_cast<u32*>(data); waveBuf.data_vaddr = reinterpret_cast<u32 *>(data);
waveBuf.nsamples = dataSize / (wavHeader.bits_per_sample >> 3); waveBuf.nsamples = dataSize / (wavHeader.bits_per_sample >> 3);
waveBuf.looping = toloop; waveBuf.looping = toloop;
waveBuf.status = NDSP_WBUF_FREE; waveBuf.status = NDSP_WBUF_FREE;
chnl = channel;} chnl = channel;
}
} }
sound::~sound() { sound::~sound() {
if (isndspinit){ if (isndspinit) {
waveBuf.data_vaddr = 0; waveBuf.data_vaddr = 0;
waveBuf.nsamples = 0; waveBuf.nsamples = 0;
waveBuf.looping = false; waveBuf.looping = false;
@ -113,18 +112,23 @@ sound::~sound() {
if (data) { if (data) {
linearFree(data); linearFree(data);
}} }
}
} }
void sound::play() { void sound::play() {
if (isndspinit){ if (isndspinit) {
if (!data) return; if (!data)
return;
DSP_FlushDataCache(data, dataSize); DSP_FlushDataCache(data, dataSize);
ndspChnWaveBufAdd(chnl, &waveBuf);} ndspChnWaveBufAdd(chnl, &waveBuf);
}
} }
void sound::stop() { void sound::stop() {
if (isndspinit){ if (isndspinit) {
if (!data) return; if (!data)
ndspChnWaveBufClear(chnl);} return;
ndspChnWaveBufClear(chnl);
}
} }

View File

@ -1,26 +1,26 @@
#include <renderd7/thread.hpp> #include <renderd7/thread.hpp>
namespace RenderD7 { namespace RenderD7 {
void Threads::Exit() void Threads::Exit() {}
{ Thread::Thread() : m_started(false), m_running(false) { /* do nothing */
}
} Thread::Thread(std::function<void(RenderD7::Parameter)> t_function,
Thread::Thread() : RenderD7::Parameter t_parameter, bool t_autostart,
m_started(false), bool t_detached, unsigned long long int t_stackSize)
m_running(false) { /* do nothing */ } : m_started(false), m_running(false) {
Thread::Thread(std::function<void(RenderD7::Parameter)> 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); initialize(t_function, t_parameter, t_autostart, t_detached, t_stackSize);
} }
Thread::~Thread() { Thread::~Thread() {
join(); join();
if (m_started) threadFree(m_thread); if (m_started)
} threadFree(m_thread);
}
void Thread::initialize(std::function<void(RenderD7::Parameter)> t_function, RenderD7::Parameter t_parameter, bool t_autostart, bool t_detached, unsigned long long int t_stackSize) { void Thread::initialize(std::function<void(RenderD7::Parameter)> t_function,
RenderD7::Parameter t_parameter, bool t_autostart,
bool t_detached, unsigned long long int t_stackSize) {
m_stackSize = t_stackSize; m_stackSize = t_stackSize;
m_data.m_parameter = t_parameter; m_data.m_parameter = t_parameter;
m_data.m_function = t_function; m_data.m_function = t_function;
@ -29,53 +29,51 @@ namespace RenderD7 {
if (t_autostart) { if (t_autostart) {
start(t_detached); start(t_detached);
} }
} }
void Thread::setStackSize(unsigned long long int t_stackSize) { void Thread::setStackSize(unsigned long long int t_stackSize) {
m_stackSize = t_stackSize; m_stackSize = t_stackSize;
} }
void Thread::start(bool t_detached) { void Thread::start(bool t_detached) {
if (!m_running) { if (!m_running) {
m_started = true; m_started = true;
m_running = true; m_running = true;
s32 prio; s32 prio;
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
m_thread = threadCreate(threadFunction, &m_data, m_stackSize, prio + 1, -2, t_detached); m_thread = threadCreate(threadFunction, &m_data, m_stackSize, prio + 1, -2,
} t_detached);
} }
}
void Thread::kill() { void Thread::kill() {
threadDetach(m_thread); threadDetach(m_thread);
m_running = false; m_running = false;
m_started = false; m_started = false;
} }
void Thread::join(long long unsigned int t_timeout) { void Thread::join(long long unsigned int t_timeout) {
if (m_running) { if (m_running) {
threadJoin(m_thread, t_timeout); threadJoin(m_thread, t_timeout);
threadFree(m_thread); threadFree(m_thread);
m_running = false; m_running = false;
m_started = false; m_started = false;
} }
} }
bool Thread::isRunning() { bool Thread::isRunning() { return m_running; }
return m_running;
}
void Thread::sleep() { void Thread::sleep() { svcSleepThread(0); }
svcSleepThread(0);
}
void Thread::sleep(int t_milliseconds) { void Thread::sleep(int t_milliseconds) {
svcSleepThread(1000000 * t_milliseconds); svcSleepThread(1000000 * t_milliseconds);
} }
// private methods // private methods
void Thread::threadFunction(void* arg) { void Thread::threadFunction(void *arg) {
RenderD7::Thread::ThreadData data = *static_cast<RenderD7::Thread::ThreadData*>(arg); RenderD7::Thread::ThreadData data =
*static_cast<RenderD7::Thread::ThreadData *>(arg);
data.m_function(data.m_parameter); data.m_function(data.m_parameter);
*data.m_running = false; *data.m_running = false;
}
} }
} // namespace RenderD7