21 Commits

Author SHA1 Message Date
8b70d0e9b7 Format to LLVL 2022-11-12 23:19:41 +01:00
36e5676d9f Ehh 2022-08-22 17:18:26 +01:00
f706193945 Offset 2022-08-22 17:14:19 +01:00
e24b704809 __ 2022-08-22 17:03:51 +01:00
91bbcdb7a7 Some DBG Stuff 2022-08-04 02:50:37 +02:00
2cb54dd570 __ 2022-08-04 01:47:07 +02:00
90dde05b79 __ 2022-08-04 01:13:26 +02:00
1ae4ff72d3 __ 2022-07-31 10:02:29 +02:00
9213a1d5dd Implement Experiment of NFontApi 2022-07-31 01:23:39 +02:00
ca52e6dae6 __ 2022-07-30 15:49:44 +02:00
83946b1e66 Fix A Lot of Stuff 2022-07-30 14:42:02 +02:00
61cb41ae29 Big CleanUp 2022-07-29 13:19:31 +02:00
bca1c36f75 A Lot of Bugfixes 2022-07-28 14:30:09 +02:00
3270842a1b __ 2022-07-27 11:00:57 +02:00
bd7d21d489 __ 2022-07-27 10:55:52 +02:00
cc5d669ab4 Add Logo to Readme 2022-07-25 16:53:29 +02:00
2c38997b4c Add Logo 2022-07-25 16:50:41 +02:00
a49bcd8712 awd 2022-07-25 14:42:58 +02:00
dbaa4d912a D 2022-07-25 12:12:12 +02:00
8f2c877197 Implement Benchm,arking System for BitmapPrinter 2022-07-25 11:31:41 +02:00
1ee4f6849e Update to use releases 2022-07-25 09:06:40 +02:00
50 changed files with 10512 additions and 4290 deletions

65
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,65 @@
{
"files.associations": {
"array": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"numeric": "cpp",
"type_traits": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"optional": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"typeinfo": "cpp",
"utility": "cpp",
"atomic": "cpp",
"bit": "cpp",
"bitset": "cpp",
"chrono": "cpp",
"codecvt": "cpp",
"condition_variable": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"map": "cpp",
"iomanip": "cpp",
"memory_resource": "cpp",
"ratio": "cpp",
"regex": "cpp",
"shared_mutex": "cpp",
"valarray": "cpp",
"random": "cpp",
"cuchar": "cpp",
"compare": "cpp",
"concepts": "cpp",
"numbers": "cpp"
}
}

4
BuildAndInstall.sh Executable file
View File

@ -0,0 +1,4 @@
export DEVKITARM=/opt/devkitpro/devkitARM/
export DEVKITPRO=/opt/devkitpro/
make -j12
make install

View File

@ -1,15 +1,13 @@
# RenderD7 # RenderD7 <img alt="LOGO" src="https://github.com/NPI-D7/RenderD7/blob/main/logo.png" height="30">
RenderD7 is now LibRenderD7. RenderD7 is now LibRenderD7.
### Installation (Ubuntu) ### Installation (Ubuntu)
first run this first run this
`sudo su` `sudo su`
then this then this
``` ```
git clone https://github.com/NPI-D7/RenderD7.git curl -L https://github.com/NPI-D7/RenderD7/releases/download/v0.8.0-pre1/renderd7-0.8.0.tar.bz2 -o renderd7-0.8.0.tar.bz2
cd RenderD7 mkdir -p /opt/devkitpro/libctru
export DEVKITARM=/opt/devkitpro/devkitARM/ bzip2 -cd renderd7-0.8.0.tar.bz2 | tar -xf - -C /opt/devkitpro/libctru
export DEVKITPRO=/opt/devkitpro/
make install
``` ```
Make sure that `-lrenderd7` is before `-lcitro2d`, `-lcitro3d`, `-lctru`. Make sure that `-lrenderd7` is before `-lcitro2d`, `-lcitro3d`, `-lctru`.

View File

@ -0,0 +1,111 @@
#pragma once
#include <string>
#include <vector>
#include <renderd7/bmp.hpp>
#include <renderd7/bmpconverter.hpp>
#include <renderd7/Image.hpp>
#include <renderd7/Screen.hpp>
#include <renderd7/Time.hpp>
#include <renderd7/Fonts/NFontApi.hpp>
namespace RenderD7 {
enum Encoder {
BITMAP, ///< Encode Data to Bitmap
DIRECT, ///< Encode Direct to Framebuffer(No Decoder Required)
C3D ///< Encode Directly to C3D_Tex (Just an Idea)
};
enum Decoder {
BITMAP2C3D, ///< Decode and Encode to C3D_Tex (Currently Fastest) (47,4ms)
BITMAP2PNG2C3D ///< Decode Bitmap end Convert to Png, then C3D (Very Slow)
///< (201,4ms)
};
class BitmapPrinter {
public:
BitmapPrinter(int w, int h);
~BitmapPrinter();
bool DecodeFile(std::string file);
void SetDecoder(Decoder deccc) { decc = deccc; }
void DrawPixel(int x, int y, u8 b, u8 g, u8 r, u8 a);
void DrawRect(int x, int y, int w, int h, u8 line_w, u8 b, u8 g, u8 r, u8 a);
void DrawRectFilled(int x, int y, int w, int h, u8 b, u8 g, u8 r, u8 a);
void UsePreMap(BMP map);
void UsePrePrintMap(BitmapPrinter printmap);
BMP GetBitmap() { return bitmap; }
void SaveBmp(std::string name);
void SavePng(std::string name);
void CreateScreen(C3D_RenderTarget *target);
bool DrawScreenDirectF(int framerate);
bool DrawScreenDirect();
void DrawScreenF(int framerate);
void DrawScreen();
bool UpdateScreenF(int framerate);
bool UpdateScreen();
void Clear(u8 b = 0, u8 g = 0, u8 r = 0, u8 a = 255);
void ClearBlank();
RenderD7::Image GetImage();
/// Test to Find out The Best Settings for BitmapPrinter
void Benchmark();
/// Setup the Benchmark
/// \param framerate The Fps of the ScreenUpdates
void SetupBenchmark(int framerate);
bool IsBenchmarkRunning() { return this->benchmark; }
void DrawDebugText(int x, int y, int t_size, u32 color, std::string text);
void DrawText(int x, int y, float t_size, u32 color, std::string text,
RenderD7::NFontApi font);
private:
// funcs
bool Decode(Decoder deccc);
void DrawDebugChar(u32 posX, u32 posY, int t_size, u32 color, char character);
void DrawChar(int posX, int posY, float t_size, u32 color, char character,
RenderD7::NFontApi font);
// parameter
int frame = 0;
RenderD7::Image renderframe;
bool isscreen = false;
C3D_RenderTarget *targetr;
BMP bitmap = BMP(
20, 20,
true); // Need to Set e Predefined Bitmap. If not the System will Crash.
BMP blank = BMP(
20, 20,
true); // Need to Set e Predefined Bitmap. If not the System will Crash.
///////////////////////////////////////////////////////////////////////////////////////////////////
// Benchmark Stuff;
int testfpsd;
bool benchmark = false;
bool setupbenchmark;
float frametime = 0;
uint64_t lastTime = 0;
float dtt = 0.f;
float dtt2 = 0.f;
float dtt3 = 0.f;
float timer = 0;
float mhdtt = 0;
float mdtt2;
float mdtt3;
float fpsClock = 0.f;
int frameCounter = 0, fps = 0;
std::vector<float> hdttt;
std::vector<float> hdttt2;
std::vector<float> hdttt3;
std::vector<int> fpscountc;
int renderedframes = 0;
int testfps = 60;
Encoder encc = Encoder::BITMAP;
Decoder decc = Decoder::BITMAP2C3D;
////////////////////////////////////////////////////////////////////////////////////////////////
};
} // namespace RenderD7

View File

@ -1,23 +0,0 @@
#pragma once
#include <renderd7/Time.hpp>
namespace rnd7 {
class Clock {
public:
Clock() {};
virtual ~Clock() {};
virtual Time getCurrentTime() const { return Time{}; };
Time getElapsedTime() const;
Time restart();
protected:
Time m_startTime; ///< Time of last reset, in microseconds
};
}

View File

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

28
include/renderd7/Draw.hpp Normal file
View File

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

View File

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

View File

@ -0,0 +1,142 @@
#pragma once
#include <bitset>
#include <iostream>
#include <string>
#include <vector>
#include <renderd7/external/stb_truetype.h>
#define MAXUNICODE 0x10FFFF
namespace RenderD7 {
inline int utf8_decode(const char *o) {
static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
const unsigned char *s = (const unsigned char *)o;
unsigned int c = s[0];
unsigned int res = 0; /* final result */
if (c < 0x80) /* ascii? */
res = c;
else {
int count = 0; /* to count number of continuation bytes */
while (c & 0x40) { /* still have continuation bytes? */
int cc = s[++count]; /* read next byte */
if ((cc & 0xC0) != 0x80) /* not a continuation byte? */
return -1; /* invalid byte sequence */
res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */
c <<= 1; /* to test next bit */
}
res |= ((c & 0x7F) << (count * 5)); /* add first byte */
if (count > 3 || res > MAXUNICODE || res <= limits[count])
return -1; /* invalid byte sequence */
s += count; /* skip continuation bytes read */
}
return res;
}
inline std::string IntToUtf8(int convertval) {
// We only care about plane 1 right now,
// but know that we have other options (0x10FFFF)
// Technically UTF-8 is "limited" to 4 bytes, so it's not
// Like it matters much anyways these days
if (convertval == 0)
return " ";
if ((convertval <= 0x7F) && (convertval > 0x00)) {
std::string out(".");
std::bitset<8> x(convertval);
unsigned long l = x.to_ulong();
unsigned char c = static_cast<unsigned char>(l);
out[0] = c;
return out;
} else if ((convertval >= 0x80) && (convertval <= 0x07FF)) {
std::string out("..");
int firstShift = (convertval >> 0x06) ^ 0xC0;
int secondShift = ((convertval ^ 0xFFC0) | 0x80) & ~0x40;
std::bitset<8> first(firstShift);
std::bitset<8> last(secondShift);
unsigned long l = first.to_ulong();
unsigned char c = static_cast<unsigned char>(l);
out[0] = c;
unsigned long ltwo = last.to_ulong();
unsigned char ctwo = static_cast<unsigned char>(ltwo);
out[1] = ctwo;
return out;
} else if ((convertval >= 0x0800) && (convertval <= 0xFFFF)) {
std::string out("...");
int firstShift = ((convertval ^ 0xFC0FFF) >> 0x0C) | 0xE0;
int secondShift = (((convertval ^ 0xFFF03F) >> 0x06) | 0x80) & ~0x40;
int thirdShift = ((convertval ^ 0xFFFC0) | 0x80) & ~0x40;
std::bitset<8> first(firstShift);
std::bitset<8> second(secondShift);
std::bitset<8> third(thirdShift);
unsigned long lone = first.to_ulong();
unsigned char cone = static_cast<unsigned char>(lone);
out[0] = cone;
unsigned long ltwo = second.to_ulong();
unsigned char ctwo = static_cast<unsigned char>(ltwo);
out[1] = ctwo;
unsigned long lthree = third.to_ulong();
unsigned char cthree = static_cast<unsigned char>(lthree);
out[2] = cthree;
return out;
} else {
return " ";
}
}
#define I2U82I(val) RenderD7::utf8_decode(RenderD7::IntToUtf8(val).c_str())
class NFontApi {
public:
NFontApi();
~NFontApi();
void LoadTTF(std::string path);
unsigned char *GetGlyphBitmap(char glyph);
std::string GetStatus() { return status; }
float GetScale() { return scale; }
int GetGlyphWidth(char glyph);
int GetGlyphHeight(char glyph);
int GetLineHeight() { return l_h; }
int GetBaseHeight() { return height; }
private:
std::string status;
int height;
float scale;
int b_w;
int b_h;
int l_h;
int w;
int h;
int x0, y0, x1, y1;
int ascent, baseline, decent, linegap;
int linespace;
stbtt_fontinfo font;
};
} // namespace RenderD7

View File

@ -0,0 +1,46 @@
#pragma once
#include <citro2d.h>
#include <citro3d.h>
#include <memory>
#include <renderd7/Sheet.hpp>
#include <renderd7/bmp.hpp>
#include <renderd7/bmpconverter.hpp>
#include <cassert>
#include <cstring>
#include <renderd7/Color.hpp>
#include <renderd7/external/lodepng.h>
namespace RenderD7 {
/// Image Class
class Image {
public:
Image() {}
~Image();
void Unload();
/// Load Image from Png
/// \param path path to png file
void LoadPng(const std::string path);
/// Load the Image from buffer
/// \param buffer the frame buffer
void LoadPFromBuffer(const std::vector<u8> &buffer);
void LoadFromBitmap(BMP bitmap);
/// Draw the Image directly
/// \param x The x position
/// \param y the y position
/// \param scaleX x scale from 0.0 to 1.0
/// \param scaleY y scale from 0.0 to 1.0
bool Draw(float x, float y, float scaleX = 1.0f, float scaleY = 1.0f);
/// \brief Get The Image
/// \return C2D_Image
C2D_Image Get() { return this->img; }
void FromSheet(RenderD7::Sheet sheet, size_t index);
/// \param img this is the C2D_Image
C2D_Image img;
/// \param loadet whether the image is loadet or not
bool loadet = false;
};
} // namespace RenderD7

17
include/renderd7/Ovl.hpp Normal file
View File

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

View File

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

View File

@ -0,0 +1,21 @@
#pragma once
#include <citro2d.h>
#include <citro3d.h>
namespace RenderD7 {
/** The Spritesheet Class */
class Sheet {
public:
/// Construct sheet
Sheet();
// Deconstruct sheet
~Sheet();
/// Load a Sritesheet
/// \param path Path to the Spritesheet (.t3x)
Result Load(const char *path);
/// Unload the Spritesheet
void Free();
/// The Spritesheet
C2D_SpriteSheet spritesheet;
};
} // namespace RenderD7

View File

@ -0,0 +1,39 @@
#pragma once
#include <citro2d.h>
#include <citro3d.h>
#include <renderd7/Image.hpp>
#include <renderd7/Sheet.hpp>
namespace RenderD7 {
/// Sprite Class
class Sprite {
public:
/// \brief Construct Sprite
Sprite();
/// \brief Deconstruct Sprite
~Sprite();
/// \brief Load a Sprite From SpriteSheet
/// \param sheet the Sheet to load from.(RenderD7::Sheet)
/// \param index the number of the Sprite in the Sheet
void FromSheet(RenderD7::Sheet *sheet, size_t index);
/// \brief Load a Sprite From SpriteSheet
/// \param img the Image to load from.(RenderD7::Image)
void FromImage(RenderD7::Image *img);
bool Draw();
void SetCenter(float x, float y);
void SetPos(float x, float y);
void SetScale(float x, float y);
void SetRotation(float rotation);
void Rotate(float speed);
float getWidth();
float getHeigh();
float getPosX();
float getPosY();
private:
C2D_ImageTint tint;
C2D_Sprite sprite;
};
} // namespace RenderD7

View File

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

View File

@ -1,82 +1,7 @@
namespace rnd7 { #pragma once
class Time { #include <string>
public:
Time(); namespace RenderD7 {
std::string FormatString(std::string fmt_str, ...);
float asSeconds() const; std::string GetTimeStr(void);
} // namespace RenderD7
int asMilliseconds() const;
long asMicroseconds() const;
static const Time Zero_;
private:
friend Time seconds(float);
friend Time milliseconds(int);
friend Time microseconds(long);
explicit Time(long microseconds);
private:
long m_microseconds; ///< Time value stored as microseconds
};
Time seconds(float amount);
Time milliseconds(int amount);
Time microseconds(long amount);
bool operator==(Time left, Time right);
bool operator!=(Time left, Time right);
bool operator<(Time left, Time right);
bool operator>(Time left, Time right);
bool operator<=(Time left, Time right);
bool operator>=(Time left, Time right);
Time operator-(Time right);
Time operator+(Time left, Time right);
Time &operator+=(Time &left, Time right);
Time operator-(Time left, Time right);
Time &operator-=(Time &left, Time right);
Time operator*(Time left, float right);
Time operator*(Time left, long right);
Time operator*(float left, Time right);
Time operator*(long left, Time right);
Time &operator*=(Time &left, float right);
Time &operator*=(Time &left, long right);
Time operator/(Time left, float right);
Time operator/(Time left, long right);
Time &operator/=(Time &left, float right);
Time &operator/=(Time &left, long right);
float operator/(Time left, Time right);
Time operator%(Time left, Time right);
Time &operator%=(Time &left, Time right);
}

View File

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

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,56 +281,53 @@ 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) {
if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) {
return 59;
} }
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) {
//
}*/
// 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;
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;
} }
//}
} }
} }
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;
@ -314,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;
@ -327,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;
@ -337,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;
@ -381,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;
@ -399,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;
@ -417,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;
@ -435,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;
@ -453,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;
@ -471,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;
@ -489,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;
@ -507,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;
@ -623,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;
@ -639,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
@ -701,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

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

5077
include/renderd7/external/stb_truetype.h vendored Normal file

File diff suppressed because it is too large Load Diff

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,49 +1,68 @@
#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/BitmapPrinter.hpp>
#include <renderd7/lang.hpp> #include <renderd7/Color.hpp>
#include <renderd7/parameter.hpp> #include <renderd7/Draw.hpp>
#include <renderd7/thread.hpp> #include <renderd7/Image.hpp>
#include <renderd7/ini.hpp> #include <renderd7/Ovl.hpp>
#include <renderd7/stringtool.hpp> #include <renderd7/Screen.hpp>
#include <renderd7/Clock.hpp> #include <renderd7/Sheet.hpp>
#include <renderd7/Sprite.hpp>
#include <renderd7/SpriteAnimation.hpp>
#include <renderd7/Time.hpp>
#include <renderd7/Toast.hpp>
#include <renderd7/bmp.hpp> #include <renderd7/bmp.hpp>
#include <renderd7/bmpconverter.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;
extern C3D_RenderTarget* TopRight; extern C3D_RenderTarget* TopRight;
extern C3D_RenderTarget* Bottom; extern C3D_RenderTarget* Bottom;*/
extern u32 d7_hDown; extern u32 d7_hDown;
extern u32 d7_hHeld; extern u32 d7_hHeld;
@ -53,129 +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
};
/// Set current RenderScreen
/// \param target The RenderTarget Top, Bottom
void OnScreen(C3D_RenderTarget *target);
/** The Spritesheet Class */
class Sheet
{
public:
/// Construct sheet
Sheet();
// Deconstruct sheet
~Sheet();
/// Load a Sritesheet
/// \param path Path to the Spritesheet (.t3x)
Result Load(const char *path);
/// Unload the Spritesheet
void Free();
/// The Spritesheet
C2D_SpriteSheet spritesheet;
};
/// Image Class
class Image
{
public:
~Image();
void Unload(); class Scene {
/// Load Image from Png public:
/// \param path path to png file
void LoadPng(const std::string path);
/// Load the Image from buffer
/// \param buffer the frame buffer
void LoadPFromBuffer(const std::vector<u8> &buffer);
void LoadFromBitmap(BMP bitmap);
/// Draw the Image directly
/// \param x The x position
/// \param y the y position
/// \param scaleX x scale from 0.0 to 1.0
/// \param scaleY y scale from 0.0 to 1.0
bool Draw(float x, float y, float scaleX = 1.0f, float scaleY = 1.0f);
/// \brief Get The Image
/// \return C2D_Image
C2D_Image Get(){return this->img;}
void FromSheet(RenderD7::Sheet sheet, size_t index);
/// \param img this is the C2D_Image
C2D_Image img;
/// \param loadet whether the image is loadet or not
bool loadet = false;
};
/// Sprite Class
class Sprite
{
public:
/// \brief Construct Sprite
Sprite();
/// \brief Deconstruct Sprite
~Sprite();
/// \brief Load a Sprite From SpriteSheet
/// \param sheet the Sheet to load from.(RenderD7::Sheet)
/// \param index the number of the Sprite in the Sheet
void FromSheet(RenderD7::Sheet *sheet, size_t index);
/// \brief Load a Sprite From SpriteSheet
/// \param img the Image to load from.(RenderD7::Image)
void FromImage(RenderD7::Image *img);
bool Draw();
void SetCenter(float x, float y);
void SetPos(float x, float y);
void SetScale(float x, float y);
void SetRotation(float rotation);
void Rotate(float speed);
float getWidth();
float getHeigh();
float getPosX();
float getPosY();
private:
C2D_ImageTint tint;
C2D_Sprite sprite;
};
class Scene {
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";
@ -187,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},
@ -197,209 +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 Ovl { class DSP_NF : public RenderD7::Ovl {
public: public:
virtual ~Ovl(){}
virtual void Draw() const = 0;
virtual void Logic() = 0;
inline bool IsKilled() {return this->iskilled; }
inline void Kill() { iskilled = true; }
private:
bool iskilled = false;
};
class DSP_NF : public RenderD7::Ovl
{
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;
}; };
class Toast : public RenderD7::Ovl int GetRandomInt(int b, int e);
{ void DrawMetrikOvl();
public: bool DrawImageFromSheet(RenderD7::Sheet *sheet, size_t index, float x, float y,
Toast(std::string head, std::string msg); float scaleX = 1.0, float scaleY = 1.0);
void Draw(void) const override; namespace Error {
void Logic() override; void DisplayError(std::string toptext, std::string errortext, int timesec = 3);
private: void DisplayFatalError(std::string toptext, std::string errortext);
std::string head, msg; } // namespace Error
int msgposy = 240; namespace Init {
int delay = 0; 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
void AddOvl(std::unique_ptr<RenderD7::Ovl> scene); namespace Convert {
namespace Color inline float StringtoFloat(std::string inp) { return std::atof(inp.c_str()); }
{ inline int StringtoInt(std::string inp) { return std::atoi(inp.c_str()); }
struct rgba inline bool FloatToBool(float inp) {
{ if (inp == 1)
u8 r, g, b, a; return true;
}; else
class RGBA{ return false;
public: }
RGBA(u8 r, u8 g, u8 b, u8 a) : m_r(r),m_g(g),m_b(b),m_a(a){} } // namespace Convert
u32 toRGBA() const {return (m_r << 24) | (m_g << 16) | (m_b << 8) | m_a;}
u8 m_r, m_g ,m_b, m_a; struct DirContent {
};
std::string RGB2Hex(int r, int g, int b);
u32 Hex(const std::string color, u8 a = 255);
}
int GetRandomInt(int b, int e);
void DrawMetrikOvl();
bool DrawImageFromSheet(RenderD7::Sheet* sheet, size_t index, float x, float y, float scaleX = 1.0, float scaleY = 1.0);
namespace Error
{
void DisplayError(std::string toptext, std::string errortext, int timesec = 3);
void DisplayFatalError(std::string toptext, std::string errortext);
}
namespace Init
{
Result Main(std::string app_name = "RD7Game");
Result Reload();
void Graphics();
void NdspFirm(bool useit = false);
}
namespace Exit
{
void Main();
void NdspFirm();
void Graphics();
}
namespace Msg
{
void Display(std::string titletxt, std::string subtext, C3D_RenderTarget *target);
void DisplayWithProgress(std::string titletext, std::string subtext, float current, float total, u32 prgbarcolor);
}
namespace Convert
{
inline float StringtoFloat(std::string inp){return std::atof(inp.c_str());}
inline int StringtoInt(std::string inp){return std::atoi(inp.c_str());}
inline bool FloatToBool(float inp){if(inp == 1)return true; else return false;}
}
struct DirContent
{
std::string name; std::string 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);
bool DrawRect(float x, float y, float w, float h, u32 color);
bool DrawNFRect(float p1x, float p1y, float w, float h, u32 color, float scale = 1);
bool DrawPx(float x, float y, u32 color);
void DrawTextCentered(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr);
void DrawText(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr);
void DrawTextLeft(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr);
float GetTextWidth(float size, std::string Text, C2D_Font fnt = nullptr);
void GetTextSize(float size, float *width, float *height, std::string Text, C2D_Font fnt = nullptr);
float GetTextHeight(float size, std::string Text, C2D_Font fnt = nullptr);
Result loadFont(C2D_Font &fnt, const char * Path = "");
Result unloadFont(C2D_Font &fnt);
bool DrawCircle(float x, float y, float radius, u32 color);
bool DrawImage(C2D_Image img, float x, float y, float scaleX = 1.0f, float scaleY = 1.0f);
void FrameEnd();
void ToggleRD7SR();
bool IsRD7SR();
class SpriteSheetAnimation : public RenderD7::Sprite void FrameEnd();
{ void ToggleRD7SR();
public: bool IsRD7SR();
SpriteSheetAnimation();
~SpriteSheetAnimation();
void Setup(RenderD7::Sheet *sheet, size_t imagecount, size_t startimage, float frame_begin, float frame_finish);
void Play(float timespeed);
private:
size_t images;
size_t imgs = 0;
float D_totaltime;
RenderD7::Sheet *sheet;
float time;
};
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);
std::string FormatString(std::string fmt_str, ...);
std::string GetTimeStr(void); 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 = "";
@ -409,40 +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};
}; };
bool NameIsEndingWith(const std::string &name, const std::vector<std::string> &extensions); void GetDirContentsExt(std::vector<RenderD7::DirContent> &dircontent,
void GetDirContentsExt(std::vector<RenderD7::DirContent> &dircontent, const std::vector<std::string> &extensions); const std::vector<std::string> &extensions);
void GetDirContents(std::vector<RenderD7::DirContent> &dircontent); void GetDirContents(std::vector<RenderD7::DirContent> &dircontent);
class BitmapPrinter } // namespace RenderD7
{
public:
BitmapPrinter(int w, int h);
~BitmapPrinter();
bool DecodeFile(std::string file);
bool DecodeMem(std::vector<unsigned char> buffer);
void DrawPixel(int x, int y, u8 b, u8 g, u8 r, u8 a);
void DrawRect(int x, int y, int w, int h, u8 line_w, u8 b, u8 g, u8 r, u8 a);
void DrawRectFilled(int x, int y, int w, int h, u8 b, u8 g, u8 r, u8 a);
void UsePreMap(BMP map);
void UsePrePrintMap(BitmapPrinter printmap);
BMP GetBitmap(){ return bitmap; }
void SaveBmp(std::string name);
void SavePng(std::string name);
void CreateScreen(C3D_RenderTarget *target);
void DrawScreen(int framerate);
void Clear(u8 b = 0, u8 g = 0, u8 r = 0, u8 a = 255);
void ClearBlank();
RenderD7::Image GetImage();
private:
int frame = 0;
RenderD7::Image renderframe;
bool isscreen = false;
C3D_RenderTarget* targetr;
BMP bitmap = NULL;
BMP blank = NULL;
};
} /// 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,11 +1,40 @@
template<class T> #pragma once
T GetFileName(T const & path, T const & delims = "/\\") #include <iomanip>
{ #include <iostream>
#include <string>
namespace RenderD7 {
inline bool NameIsEndingWith(const std::string &name,
const std::vector<std::string> &extensions) {
if (name.substr(0, 2) == "._")
return false;
if (name.size() == 0)
return false;
if (extensions.size() == 0)
return true;
for (int i = 0; i < (int)extensions.size(); i++) {
const std::string ext = extensions.at(i);
if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0)
return true;
}
return false;
}
} // namespace RenderD7
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> std::string Int_To_Hex(T i) {
std::stringstream stream;
stream << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex
<< i;
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
}

BIN
logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

465
source/BitmapPrinter.cpp Normal file
View File

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

View File

@ -1,20 +0,0 @@
#include <renderd7/Clock.hpp>
namespace rnd7 {
////////////////////////////////////////////////////////////
Time Clock::getElapsedTime() const {
return getCurrentTime() - m_startTime;
}
////////////////////////////////////////////////////////////
Time Clock::restart() {
Time now = getCurrentTime();
Time elapsed = now - m_startTime;
m_startTime = now;
return elapsed;
}
}

24
source/Color.cpp Normal file
View File

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

216
source/Draw.cpp Normal file
View File

@ -0,0 +1,216 @@
#include <renderd7/Draw.hpp>
extern C2D_TextBuf TextBuf;
extern C2D_Font Font;
extern bool currentScreen;
bool RenderD7::Draw::Rect(float x, float y, float w, float h, u32 color) {
return C2D_DrawRectSolid(x, y, 0.5f, w, h, color);
}
bool RenderD7::Draw::Px(float x, float y, u32 color) {
return C2D_DrawRectSolid(x, y, 0.5f, 1, 1, color);
}
void RenderD7::Draw::TextCentered(float x, float y, float size, u32 color,
std::string Text, int maxWidth, int maxHeight,
C2D_Font fnt) {
float lineHeight, widthScale;
// Check for the lineHeight.
if (fnt != nullptr) {
lineHeight = RenderD7::Draw::GetTextHeight(size, " ", fnt);
} else {
lineHeight = RenderD7::Draw::GetTextHeight(size, " ");
}
int line = 0;
while (Text.find('\n') != Text.npos) {
if (maxWidth == 0) {
// Do the widthScale.
if (fnt != nullptr) {
widthScale = RenderD7::Draw::GetTextWidth(
size, Text.substr(0, Text.find('\n')), fnt);
} else {
widthScale =
RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')));
}
} else {
// Do the widthScale 2.
if (fnt != nullptr) {
widthScale = std::min((float)maxWidth,
RenderD7::Draw::GetTextWidth(
size, Text.substr(0, Text.find('\n')), fnt));
} else {
widthScale = std::min((float)maxWidth,
RenderD7::Draw::GetTextWidth(
size, Text.substr(0, Text.find('\n'))));
}
}
if (fnt != nullptr) {
RenderD7::Draw::Text((currentScreen ? 200 : 160) + x - (widthScale / 2),
y + (lineHeight * line), size, color,
Text.substr(0, Text.find('\n')), maxWidth, maxHeight,
fnt);
} else {
RenderD7::Draw::Text((currentScreen ? 200 : 160) + x - (widthScale / 2),
y + (lineHeight * line), size, color,
Text.substr(0, Text.find('\n')), maxWidth,
maxHeight);
}
Text = Text.substr(Text.find('\n') + 1);
line++;
}
if (maxWidth == 0) {
// Do the next WidthScale.
if (fnt != nullptr) {
widthScale = RenderD7::Draw::GetTextWidth(
size, Text.substr(0, Text.find('\n')), fnt);
} else {
widthScale =
RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n')));
}
} else {
// And again.
if (fnt != nullptr) {
widthScale = std::min((float)maxWidth,
RenderD7::Draw::GetTextWidth(
size, Text.substr(0, Text.find('\n')), fnt));
} else {
widthScale = std::min(
(float)maxWidth,
RenderD7::Draw::GetTextWidth(size, Text.substr(0, Text.find('\n'))));
}
}
if (fnt != nullptr) {
RenderD7::Draw::Text((currentScreen ? 200 : 160) + x - (widthScale / 2),
y + (lineHeight * line), size, color,
Text.substr(0, Text.find('\n')), maxWidth, maxHeight,
fnt);
} else {
RenderD7::Draw::Text((currentScreen ? 200 : 160) + x - (widthScale / 2),
y + (lineHeight * line), size, color,
Text.substr(0, Text.find('\n')), maxWidth, maxHeight);
}
}
// Draw String or Text.
void RenderD7::Draw::Text(float x, float y, float size, u32 color,
std::string Text, int maxWidth, int maxHeight,
C2D_Font fnt) {
C2D_Text c2d_text;
if (fnt != nullptr) {
C2D_TextFontParse(&c2d_text, fnt, TextBuf, Text.c_str());
} else {
C2D_TextFontParse(&c2d_text, Font, TextBuf, Text.c_str());
}
C2D_TextOptimize(&c2d_text);
float heightScale;
if (maxHeight == 0) {
heightScale = size;
} else {
if (fnt != nullptr) {
heightScale = std::min(
size,
size * (maxHeight / RenderD7::Draw::GetTextHeight(size, Text, fnt)));
} else {
heightScale = std::min(
size, size * (maxHeight / RenderD7::Draw::GetTextHeight(size, Text)));
}
}
if (maxWidth == 0) {
C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, size, heightScale,
color);
} else {
if (fnt != nullptr) {
C2D_DrawText(
&c2d_text, C2D_WithColor, x, y, 0.5f,
std::min(size, size * (maxWidth / RenderD7::Draw::GetTextWidth(
size, Text, fnt))),
heightScale, color);
} else {
C2D_DrawText(
&c2d_text, C2D_WithColor, x, y, 0.5f,
std::min(size, size * (maxWidth /
RenderD7::Draw::GetTextWidth(size, Text))),
heightScale, color);
}
}
}
void RenderD7::Draw::TextRight(float x, float y, float size, u32 color,
std::string Text, int maxWidth, int maxHeight,
C2D_Font fnt) {
RenderD7::Draw::Text(x - RenderD7::Draw::GetTextWidth(size, Text, fnt), y,
size, color, Text, maxWidth, maxHeight, fnt);
}
// Get String or Text Width.
float RenderD7::Draw::GetTextWidth(float size, std::string Text, C2D_Font fnt) {
float width = 0;
if (fnt != nullptr) {
GetTextSize(size, &width, NULL, Text, fnt);
} else {
GetTextSize(size, &width, NULL, Text);
}
return width;
}
// Get String or Text Size.
void RenderD7::Draw::GetTextSize(float size, float *width, float *height,
std::string Text, C2D_Font fnt) {
C2D_Text c2d_text;
if (fnt != nullptr) {
C2D_TextFontParse(&c2d_text, fnt, TextBuf, Text.c_str());
} else {
C2D_TextFontParse(&c2d_text, Font, TextBuf, Text.c_str());
}
C2D_TextGetDimensions(&c2d_text, size, size, width, height);
}
// Get String or Text Height.
float RenderD7::Draw::GetTextHeight(float size, std::string Text,
C2D_Font fnt) {
float height = 0;
if (fnt != nullptr) {
GetTextSize(size, NULL, &height, Text.c_str(), fnt);
} else {
GetTextSize(size, NULL, &height, Text.c_str());
}
return height;
}
Result RenderD7::Draw::LoadFont(C2D_Font &fnt, const char *Path) {
fnt = C2D_FontLoad(Path); // Only load if found.
return 0;
}
// Unload a Font.
Result RenderD7::Draw::UnloadFont(C2D_Font &fnt) {
if (fnt != nullptr) {
C2D_FontFree(fnt); // Make sure to only unload if not nullptr.
}
return 0;
}
bool RenderD7::Draw::Circle(float x, float y, float radius, u32 color) {
return C2D_DrawCircleSolid(x, y, 0.5f, radius, color);
}
bool RenderD7::Draw::Image(C2D_Image img, float x, float y, float scaleX,
float scaleY) {
return C2D_DrawImageAt(img, x, y, 0.5f, nullptr, scaleX, scaleY);
}
bool RenderD7::Draw::NFRect(float p1x, float p1y, float w, float h, u32 color,
float scale) {
C2D_DrawLine(p1x, p1y, color, w, p1y, color, scale, 1);
C2D_DrawLine(w, p1y, color, w, h, color, scale, 1);
C2D_DrawLine(w, h, color, p1x, h, color, scale, 1);
C2D_DrawLine(p1x, h, color, p1x, p1y, color, scale, 1);
return true;
}

344
source/FileSystem.cpp Normal file
View File

@ -0,0 +1,344 @@
#include <3ds.h>
#include <cstring>
#include <renderd7/FileSystem.hpp>
// Debugging
#include <memory>
#include <renderd7/Ovl.hpp>
#include <renderd7/Toast.hpp>
const char *RenderD7::FileSystem::GetPhysfsError() {
return PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode());
}
std::string RenderD7::FileSystem::Normalize(const std::string &input) {
std::string out;
bool seenSep = false, isSep = false;
for (size_t i = 0; i < input.size(); ++i) {
isSep = (input[i] == '/');
if (!isSep || !seenSep)
out += input[i];
seenSep = isSep;
}
return out;
}
void RenderD7::FileSystem::Initialize() { RenderD7::FileSystem::savePath = ""; }
int RenderD7::FileSystem::Init(const char *argv) {
int res = PHYSFS_init(argv);
if (res != 1) {
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
}
return res;
}
bool RenderD7::FileSystem::SetSource(const char *source) {
if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
std::string searchPath = source;
if (!PHYSFS_mount(searchPath.c_str(), NULL, 1))
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
return true;
}
bool RenderD7::FileSystem::SetIdentity(const char *name, bool append) {
if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
std::string old = RenderD7::FileSystem::savePath;
RenderD7::FileSystem::savePath = RenderD7::FileSystem::Normalize(
RenderD7::FileSystem::GetUserDirectory() + "/save/" + name);
printf("Save Path set to %s\n", savePath.c_str());
if (!old.empty())
PHYSFS_unmount(old.c_str());
int success = PHYSFS_mount(savePath.c_str(), NULL, append);
printf("Save Path mounted %d\n", success);
PHYSFS_setWriteDir(nullptr);
return true;
}
std::string RenderD7::FileSystem::GetSaveDirectory() {
return RenderD7::FileSystem::Normalize(
RenderD7::FileSystem::GetUserDirectory() + "/save");
}
bool RenderD7::FileSystem::SetupWriteDirectory() {
if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
if (RenderD7::FileSystem::savePath.empty())
RenderD7::AddOvl(
std::make_unique<RenderD7::Toast>("PHYSFS-Error", "Path is Empty"));
return false;
std::string tmpWritePath = RenderD7::FileSystem::savePath;
std::string tmpDirectoryPath = RenderD7::FileSystem::savePath;
if (RenderD7::FileSystem::savePath.find(
RenderD7::FileSystem::GetUserDirectory()) == 0) {
tmpWritePath = RenderD7::FileSystem::GetUserDirectory();
tmpDirectoryPath =
savePath.substr(RenderD7::FileSystem::GetUserDirectory().length());
/* strip leading '/' characters from the path we want to create */
size_t startPosition = tmpDirectoryPath.find_first_not_of('/');
if (startPosition != std::string::npos)
tmpDirectoryPath = tmpDirectoryPath.substr(startPosition);
}
if (!PHYSFS_setWriteDir(tmpWritePath.c_str())) {
printf("Failed to set write dir to %s\n", tmpWritePath.c_str());
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Failed to set write dir to %s\n",
tmpWritePath.c_str())));
return false;
}
if (!RenderD7::FileSystem::CreateDirectory(tmpDirectoryPath.c_str())) {
printf("Failed to create dir %s\n", tmpDirectoryPath.c_str());
/* clear the write directory in case of error */
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FormatString("Failed to create dir %s\n",
tmpDirectoryPath.c_str())));
PHYSFS_setWriteDir(nullptr);
return false;
}
if (!PHYSFS_setWriteDir(savePath.c_str())) {
printf("Failed to set write dir to %s\n", savePath.c_str());
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Failed to set write dir to %s\n",
savePath.c_str())));
return false;
}
if (!PHYSFS_mount(savePath.c_str(), nullptr, 0)) {
printf("Failed to mount write dir (%s)\n",
RenderD7::FileSystem::GetPhysfsError());
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Failed to mount write dir (%s)\n",
RenderD7::FileSystem::GetPhysfsError())));
/* clear the write directory in case of error */
PHYSFS_setWriteDir(nullptr);
return false;
}
return true;
}
std::string RenderD7::FileSystem::GetUserDirectory() {
return RenderD7::FileSystem::Normalize(
PHYSFS_getPrefDir("npi-d7", "renderd7"));
}
bool RenderD7::FileSystem::GetInfo(const char *filename,
RenderD7::FileSystem::Info &info) {
if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
PHYSFS_Stat stat = {};
if (!PHYSFS_stat(filename, &stat))
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
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);
if (stat.filetype == PHYSFS_FILETYPE_REGULAR)
info.type = RenderD7::FileSystem::FileType_File;
else if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY)
info.type = RenderD7::FileSystem::FileType_Directory;
else if (stat.filetype == PHYSFS_FILETYPE_SYMLINK)
info.type = RenderD7::FileSystem::FileType_SymLink;
else
info.type = RenderD7::FileSystem::FileType_Other;
return true;
}
void RenderD7::FileSystem::GetDirectoryItems(const char *path,
std::vector<std::string> &items) {
if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return;
char **results = PHYSFS_enumerateFiles(path);
if (results == nullptr)
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return;
for (char **item = results; *item != 0; item++)
items.push_back(*item);
PHYSFS_freeList(results);
}
bool RenderD7::FileSystem::OpenFile(File &file, const char *name,
FileMode mode) {
if (mode == FileMode_Closed)
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
if (file.handle)
RenderD7::FileSystem::CloseFile(file);
if (mode == FileMode_Read && !PHYSFS_exists(name)) {
printf("Could not open file %s, does not exist.\n", name);
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Could not open file %s, does not exist.\n",
name)));
return false;
}
if ((mode == FileMode_Write) &&
(PHYSFS_getWriteDir() == nullptr &&
RenderD7::FileSystem::SetupWriteDirectory())) {
printf("Could not set write directory.\n");
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Could not set write directory.\n")));
return false;
}
PHYSFS_getLastErrorCode();
switch (mode) {
case FileMode_Read:
file.handle = PHYSFS_openRead(name);
break;
case FileMode_Write:
file.handle = PHYSFS_openWrite(name);
break;
default:
break;
}
if (!file.handle) {
const char *error = RenderD7::FileSystem::GetPhysfsError();
if (error == nullptr)
error = "unknown error";
printf("Could not open file %s (%s)\n", name, error);
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Could not open file %s (%s)\n", name, error)));
return false;
}
file.mode = mode;
return true;
}
bool RenderD7::FileSystem::CloseFile(File &file) {
if (file.handle == nullptr || !PHYSFS_close(file.handle))
return false;
file.handle = nullptr;
return true;
}
bool RenderD7::FileSystem::CreateDirectory(const char *name) {
if (!PHYSFS_isInit())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
if (PHYSFS_getWriteDir() == nullptr &&
!RenderD7::FileSystem::SetupWriteDirectory())
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
if (!PHYSFS_mkdir(name))
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
return true;
}
int64_t RenderD7::FileSystem::ReadFile(File &file, void *destination,
int64_t size) {
if (!file.handle || file.mode != FileMode_Read) {
printf("File is not opened for reading.\n");
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", "File is not opened for reading.\n"));
return 0;
}
if (size > file.GetSize())
size = file.GetSize();
else if (size < 0) {
printf("Invalid read size %lld\n", size);
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error",
RenderD7::FormatString("Invalid read size %lld\n", size)));
return 0;
}
return PHYSFS_readBytes(file.handle, destination, (PHYSFS_uint64)size);
}
bool RenderD7::FileSystem::WriteFile(File &file, const void *data,
int64_t size) {
if (!file.handle || file.mode != FileMode_Write) {
printf("File is not opened for writing.\n");
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", "File is not opened for writing.\n"));
return false;
}
int64_t written = PHYSFS_writeBytes(file.handle, data, (PHYSFS_uint64)size);
if (written != size) {
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"PHYSFS-Error", RenderD7::FileSystem::GetPhysfsError()));
return false;
}
return true;
}

260
source/Image.cpp Normal file
View File

@ -0,0 +1,260 @@
#include <renderd7/Image.hpp>
#include <renderd7/Ovl.hpp>
#include <renderd7/Toast.hpp>
extern bool usedbgmsg;
static u32 GetNextPowerOf2(u32 v) {
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return (v >= 64 ? v : 64);
}
static bool C3DTexToC2DImage(C2D_Image *texture, u32 width, u32 height,
u8 *buf) {
if (width >= 1024 || height >= 1024)
return false;
C3D_Tex *tex = new C3D_Tex[sizeof(C3D_Tex)];
Tex3DS_SubTexture *subtex = new Tex3DS_SubTexture[sizeof(Tex3DS_SubTexture)];
subtex->width = static_cast<u16>(width);
subtex->height = static_cast<u16>(height);
// RGBA -> ABGR
for (u32 row = 0; row < subtex->width; row++) {
for (u32 col = 0; col < subtex->height; col++) {
u32 z = (row + col * subtex->width) * 4;
u8 r = *(u8 *)(buf + z);
u8 g = *(u8 *)(buf + z + 1);
u8 b = *(u8 *)(buf + z + 2);
u8 a = *(u8 *)(buf + z + 3);
*(buf + z) = a;
*(buf + z + 1) = b;
*(buf + z + 2) = g;
*(buf + z + 3) = r;
}
}
u32 w_pow2 = GetNextPowerOf2(subtex->width);
u32 h_pow2 = GetNextPowerOf2(subtex->height);
subtex->left = 0.f;
subtex->top = 1.f;
subtex->right = (subtex->width / static_cast<float>(w_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_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST);
std::memset(tex->data, 0, tex->size);
for (u32 x = 0; x < subtex->width; x++) {
for (u32 y = 0; y < subtex->height; y++) {
u32 dst_pos = ((((y >> 3) * (w_pow2 >> 3) + (x >> 3)) << 6) +
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) |
((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) *
4;
u32 src_pos = (y * subtex->width + x) * 4;
std::memcpy(&(static_cast<u8 *>(tex->data))[dst_pos],
&(static_cast<u8 *>(buf))[src_pos], 4);
}
}
C3D_TexFlush(tex);
tex->border = RenderD7::Color::Hex("#000000", 0);
C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
if (tex && subtex) {
texture->tex = tex;
texture->subtex = subtex;
return true;
}
return false;
}
extern "C" {
#include <renderd7/external/libnsbmp/libnsbmp.h>
}
static const u32 BYTES_PER_PIXEL = 4;
#define MAX_IMAGE_BYTES (48 * 1024 * 1024)
namespace LIBBMP {
static void *bitmap_create(int width, int height,
[[maybe_unused]] unsigned int state) {
/* ensure a stupidly large (>50Megs or so) bitmap is not created */
if ((static_cast<long long>(width) * static_cast<long long>(height)) >
(MAX_IMAGE_BYTES / BYTES_PER_PIXEL))
return nullptr;
return std::calloc(width * height, BYTES_PER_PIXEL);
}
static unsigned char *bitmap_get_buffer(void *bitmap) {
assert(bitmap);
return static_cast<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);
}
} // namespace LIBBMP
unsigned Image_to_C3D(C2D_Image img, const std::vector<unsigned char> &bmpc) {
bmp_bitmap_callback_vt bitmap_callbacks = {
LIBBMP::bitmap_create, LIBBMP::bitmap_destroy, LIBBMP::bitmap_get_buffer,
LIBBMP::bitmap_get_bpp};
bmp_result code = BMP_OK;
bmp_image bmp;
bmp_create(&bmp, &bitmap_callbacks);
code = bmp_analyse(&bmp, bmpc.size(), (u8 *)bmpc.data());
if (code != BMP_OK) {
bmp_finalise(&bmp);
return 1;
}
code = bmp_decode(&bmp);
if (code != BMP_OK) {
if ((code != BMP_INSUFFICIENT_DATA) && (code != BMP_DATA_ERROR)) {
bmp_finalise(&bmp);
return 2;
}
/* skip if the decoded image would be ridiculously large */
if ((bmp.width * bmp.height) > 200000) {
bmp_finalise(&bmp);
return 3;
}
}
C2D_Image *texture = new C2D_Image();
bool ret = C3DTexToC2DImage(texture, static_cast<u32>(bmp.width),
static_cast<u32>(bmp.height),
static_cast<u8 *>(bmp.bitmap));
bmp_finalise(&bmp);
delete texture;
if (!ret) {
return 4;
}
return 0;
}
void RenderD7::Image::LoadPng(const std::string path) {
if (usedbgmsg) {
// RenderD7::Msg::Display("RenderD7", "Loading Png:" + path, Top);
}
std::vector<u8> ImageBuffer;
unsigned width, height;
if (loadet) {
C3D_TexDelete(this->img.tex);
loadet = false;
}
lodepng::decode(ImageBuffer, width, height, path);
this->img.tex = new C3D_Tex;
this->img.subtex =
new Tex3DS_SubTexture({(u16)width, (u16)height, 0.0f, 1.0f,
width / 1024.0f, 1.0f - (height / 1024.0f)});
C3D_TexInit(this->img.tex, 1024, 1024, GPU_RGBA8);
C3D_TexSetFilter(this->img.tex, GPU_LINEAR, GPU_LINEAR);
this->img.tex->border = 0xFFFFFFFF;
C3D_TexSetWrap(this->img.tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
for (u32 x = 0; x < width && x < 1024; x++) {
for (u32 y = 0; y < height && y < 1024; y++) {
const u32 dstPos = ((((y >> 3) * (1024 >> 3) + (x >> 3)) << 6) +
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) |
((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) *
4;
const u32 srcPos = (y * width + x) * 4;
((uint8_t *)this->img.tex->data)[dstPos + 0] =
ImageBuffer.data()[srcPos + 3];
((uint8_t *)this->img.tex->data)[dstPos + 1] =
ImageBuffer.data()[srcPos + 2];
((uint8_t *)this->img.tex->data)[dstPos + 2] =
ImageBuffer.data()[srcPos + 1];
((uint8_t *)this->img.tex->data)[dstPos + 3] =
ImageBuffer.data()[srcPos + 0];
}
}
loadet = true;
}
RenderD7::Image::~Image() {
if (loadet)
C3D_TexDelete(img.tex);
loadet = false;
}
void RenderD7::Image::Unload() {
if (loadet)
C3D_TexDelete(img.tex);
loadet = false;
}
void RenderD7::Image::LoadPFromBuffer(const std::vector<u8> &buffer) {
std::vector<u8> ImageBuffer;
if (loadet) {
C3D_TexDelete(this->img.tex);
loadet = false;
}
unsigned width, height;
lodepng::decode(ImageBuffer, width, height, buffer);
img.tex = new C3D_Tex;
img.subtex =
new Tex3DS_SubTexture({(u16)width, (u16)height, 0.0f, 1.0f,
width / 512.0f, 1.0f - (height / 512.0f)});
C3D_TexInit(img.tex, 512, 512, GPU_RGBA8);
C3D_TexSetFilter(img.tex, GPU_LINEAR, GPU_LINEAR);
img.tex->border = 0xFFFFFFFF;
C3D_TexSetWrap(img.tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
for (u32 x = 0; x < width && x < 512; x++) {
for (u32 y = 0; y < height && y < 512; y++) {
const u32 dstPos = ((((y >> 3) * (512 >> 3) + (x >> 3)) << 6) +
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) |
((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) *
4;
const u32 srcPos = (y * width + x) * 4;
((uint8_t *)img.tex->data)[dstPos + 0] = ImageBuffer.data()[srcPos + 3];
((uint8_t *)img.tex->data)[dstPos + 1] = ImageBuffer.data()[srcPos + 2];
((uint8_t *)img.tex->data)[dstPos + 2] = ImageBuffer.data()[srcPos + 1];
((uint8_t *)img.tex->data)[dstPos + 3] = ImageBuffer.data()[srcPos + 0];
}
}
}
void RenderD7::Image::FromSheet(RenderD7::Sheet sheet, size_t index) {}
bool RenderD7::Image::Draw(float x, float y, float scaleX, float scaleY) {
if (loadet)
return C2D_DrawImageAt(this->img, x, y, 0.5f, nullptr, scaleX, scaleY);
return false;
}
void RenderD7::Image::LoadFromBitmap(BMP bitmap) {
loadet = false;
unsigned error = Image_to_C3D(this->img, bitmap.DATA());
if (error == 0) {
this->loadet = true;
}
if (error) {
std::cout << "BMP decoding error " << error << std::endl;
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>(
"Bmp - Error", "Code: " + std::to_string(error)));
}
}

66
source/NFontApi.cpp Normal file
View File

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

8
source/Screen.cpp Normal file
View File

@ -0,0 +1,8 @@
#include <renderd7/Screen.hpp>
extern bool currentScreen;
void RenderD7::OnScreen(C3D_RenderTarget *target) {
C2D_SceneBegin(target);
currentScreen = (target == Top || target == TopRight) ? 1 : 0;
}

15
source/Sheet.cpp Normal file
View File

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

36
source/Sprite.cpp Normal file
View File

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

View File

@ -0,0 +1,38 @@
#include <renderd7/SpriteAnimation.hpp>
#include <renderd7/log.hpp>
extern Log renderd7log;
RenderD7::SpriteSheetAnimation::SpriteSheetAnimation() {
renderd7log.Write("SpriteSheetAnimation createt!");
}
RenderD7::SpriteSheetAnimation::~SpriteSheetAnimation() {
//
}
void RenderD7::SpriteSheetAnimation::Setup(RenderD7::Sheet *sheet,
size_t imagecount, size_t startimage,
float frame_begin,
float frame_finish) {
D_totaltime = frame_begin;
renderd7log.Write("frame_begin success");
this->images = imagecount;
renderd7log.Write("imagecount success");
this->sheet = sheet;
renderd7log.Write("sheet success");
this->time = frame_finish;
renderd7log.Write("frame_finish success");
RenderD7::SpriteSheetAnimation::FromSheet(this->sheet, startimage);
}
void RenderD7::SpriteSheetAnimation::Play(float timespeed) {
D_totaltime += timespeed;
if (D_totaltime >= time) {
D_totaltime -= time;
imgs++;
if (imgs == images) {
imgs = 0;
}
}
RenderD7::SpriteSheetAnimation::FromSheet(sheet, imgs);
// RenderD7::SpriteSheetAnimation::Draw();
}

View File

@ -1,200 +1,30 @@
#include <fstream>
#include <memory>
#include <renderd7/Time.hpp> #include <renderd7/Time.hpp>
#include <stdarg.h>
#include <stdio.h>
namespace rnd7 { #include <string.h>
//////////////////////////////////////////////////////////// #include <string>
const Time Time::Zero_; #include <time.h>
#include <unistd.h>
//////////////////////////////////////////////////////////// std::string RenderD7::FormatString(std::string fmt_str, ...) {
Time::Time() : va_list ap;
m_microseconds(0) { char *fp = NULL;
} va_start(ap, fmt_str);
vasprintf(&fp, fmt_str.c_str(), ap);
va_end(ap);
//////////////////////////////////////////////////////////// std::unique_ptr<char, decltype(free) *> formatted(fp, free);
float Time::asSeconds() const { return std::string(formatted.get());
return m_microseconds / 1000000.f; }
}
std::string RenderD7::GetTimeStr(void) {
time_t unixTime;
//////////////////////////////////////////////////////////// struct tm timeStruct;
int Time::asMilliseconds() const { time(&unixTime);
return static_cast<int>(m_microseconds / 1000); localtime_r(&unixTime, &timeStruct);
} return FormatString("%04i-%02i-%02i_%02i-%02i-%02i",
timeStruct.tm_year + 1900, timeStruct.tm_mon + 1,
timeStruct.tm_mday, timeStruct.tm_hour, timeStruct.tm_min,
//////////////////////////////////////////////////////////// timeStruct.tm_sec);
long Time::asMicroseconds() const {
return m_microseconds;
}
////////////////////////////////////////////////////////////
Time::Time(long microseconds) :
m_microseconds(microseconds) {
}
////////////////////////////////////////////////////////////
Time seconds(float amount) {
return Time(static_cast<long>(amount * 1000000));
}
////////////////////////////////////////////////////////////
Time milliseconds(int amount) {
return Time(static_cast<long>(amount) * 1000);
}
////////////////////////////////////////////////////////////
Time microseconds(long amount) {
return Time(amount);
}
////////////////////////////////////////////////////////////
bool operator==(Time left, Time right) {
return left.asMicroseconds() == right.asMicroseconds();
}
////////////////////////////////////////////////////////////
bool operator!=(Time left, Time right) {
return left.asMicroseconds() != right.asMicroseconds();
}
////////////////////////////////////////////////////////////
bool operator<(Time left, Time right) {
return left.asMicroseconds() < right.asMicroseconds();
}
////////////////////////////////////////////////////////////
bool operator>(Time left, Time right) {
return left.asMicroseconds() > right.asMicroseconds();
}
////////////////////////////////////////////////////////////
bool operator<=(Time left, Time right) {
return left.asMicroseconds() <= right.asMicroseconds();
}
////////////////////////////////////////////////////////////
bool operator>=(Time left, Time right) {
return left.asMicroseconds() >= right.asMicroseconds();
}
////////////////////////////////////////////////////////////
Time operator-(Time right) {
return microseconds(-right.asMicroseconds());
}
////////////////////////////////////////////////////////////
Time operator+(Time left, Time right) {
return microseconds(left.asMicroseconds() + right.asMicroseconds());
}
////////////////////////////////////////////////////////////
Time &operator+=(Time &left, Time right) {
return left = left + right;
}
////////////////////////////////////////////////////////////
Time operator-(Time left, Time right) {
return microseconds(left.asMicroseconds() - right.asMicroseconds());
}
////////////////////////////////////////////////////////////
Time &operator-=(Time &left, Time right) {
return left = left - right;
}
////////////////////////////////////////////////////////////
Time operator*(Time left, float right) {
return seconds(left.asSeconds() * right);
}
////////////////////////////////////////////////////////////
Time operator*(Time left, long right) {
return microseconds(left.asMicroseconds() * right);
}
////////////////////////////////////////////////////////////
Time operator*(float left, Time right) {
return right * left;
}
////////////////////////////////////////////////////////////
Time operator*(long left, Time right) {
return right * left;
}
////////////////////////////////////////////////////////////
Time &operator*=(Time &left, float right) {
return left = left * right;
}
////////////////////////////////////////////////////////////
Time &operator*=(Time &left, long right) {
return left = left * right;
}
////////////////////////////////////////////////////////////
Time operator/(Time left, float right) {
return seconds(left.asSeconds() / right);
}
////////////////////////////////////////////////////////////
Time operator/(Time left, long right) {
return microseconds(left.asMicroseconds() / right);
}
////////////////////////////////////////////////////////////
Time &operator/=(Time &left, float right) {
return left = left / right;
}
////////////////////////////////////////////////////////////
Time &operator/=(Time &left, long right) {
return left = left / right;
}
////////////////////////////////////////////////////////////
float operator/(Time left, Time right) {
return left.asSeconds() / right.asSeconds();
}
////////////////////////////////////////////////////////////
Time operator%(Time left, Time right) {
return microseconds(left.asMicroseconds() % right.asMicroseconds());
}
////////////////////////////////////////////////////////////
Time &operator%=(Time &left, Time right) {
return left = left % right;
}
} }

38
source/Toast.cpp Normal file
View File

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

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,49 +2,43 @@
#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) {
printf("%s\n", filename);
void Log::Init(const char *filename) std::string fn = filename;
{ std::string name = fn + ".txt";
std::string name = "sdmc:/" + Log::logDate() + filename + ".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());
std::ofstream logFile; std::ofstream logFile;
logFile.open((this->filename), std::ofstream::app); logFile.open((this->filename), std::ofstream::app);
std::string writeDebug = "["; std::string writeDebug = "[";
@ -54,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